Skip to content

fix(database): stop colliding with the emulator on a shared database - #209

Merged
DennisObject merged 2 commits into
devfrom
fix/shared-database-safety
Aug 14, 2026
Merged

fix(database): stop colliding with the emulator on a shared database#209
DennisObject merged 2 commits into
devfrom
fix/shared-database-safety

Conversation

@DennisObject

Copy link
Copy Markdown
Owner

Atom and the emulator share one schema, and two places in Atom assumed otherwise.

Password reset tokens move to website_password_resets

password_resets is a table emulators own — Polaris keys one by user_id with an expires_at and a created_ip. Atom's own migrations created it, renamed it, and (through the collision-aware builder on this branch's base) would reclaim it, which on a live hotel either fails the install or renames the emulator's table out from under it.

  • New migration 2026_08_14_000000 takes over the legacy table only when its columns match the one Atom created in 2014_10_12_100000 (email, token, created_at, and none of user_id / expires_at / created_ip). If website_password_resets already exists it copies the rows across instead. A foreign table is left exactly as it is, tokens and all.
  • 2014_10_12_100000, 2023_02_18_000000 and 2023_09_13_130322 grew the same shape check, so a fresh install against an existing hotel is a no-op rather than a collision.
  • PasswordResetToken and config/auth.php point at the new table.

Polaris' own repair migration adds user_id/created_ip to a CMS-era password_resets, so a hybrid table reads as foreign and Atom starts clean. Tokens live 15 minutes, so nothing durable is lost.

The installer no longer offers to wipe a hotel

The bundled Arcturus dump opens with DROP TABLE IF EXISTS for all 122 tables it ships, and ensureEmptyDatabase() would offer to clear any non-empty database — --fresh did it without asking.

HotelSchemaPreflight classifies the target database as Fresh, AtomOnly, Hotel or Unknown before anything is written, mirroring the check Polaris runs before it migrates. A Hotel — Arcturus' table signature, Polaris' flyway_schema_history, Ada's __EFMigrationsHistory, or a spread of Ada's own tables — is now refused outright, --fresh included, and the operator is pointed at --skip-arcturus. Empty and Atom-only databases keep the existing prompt, which now names the tables nobody claims.

Testing

vendor/bin/pest — 382 passed (1484 assertions), including 10 new preflight cases covering empty, Atom-only, full hotel, hotel + plugin tables, Flyway-history-only, EF-history-only, an Ada schema, a half-built hotel, and an unrelated WordPress database.

🤖 Generated with Claude Code

DennisObject and others added 2 commits August 14, 2026 21:45
Atom and the emulator share one schema, and two places in Atom assumed
otherwise.

`password_resets` is a table emulators own - Polaris keys one by user_id
with an expires_at and a created_ip. Atom's own migrations created,
renamed and (through the collision-aware builder) reclaimed a table of
that name, which on a live hotel either fails the install or renames the
emulator's table out from under it. Atom's tokens now live in
`website_password_resets`: a new migration takes over the legacy table
only when its columns match the one Atom created in 2014_10_12_100000, and
copies the rows across when the target already exists. A foreign table is
left exactly as it is, tokens and all. The historical migrations grew the
same shape check so a fresh install against an existing hotel is a no-op
rather than a collision.

The Arcturus installer offered to drop every table in a database that
already held a hotel - the bundled dump opens with DROP TABLE for all 122
tables it ships. It now inspects the database first: a schema an emulator
manages (Arcturus tables, Polaris' Flyway history, Ada's Entity Framework
history, or a spread of Ada's own tables) is refused outright, --fresh
included, and the operator is pointed at --skip-arcturus. Empty and
Atom-only databases keep the existing prompt, which now names the tables
nobody claims.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@DennisObject
DennisObject merged commit 8d1a834 into dev Aug 14, 2026
1 of 3 checks passed
@DennisObject
DennisObject deleted the fix/shared-database-safety branch August 14, 2026 21:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant