You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Add an ImportBatches table to track the origin of every record, and a nullable ImportBatchId foreign key on Quotes, Characters, Sources, and People.
Why ImportBatches, not ImportSources
The domain already has a Sources table (film/book/TV sources — "Forrest Gump", "The Matrix"). ImportBatches is unambiguous: it refers to a single import operation, not a media source.
ImportBatches table
CREATETABLEImportBatches (
Id TEXTNOT NULLPRIMARY KEY, -- UUID
Name TEXTNOT NULL, -- e.g. "vilaboim/movie-quotes", "Manual import 2026-06-16"
Type TEXTNOT NULL, -- 'seed' | 'import' | 'system'
Url TEXT, -- nullable; source URL for seed-type batches
ImportedAt TEXTNOT NULL, -- ISO 8601 UTC
ImportedBy TEXT, -- actor ID (user UUID, 'system', or provider name)
RecordCount INTNOT NULL DEFAULT 0-- denormalised; updated after each import run
);
Type values:
Type
Scenario
seed
Seeded from an external dataset (vilaboim, NikhilNamal17); has a Url
import
Bulk import via the import endpoint (#45); ImportedBy = user UUID
system
Startup seeding from the bundled quotes.json
Foreign key on entity tables
Quotes, Characters, Sources, and People each gain one nullable column:
Existing records cannot be retroactively linked to a specific batch (the information was not captured). Leave them as NULL — they are effectively "pre-provenance" records.
Add an
ImportBatchestable to track the origin of every record, and a nullableImportBatchIdforeign key on Quotes, Characters, Sources, and People.Why
ImportBatches, notImportSourcesThe domain already has a
Sourcestable (film/book/TV sources — "Forrest Gump", "The Matrix").ImportBatchesis unambiguous: it refers to a single import operation, not a media source.ImportBatchestableType values:
seedUrlimportImportedBy= user UUIDsystemquotes.jsonForeign key on entity tables
Quotes, Characters, Sources, and People each gain one nullable column:
NULL= manually created via the management UI with no associated importSchema version bump required; migration sets
ImportBatchId = NULLfor all existing rows.Pre-seeded batches for existing data
On migration, insert one
ImportBatchrow per known seed source so the existing dataset has traceable provenance:{ Name: "vilaboim/movie-quotes", Type: "seed", Url: "...", ImportedAt: <migration timestamp> }{ Name: "NikhilNamal17/popular-movie-quotes", Type: "seed", Url: "...", ImportedAt: <migration timestamp> }Existing records cannot be retroactively linked to a specific batch (the information was not captured). Leave them as
NULL— they are effectively "pre-provenance" records.Connection to existing issues
ImportBatchrow per import run; links all written records to that batch viaImportBatchIdImportBatchentry per source dataset it processes; links all records from that source to that batchImportBatchesentries complement the audit log: the audit log records field-level changes,ImportBatchesrecords the origin eventImportBatchIdto scope deletionsNotes
RecordCountis denormalised for display performance in the UI; updated after each import and after targeted resetsImportBatchestable is NOT included in the export endpoint (Export endpoint: GET /api/v1/quotes/export #47) — it is instance-specific provenance data