focus-flow/Codex Documentation/Current Software Plan/V1_ADR_003_MongoDB_Runtime_Topology.md

7.2 KiB

V1 ADR 003: MongoDB Runtime Topology

Status: Accepted during Block 16.1

Date: 2026-06-25

Context

MongoDB is the committed persistence target for V1, but the Flutter UI and pure Dart scheduling core must not own production database credentials. Block 15 completed the adapter-neutral document schema, codecs, repository contracts, index catalog, payload limits, and migration contracts.

Before adding a MongoDB dependency, Block 16 needs a runtime decision that keeps credentials inside a trusted boundary, supports transactions, and avoids deprecated MongoDB client-access products.

Sources checked on 2026-06-25:

  • MongoDB official client libraries list: https://www.mongodb.com/docs/drivers/
  • MongoDB Node.js driver docs: https://www.mongodb.com/docs/drivers/node/current/
  • MongoDB Node.js transaction docs: https://www.mongodb.com/docs/drivers/node/current/crud/transactions/
  • MongoDB transaction manual: https://www.mongodb.com/docs/manual/core/transactions/
  • MongoDB Atlas App Services EOL notice: https://www.mongodb.com/docs/api/doc/atlas-app-services-admin-api-v3/
  • Deprecated Atlas Data API docs: https://www.mongodb.com/docs/api/doc/atlas-data-api-v1/
  • Dart package checks: https://pub.dev/packages/mongo_dart and https://pub.dev/packages/mongo_db_driver

Decision

V1 selects a trusted service boundary for MongoDB persistence.

The MongoDB-owning runtime is a separate Node.js/TypeScript service using the official MongoDB Node.js driver. This service owns:

  • MongoDB connection strings and credentials;
  • TLS/SRV driver configuration;
  • client lifecycle and health checks;
  • index bootstrap from the Block 15 index catalog;
  • document reads/writes against the V1 collection contract;
  • sessions and transactions for multi-record scheduling writes;
  • redacted diagnostics and failure mapping.

The Flutter UI never connects directly to MongoDB and never receives connection strings, database credentials, raw MongoDB documents, driver clients, collections, sessions, or cursors.

The pure Dart package remains dependency-free with respect to MongoDB. Dart domain and application code continue to use repository interfaces and typed use case results. The trusted service exposes a narrow versioned application API that maps to the Block 14 use cases and Block 15 document contract.

During the UI foundation/design spike, the first Flutter UI should use the existing in-memory application composition by default. Persisted development flows may use a local trusted service process, but that process remains outside the Flutter binary and reads secrets only from runtime configuration.

Rejected Options

Direct MongoDB from Flutter or mobile Dart

Rejected. It would place database credentials in an untrusted binary and force the UI to own network/database failure modes. It also couples the UI to driver types and makes owner-scope/security mistakes harder to contain.

Pure Dart MongoDB adapter as the production V1 foundation

Rejected for now. MongoDB's official client library list does not include Dart. mongo_dart is active and useful for experiments, but it is community-supported rather than an official MongoDB driver. mongo_db_driver advertises sessions and transactions, but its package page explicitly identifies it as pre-alpha and not suitable for production. Neither should become the V1 persistence foundation without a later ADR reversing this decision.

Atlas Data API, Atlas Device SDKs, App Services, GraphQL, Functions, or

Custom HTTPS Endpoints

Rejected. MongoDB's App Services notice says these paths reached end-of-life on September 30, 2025, with database triggers remaining available. They are not a stable V1 foundation.

SQLite or another local fallback

Rejected. MongoDB remains the committed persistence target. A disconnected fallback would add an unplanned sync/reconciliation problem and violate the current persistence target rules.

Driver and Deployment Requirements

The selected service must use the official MongoDB Node.js driver current major line at implementation time.

Mandatory capabilities:

  • mongodb+srv:// and TLS-capable connections for Atlas;
  • BSON fidelity at the adapter edge;
  • sessions and multi-document transactions;
  • explicit transaction retry handling for documented retryable categories;
  • bounded connection and operation timeouts;
  • graceful startup/shutdown and health checks;
  • idempotent index creation;
  • redacted logging;
  • no raw driver values in public service DTOs.

MongoDB deployment requirements:

  • Multi-document scheduling writes require MongoDB Server 4.0 or later.
  • Transaction acceptance requires a transaction-capable deployment. V1 local and CI testing must use a replica set or supported sharded deployment, not a standalone server.
  • If the service cannot verify transaction capability at startup for a production Mongo-backed configuration, it must fail closed instead of falling back to untracked in-memory writes.

Configuration Boundary

Development configuration:

  • Uses environment variables or a local secret file excluded from git.
  • May point to a disposable local replica set or scoped Atlas development database.
  • Must use a database name or prefix that is safe for destructive test cleanup.

Test configuration:

  • Uses uniquely named disposable databases/collections.
  • Fails if the configured target does not match the expected test scope.
  • Redacts connection strings and credentials from test output.

Production configuration:

  • Secrets come from deployment secret storage.
  • The Flutter/mobile app receives only service endpoint configuration and application-layer auth/session material once that future work is explicitly planned.
  • Production authentication, account management, cross-device sync, Atlas provisioning, network allowlists, and cluster creation remain out of scope for this block.

Threat and Safety Checklist

  • No MongoDB connection string is committed to source control.
  • No MongoDB credential is embedded in Flutter, mobile, desktop, or web UI assets.
  • Normal logs do not include task titles, hidden locked-block names, full documents, connection strings, or credential fragments.
  • Every repository query and write includes owner scope.
  • Hidden locked-time details remain hidden by default in service responses.
  • Duplicate operation IDs are enforced by a unique owner-operation index.
  • Revision predicates are required for authoritative updates.
  • Transaction retries are bounded and observable.
  • A production Mongo connection failure fails closed.
  • In-memory composition remains available only as explicit local/design-spike wiring, not as a silent production persistence fallback.

Consequences

Block 16.2 must add any MongoDB dependency only in the trusted service/runtime module, not in the pure Dart core package.

The implementation path should provide two composition roots:

  • in-memory Dart application wiring for tests and UI design work;
  • trusted service-backed persistence for MongoDB-backed development and future deployment.

If a later chunk cannot implement the selected service boundary without duplicating scheduling rules unsafely, it must stop and record the blocker rather than embedding credentials in Flutter or adopting an unmaintained driver as a shortcut.