SVC-1: Schema + builtin-sync for service_config #750

Closed
opened 2026-05-02 17:26:25 +00:00 by claude-desktop · 1 comment
Collaborator

Bundle directive

This story ships in one PR with #743 (AT-1) and #754 (LBL-1) — the foundation layer. Assign #743, not this issue. The PR closes all three (Closes #743 #750 #754).


As a platform engineer, I want a service_config table and a builtin-sync pass that mirrors config/service.json into scope='builtin', so that runtime reads of deploy-time service infra (forge URL, container image, watchdogs, auth, node_flows, penpot, MCP command) can move off the file system onto a DB-backed source of truth.

Acceptance criteria

Schema

  • migrations/<n>-service-config.ts creates the service_config table with the columns + scope check (builtin/global only) + UNIQUE(scope) constraint per specs/config-to-db.md § Architecture.
  • Webhook secret moves to the SC-6 secret table — the schema migration reads the file's bytes (one-shot), writes them to secret, stores the FK in service_config.webhook_secret_ref, and renames the file to .<basename>.migrated.bak.

Builtin sync

  • syncServiceConfigBuiltin(serviceJsonPath) writes the single scope='builtin' row. Idempotent.
  • getServiceConfig() returns the most-specific row across global → builtin.

Tests

  • Unit: idempotent sync, scope ladder merge.
  • Integration: a scope='global' override on container_image is preserved across a re-sync that bumps the builtin's value.

Out of scope

  • Swapping consumers — covered by SVC-2.
  • Hot reload of service infra mid-run — out of scope per spec non-goals.
  • Dashboard CRUD UI — covered by SVC-3.

References

  • Spec: specs/config-to-db.md § Story SVC-1, § Architecture.
  • Bundled with: #743 (AT-1), #754 (LBL-1) — assign #743, this closes via the same PR.
## Bundle directive This story ships in **one PR with #743 (AT-1) and #754 (LBL-1)** — the foundation layer. **Assign #743**, not this issue. The PR closes all three (`Closes #743 #750 #754`). --- As a platform engineer, I want a `service_config` table and a builtin-sync pass that mirrors `config/service.json` into `scope='builtin'`, so that runtime reads of deploy-time service infra (forge URL, container image, watchdogs, auth, node_flows, penpot, MCP command) can move off the file system onto a DB-backed source of truth. ## Acceptance criteria ### Schema - [ ] `migrations/<n>-service-config.ts` creates the `service_config` table with the columns + scope check (`builtin`/`global` only) + UNIQUE(scope) constraint per `specs/config-to-db.md` § Architecture. - [ ] Webhook secret moves to the SC-6 `secret` table — the schema migration reads the file's bytes (one-shot), writes them to `secret`, stores the FK in `service_config.webhook_secret_ref`, and renames the file to `.<basename>.migrated.bak`. ### Builtin sync - [ ] `syncServiceConfigBuiltin(serviceJsonPath)` writes the single `scope='builtin'` row. Idempotent. - [ ] `getServiceConfig()` returns the most-specific row across `global → builtin`. ### Tests - [ ] Unit: idempotent sync, scope ladder merge. - [ ] Integration: a `scope='global'` override on `container_image` is preserved across a re-sync that bumps the builtin's value. ## Out of scope - Swapping consumers — covered by SVC-2. - Hot reload of service infra mid-run — out of scope per spec non-goals. - Dashboard CRUD UI — covered by SVC-3. ## References - Spec: `specs/config-to-db.md` § Story SVC-1, § Architecture. - Bundled with: #743 (AT-1), #754 (LBL-1) — assign #743, this closes via the same PR.
Author
Collaborator

Shipped via PR #761 (commit 28027b9) as part of the foundation bundle alongside #743 (AT-1) and #754 (LBL-1). The PR body lacked the Closes keyword so this issue stayed open by mistake — closing now.

Coverage:

  • migrations/<n>-service-config.ts created
  • syncServiceConfigBuiltin(serviceJsonPath) writes the single scope='builtin' row, idempotent
  • getServiceConfig() resolves global → builtin
  • Webhook secret migration into the SC-6 secret table

Closing.

Shipped via PR #761 (commit `28027b9`) as part of the foundation bundle alongside #743 (AT-1) and #754 (LBL-1). The PR body lacked the `Closes` keyword so this issue stayed open by mistake — closing now. Coverage: - `migrations/<n>-service-config.ts` created - `syncServiceConfigBuiltin(serviceJsonPath)` writes the single `scope='builtin'` row, idempotent - `getServiceConfig()` resolves `global → builtin` - Webhook secret migration into the SC-6 `secret` table Closing.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
charles/claude-hooks#750
No description provided.