Architecture
Every request walks the same path: the adapter never sees SQL, and the implementation never sees HTML.
- 01clientBrowser formNative POST, works without JS
- 02adaptertask-adapter-htmxParse input, map errors to status codes
- 03contracttask-contractTasks trait: list and change
- 04implementationtask-impl-timescaleService rules over the typed repository
- 05databaseTimescaleDBScoped to the authenticated identity
The slices
Two slices — project and task — repeat the same triad, and one composition
root selects the concrete pieces:
examples/htmx-starter/
crates/project-contract/contractProject, rules, Projects, ProjectRepositorycrates/project-impl-timescale/implementationProject service and SQL repositorycrates/project-adapter-htmx/adapterPages, forms, handlerscrates/task-contract/contractTask, TaskChange, rules, Tasks, TaskRepositorycrates/task-impl-timescale/implementationTaskService and SQL repositorycrates/task-adapter-htmx/adapterRoutes, pages, formsservers/web/compositionSelects the concrete implementations and adaptersDependencies point inward
The adapters depend on their contracts only; the implementations depend on the
same contracts; neither depends on the other. servers/web is the only crate
that names everything.