ADR-0020: Single business database (drop martin / erd dual DB)
- Status: Accepted (2026-08-03)
- Decision makers: Project maintainers
Context
Application long used two DBs on same MySQL instance: martin (system/auth) and erd (modeling metadata), dual Hikari + SqlSessionFactory routed by mapper package. Railway / remote plugin MySQL defaults one DB name (often railway); dual DB creation and db/init seeding became deployment main pain.
Historical comment said sys_user / sys_role name collision prevents merge. Audit result:
| Source | Conflicting tables | Conclusion |
|---|---|---|
martin | Full sys_user / sys_role (auth source of truth) | Keep |
Old erd dump | Same-name stub tables (id/username/password only) | Zero erd mapper references, discard on merge |
No other table name overlap; can coexist same DB.
Decision
- Physically single DB: default name
erd(envMYSQLDATABASE; noDB_ERD/DB_MARTIN/DB_NAMEfallback). db/initschema only:01_create_database.sql+02_tables.sql(CREATE TABLE); no seeds, demo, privileges scripts.- Seeds in Flyway:
backend/.../db/migration/erd/V3+(system baseline / new user permissions / public demo / E2E accounts); backend startup runs viaErdFlywayConfig. - Transition keeps dual SqlSessionFactory:
martinDataSourceanderdDataSourcestill separated by package scan, but JDBC URL points to sameMYSQLDATABASE, credentials sameMYSQLUSER/MYSQLPASSWORD(avoid mapper explosion this round). Single DS merge can be future ADR. - Env vars: Spring reads Railway plugin native names directly (
MYSQLHOST/MYSQLPORT/MYSQLDATABASE/MYSQLUSER/MYSQLPASSWORD), each single placeholder, no nested fallback. Compose: MySQL container officialMYSQL_DATABASE/MYSQL_USER/MYSQL_PASSWORD, backend injects sameMYSQL*.
Consequences
- Railway: Link MySQL injects
MYSQL*; create one DB + import schema; Redeploy then Flyway seeds. No longer requireDB_MARTIN≠DB_ERDtwo DBs, norDB_*Variable Reference. - Local existing dual DB data volume: must rebuild volume (
docker compose down -vthen up) or manually migratemartin.*tables intoerdand setMYSQLDATABASE=erd. - Production existing dual DB data: export both sides → import single business DB (discard erd stub
sys_*) →MYSQLDATABASEpoints there → confirmflyway_schema_historythen baseline / run missing versions as needed. - E2E seeds enter DB via Flyway; public login still rejected by
erd.security.e2e-accounts-enabled=false.
Verification
mvn -q -DskipTests compile./scripts/railway-mysql-init.sh --dry-runlists only01+02- Empty volume compose first start backend Flyway ≥ V6;
SELECT COUNT(*) FROM erd.sys_user> 0