Local work has been stranded on one machine: `make seed` replays seed/fixtures/seed.json, which is generated from krow-demo and has never reflected what is in a database. Agents published through importagents, knowledge ingested, applications screened — none of it had a path to another deployment. `make export-data` reads the database itself and writes replayable SQL. Three things it does deliberately: Tables are ordered topologically from pg_constraint rather than left in pg_dump's own order, which sorts by name and so fails on foreign keys in a way that depends on what the tables are called. Parents always precede children, and Kahn's algorithm breaks ties alphabetically so two runs against one schema produce a byte-identical file. Every statement is INSERT ... ON CONFLICT DO NOTHING. The export can create rows on a target and cannot modify or delete one. That is a property of the generated file, not a rule someone has to remember when they apply it. The file refuses to apply to a schema older than the one it came from. A restore into a half-migrated database half-succeeds, and a partial import is harder to unpick than a failed one. pg_dump 18 wraps its output in the psql meta-commands \restrict and \unrestrict. Dumping per table left the closing one without its opener, which fails with "not currently in restricted mode" and, under --single-transaction, rolls back having inserted nothing — silently, if the caller reads psql's output through a pipe instead of its exit code. Each table's slice is therefore cut at the last line ending in a semicolon, which no line of pg_dump's epilogue does and every generated statement does. sessions and schema_migrations are excluded: sessions are bound to cookies one deployment issued, and a stale schema_migrations row would make the target lie about its own version. Verified against a scratch database migrated to 15: all 25 tables match the source row for row, a second run is a no-op, and the guard refuses a version-10 target. The output is real tenant data — password hashes, personal details — so seed/exports/ is gitignored. It moves over scp, not through git. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
29 lines
727 B
Plaintext
29 lines
727 B
Plaintext
# Secrets and local configuration
|
|
# A bare pattern matches at any depth, so this covers infrastructure/.env too.
|
|
|
|
# TLS material. The local-db overlay generates a self-signed pair inside the
|
|
# postgres volume, but nothing stops someone dropping certs here by hand.
|
|
*.pem
|
|
*.key
|
|
*.crt
|
|
|
|
# Structural snapshots taken before destructive migrations
|
|
krowdb_public_snapshot_*.sql
|
|
|
|
# Go build output
|
|
/go-api/bin/
|
|
*.test
|
|
*.out
|
|
|
|
# Editor / OS
|
|
.DS_Store
|
|
.idea/
|
|
.vscode/
|
|
|
|
# Filled-in Kubernetes secret (the .example is the committed template)
|
|
infrastructure/k8s/10-secret.yaml
|
|
|
|
# Database exports. Real tenant data — password hashes, personal details.
|
|
# Generated by `make export-data`; move it over scp, never through git.
|
|
seed/exports/
|