Skip to content

Database development

The adapter provider factory supplies application-owned persistence capabilities for SQLite, MySQL, and PostgreSQL. Concrete pools and SQL remain private to the adapter layer. Operational setup belongs in database administration; this page explains how to change persistence safely.

Application/domain code owns workflow meaning, invariants, validation, and allowed transitions. Providers own authorized reads, atomic writes, transaction/lock boundaries, and durable claims or checkpoints. HTTP handlers should not reconstruct a transaction by calling several independent writes.

Shared rendering, SMTP/IMAP/webhook transport, and export generation run outside concrete provider modules. Read an authorized bounded snapshot, release the database transaction, then perform expensive generation or external work. Persist ownership and result transitions through the appropriate atomic contract.

A transaction can commit even when the client loses the commit acknowledgement. Preserve typed uncertain outcomes and reconcile by durable operation identity. Do not convert every transport failure into a definite rollback, or automatically repeat a possibly accepted SMTP send.

Test cancellation, lock timeout, pool recovery, concurrent claims, stale generations, and process restart at the boundary where they matter. Account deletion must stay consistent with domain claims and other owned records. Related child replacement and outbox/event publication must remain atomic.

Migrations are ordered, version-aware source artifacts. Preserve original history and usable legacy identities/hashes; never initialize a populated unrecognized database as empty. SQLite and MySQL have legacy-upgrade contracts; PostgreSQL has its own Ruphish schema history.

Schema inventory files are generated expectations tied to ordered migrations. Regenerate them from a fresh disposable schema only after an intentional schema change, using the provider’s checked-in inventory SQL. Exclude database names and data-dependent counters. Validate supported provider versions and test rejection of altered schemas, not just successful fresh initialization.

For MySQL, the inventory connection uses SET NAMES utf8mb4 COLLATE utf8mb4_0900_bin, matching application connections. Consult crates/ruphish-adapters/src/mysql/schema_inventory.sql and its schema.json; use the corresponding PostgreSQL sources for that provider. Do not hand-adjust metadata to hide a startup mismatch.

Use the shared provider scenarios through the public facade and executable, with independent SQL only for setup, observation, and fault injection. Keep fixtures synthetic and isolated. Run the affected provider/version cases in database-provider testing, plus shared consumers when changing shared semantics.

Preserve the legacy-test map’s source identities and implementation status. An ignored server test is not passing provider evidence. Record exact commands and distinguish a setup failure from a failed executed assertion.