Skip to content

ADR 0016: Fresh Rust without legacy compatibility

  • Status Accepted (architecture; implementation acceptance pending)
  • Date 2026-10-15

Context

Earlier migration plans aimed at Rails parity, database adoption and rollback. The owner now requires fresh Rust. Those assumptions are superseded for this delivery; historical records describe prior work, not current acceptance rules.

Decision

Use Loco 1.2, Tera/DaisyUI and PostgreSQL 18. Rails is read-only reference. There is no legacy data import, credentials migration, database parity, reverse migration or production deployment. Fresh-schema commands must never reset or silently adopt populated databases.

Use typed request DTO → validated command → operation → typed result → response DTO boundaries throughout root src/. Use distinct entity ID newtypes, enum dose sources, typed conflict codes, parsed timezone-aware timestamps and exact Decimal math. JSON is valid for transport, configuration, templates and document storage; internal struct → Value → struct command passing is prohibited.

Rust-native versioned portability remains in scope: decrypt, validate, authorise, preflight, apply. Historical restore must not deduct stock, enqueue live reminders or mail, or replace clinical provenance with restore time. FHIR is an external adapter; MCP triggers tools and is not the portability format. Property tests must cover replay without double deduction, side-effect-free restore, revoked authority and DST/timezone schedules. Preserve existing API/MCP contracts except the explicit access/location changes, documented together in OpenAPI, clients and ADRs.

Retain older rust/ crates as read-only reference. Obsolete rust:* and api:* Task surfaces are removed; root Task owns active Loco workflows. The root CI workflow tests the active Loco application and client tools; it does not run the superseded dashboard or Rails compatibility suites. Older crates remain tooling/test consumers and historical inputs; the Axum/Leptos application is superseded by root Loco routing. Client tools form their own workspace and use their shared API client, not these legacy application crates. Do not delete them as dead code without rechecking consumers.

Alternatives

Rails parity and legacy-schema import add work expressly removed by the owner. Deleting all older Rust sources breaks retained tooling consumers. Neither is part of this decision.

Consequences

Tests and guidance must follow fresh Rust decisions rather than encode abandoned parity. Run focused tooling checks and documentation build for guidance changes; application delivery still needs its own TDD and full relevant gates. No merge, deployment or live-data action follows from architecture acceptance.