Skip to content

feat: migration script for legacy pkg api_keys → business PG- format#11

Merged
rubenhensen merged 2 commits into
mainfrom
feat/migrate-legacy-api-keys
Apr 22, 2026
Merged

feat: migration script for legacy pkg api_keys → business PG- format#11
rubenhensen merged 2 commits into
mainfrom
feat/migrate-legacy-api-keys

Conversation

@dobby-coder

@dobby-coder dobby-coder Bot commented Apr 21, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Adds scripts/migrate-legacy-api-keys.ts plus a pure planner in src/lib/server/migrations/legacy-api-keys.ts that turns rows from the old pg-pkg api_keys table into organizations + business_api_keys inserts.
  • Legacy plaintext keys are SHA-256 hashed so they keep validating once the pkg validator switch (Migrate pkg API key validation to use postguard-business PG- keys postguard#140) ships — no re-keying required in this PR.
  • Dry-run is the default; --live wraps the writes in a single transaction and is idempotent.
  • 16 unit tests (pure logic), svelte-check clean, prettier + eslint clean.

Refs encryption4all/postguard#141.
Coordinates with encryption4all/postguard#140 (pkg validator switch — different dobby working it concurrently).

Why draft — open product questions

All spelled out in docs/migrate-legacy-api-keys.md, short version:

  1. Re-key vs preserve. This PR preserves. Requires the pkg validator to accept non-`PG-` prefixed hashes during the transition. If we want a hard cutover, the script needs to generate fresh keys and send notifications (out of scope here).
  2. Grouping heuristic. kvk → org name → email domain → email is a best guess. If the real population has known structure it should fail loudly rather than fall back silently.
  3. Org status. Migrated orgs land pending. If they should be grandfathered to active, flip the default.
  4. `created_by`. Left NULL. Alternative: create a synthetic "legacy migration" admin row.

@rubenhensen please weigh in.

Test plan

  • `npx vitest run tests/unit/legacy-api-keys.test.ts` — 16/16 pass
  • `npx svelte-check` — 0 errors
  • `npx prettier --check` + `npx eslint` — clean
  • `npx vite build` — succeeds
  • Real dry-run against a snapshot of the production pkg DB (maintainer only — script has no access to live data)
  • Live migration (pending answers to the four questions above)

🤖 Generated with Claude Code

Introduces `scripts/migrate-legacy-api-keys.ts` plus a pure planner in
`src/lib/server/migrations/legacy-api-keys.ts` that turns rows from the
old `pg-pkg` `api_keys` table into `organizations` + `business_api_keys`
inserts.

The planner hashes the legacy plaintext key with SHA-256 so existing
keys continue to validate once encryption4all/postguard#140 ships.
Organisations are grouped by kvk → org name → email domain → email and
given deterministic, unique synthetic domains when no real domain is
available.

Known open product decisions (full list in
`docs/migrate-legacy-api-keys.md`):

  - whether to preserve legacy keys or re-key users
  - the exact grouping heuristic
  - `status`/`created_by` defaults for migrated orgs

The live migration is transactional and the dry-run is the default.

Refs encryption4all/postguard#141
Coordinates with encryption4all/postguard#140

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Migrated orgs are existing users and should be grandfathered to active
status, not left pending. Updates docs to reflect all four resolved
product decisions.
@rubenhensen rubenhensen marked this pull request as ready for review April 22, 2026 08:30
@rubenhensen rubenhensen merged commit 8e40573 into main Apr 22, 2026
7 checks passed
@rubenhensen rubenhensen deleted the feat/migrate-legacy-api-keys branch April 22, 2026 08:30
@dobby-coder

dobby-coder Bot commented Apr 22, 2026

Copy link
Copy Markdown
Contributor Author

Dobby has seen the approval, sir! Dobby is most grateful that Master rubenhensen has approved Dobby's migration script! 🧦

Dobby notices the PR is already merged — Dobby is a happy elf! Dobby will check if there is anything else to follow up on.

@dobby-coder

dobby-coder Bot commented Apr 22, 2026

Copy link
Copy Markdown
Contributor Author

Thanks for the review and merge! I've updated the tracking comment on encryption4all/postguard#141 with the remaining items (dry-run against prod data, live migration execution, coordination with postguard#142). The migration code is in main and ready to go.

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