Purpose
The Migrations CLI inspects local Fireway migration files and compares them with Firestore migration records. It uses the same MigrationExplorerService as the macOS module.
All successful commands print JSON. Failures return exit code 1 with a readable error on stderr.
Status And List
migrations status --project Local --directory ./migrations --collection fireway
migrations list --project Local --directory ./migrations --collection fireway
status and list are aliases. They load local migration files, query the configured Firestore migration collection, and classify each migration as:
applied: local file and remote record exist, and checksum matches or the remote record has no checksum.drifted: local file and remote record exist, but checksum differs.pending: local file exists without a remote record.missing: remote record exists without a local file.
Options:
--directory <path>is required unless the selected project has a local workspace path; when a workspace path exists, the default is<workspace>/migrations.--collection <path>defaults tofireway.--project <name|firebaseProjectID|uuid>overrides the selected project.--limit <count>controls the remote Firestore query limit and defaults to1000.
Output includes selected project JSON, local/remote counts, status counts, status rows, local files, remote records, logs, and executionMode: inspection-only.
Show Migration
migrations show 001_add_users --project Local --directory ./migrations --collection fireway
migrations show --id 001_add_users --project Local --directory ./migrations --collection fireway
show returns the status row, local file metadata, remote record metadata, and full local source content for one migration ID.
Record Applied
migrations record-applied 001_add_users --project Local --directory ./migrations --collection fireway --confirm
migrations record-applied --all-pending --project Local --directory ./migrations --collection fireway --confirm
record-applied is explicitly record-only. It does not execute Fireway source
code. It writes migration records for pending local files to the configured
Firestore emulator collection, including checksum, source path, applied
timestamp, status, and rollback note metadata. The command requires --confirm,
rejects read-only projects, and currently supports emulator projects only.
Output includes selected project JSON, executionMode: record-only, requested
and recorded IDs, skipped IDs, refreshed status counts, rollback notes, logs,
and a task snapshot.
Apply Migration
migrations apply 005_apply_writes --project Local --directory ./migrations --collection fireway --confirm
migrations apply --all-pending --project Local --directory ./migrations --collection fireway --confirm
apply executes pending migration JavaScript against a Firestore emulator target.
It requires --confirm, rejects read-only projects, and currently rejects
non-emulator projects until approved live verification exists.
The emulator execution adapter supports migration source files that expose an
up function through module.exports = async (...) => {}, module.exports.up,
exports.up, or a top-level/exported up. The migration function receives a
helper object with db, firestore, admin, collection, doc, batch,
projectID, databaseID, environment, migrationID,
migrationFileName, migrationSourcePath, and migrationCollectionPath.
Firestore writes emitted by the script are applied to the emulator through the shared Firestore write service. After successful script execution, Firestruct records the migration in the configured migration collection with checksum, source path, status, timestamp, and rollback-note metadata.
Output includes selected project JSON, executionMode: emulator-fireway-js,
requested and executed IDs, script results, applied Firestore mutation count,
refreshed status counts, rollback notes, logs, and a task snapshot.
Execution Boundary
The Migrations CLI distinguishes three workflows:
status/list/show: inspection only.record-applied: record-only state write for externally executed migrations.apply: emulator-only JavaScript execution with Firestore emulator mutation proof and migration-state recording. Production/live apply is not available until approved live verification proves the same workflow safely.
Current Verification
FirestructCLIIntegrationTests/testCLICommandsRoundTripAgainstFirebaseEmulators writes local migration files, creates Firestore emulator migration records, runs migrations status, asserts applied/drifted/missing/pending counts, runs migrations show and asserts the drifted status plus source content, verifies record-applied rejects missing --confirm, records a pending local migration, then queries the Firestore emulator to assert the migration record exists with status: applied and checksum metadata. The same emulator test verifies migrations apply rejects missing --confirm, executes 005_apply_writes through executionMode: emulator-fireway-js, asserts one Firestore mutation was applied, queries the target emulator collection to prove the script wrote the expected document, and queries the migration collection to prove the migration record exists with status: applied.
Source Anchors
Sources/FirestructCLIKit/MigrationsCommand.swiftSources/FirestructCore/ProjectRegistry+Migrations.swiftSources/FirestructCore/FirewayIntegrationService.swift