fix(database): stop colliding with the emulator on a shared database - #209
Merged
Conversation
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>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Atom and the emulator share one schema, and two places in Atom assumed otherwise.
Password reset tokens move to
website_password_resetspassword_resetsis a table emulators own — Polaris keys one byuser_idwith anexpires_atand acreated_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.2026_08_14_000000takes over the legacy table only when its columns match the one Atom created in2014_10_12_100000(email,token,created_at, and none ofuser_id/expires_at/created_ip). Ifwebsite_password_resetsalready 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_000000and2023_09_13_130322grew the same shape check, so a fresh install against an existing hotel is a no-op rather than a collision.PasswordResetTokenandconfig/auth.phppoint at the new table.Polaris' own repair migration adds
user_id/created_ipto a CMS-erapassword_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 EXISTSfor all 122 tables it ships, andensureEmptyDatabase()would offer to clear any non-empty database —--freshdid it without asking.HotelSchemaPreflightclassifies the target database asFresh,AtomOnly,HotelorUnknownbefore anything is written, mirroring the check Polaris runs before it migrates. AHotel— Arcturus' table signature, Polaris'flyway_schema_history, Ada's__EFMigrationsHistory, or a spread of Ada's own tables — is now refused outright,--freshincluded, 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