Skip to content

fix(setup): make TimeTracker.sql idempotent against an existing schema#57

Merged
CryptoJones merged 1 commit into
masterfrom
fix/setup-sql-idempotent
May 18, 2026
Merged

fix(setup): make TimeTracker.sql idempotent against an existing schema#57
CryptoJones merged 1 commit into
masterfrom
fix/setup-sql-idempotent

Conversation

@CryptoJones
Copy link
Copy Markdown
Owner

Fixes the docker compose down -v papercut documented in #56.

The bug

setup/TimeTracker.sql is pg_dump output that does an unconditional CREATE SCHEMA dbo at line 23. Against a populated postgres volume (the common case on re-runs), psql exits 3 — and because the compose migrate service depends_on setup completing successfully, the entire bring-up chain breaks.

The fix

Gate the file with a psql \if check on information_schema.schemata. If the dbo schema already exists, print "no-op" and \q (exit 0). Otherwise, the rest of the pg_dump body runs exactly as before.

Picked over the alternative of retrofitting IF NOT EXISTS to every statement because ALTER TABLE ADD CONSTRAINT has no IF NOT EXISTS form — the file would still fail mid-way through.

Test plan

  • Against live PG with dbo schema present: psql exits 0 with the "no-op" message
  • Against live PG after DROP SCHEMA dbo CASCADE: fresh bootstrap runs to completion, 14 tables created
  • Immediate re-run after fresh bootstrap: no-op, exit 0
  • Doesn't disturb the migrate service that runs after — that's a separate Sequelize-CLI invocation

After this lands, the down -v step in the integration-test docs can be removed.

Proudly Made in Nebraska. Go Big Red! 🌽 https://xkcd.com/2347/

setup/TimeTracker.sql is the pg_dump-produced bootstrap script. It
wasn't authored with idempotency in mind: \`CREATE SCHEMA dbo\`
(no IF NOT EXISTS), followed by ~40 statements that include
\`CREATE TABLE\` without IF NOT EXISTS and \`ALTER TABLE ADD
CONSTRAINT\` (which has no IF NOT EXISTS form at all).

Result: \`docker compose up setup\` against a populated postgres
volume exits 3 with "schema dbo already exists", which in turn
prevents the chained \`migrate\` service from running, which left
the docs in PR #56 with the \`docker compose down -v\` papercut.

Rather than retrofit IF-NOT-EXISTS guards to every individual
statement (and lose on ADD CONSTRAINT), gate the entire file at
the top with a psql \\if check:

  SELECT EXISTS (
      SELECT 1 FROM information_schema.schemata WHERE schema_name = 'dbo'
  ) AS dbo_exists \\gset
  \\if :dbo_exists
  \\echo 'dbo schema already exists — setup/TimeTracker.sql is a no-op'
  \\q
  \\endif

If the schema is there, psql exits 0 with a friendly message;
the chained migrate service then runs as designed. If the schema
isn't there, the rest of the pg_dump body executes exactly as
before.

Verified locally against the running compose postgres:
  - DROP SCHEMA dbo CASCADE → fresh run exit 0, 14 tables created
  - immediate re-run → "no-op" message, exit 0
  - subsequent migrate service still works (verified earlier this session)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@CryptoJones CryptoJones merged commit 6c684f9 into master May 18, 2026
2 of 3 checks passed
@CryptoJones CryptoJones deleted the fix/setup-sql-idempotent branch May 18, 2026 00:25
CryptoJones added a commit that referenced this pull request May 18, 2026
PR #57 made setup/TimeTracker.sql idempotent (psql \\if guard at
top → no-op when dbo schema already exists). The "setup exits 3
on re-run" gotcha note in tests/integration/README.md was no
longer accurate. Replaces the gotcha with a positive note that
re-runs are now safe, and reframes the \`down -v\` step from
"workaround" to "intentional fresh-DB cleanup."

Co-authored-by: Aaron K. Clark <akclark@thenetwerk.net>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
CryptoJones added a commit that referenced this pull request May 18, 2026
Continues the docs-sync pattern from #44 and #53. CHANGELOG
[Unreleased] now reflects:

  Added:
    - Sequelize associations (#54)
    - Integration test harness (#55)
    - Postman collection (#59)
    - TLS reverse-proxy compose (#60)
    - docker-compose.override.yml committed (#56)

  Fixed:
    - setup/TimeTracker.sql idempotency (#57) — removes the
      \`docker compose down -v\` workaround

  Docs:
    - Integration bring-up flow (#56, #58)
    - README sections for Testing and Behind TLS

Co-authored-by: Aaron K. Clark <akclark@thenetwerk.net>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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