Skip to content

feat(api)!: retire DAO-API drafts + migrate to User API#2046

Open
brunod-e wants to merge 8 commits into
feat/user-accounts-dashboardfrom
feat/user-drafts-cutover
Open

feat(api)!: retire DAO-API drafts + migrate to User API#2046
brunod-e wants to merge 8 commits into
feat/user-accounts-dashboardfrom
feat/user-drafts-cutover

Conversation

@brunod-e

Copy link
Copy Markdown
Collaborator

Summary

The cutover that retires draft proposals from the DAO APIs now that the User API owns them (stacked on #2044 backend and #2045 frontend). Two coordinated commits:

  1. Remove draft endpoints from the DAO APIs — deletes the /{dao}/proposal/drafts* routes + controller/service/repository/mappers, the general Postgres schema wiring (pgGeneralClient + boot migration + drizzle config), and regenerates @anticapture/client with every Draft* symbol gone (fetchers, hooks, MCP tools, models). Gateful needs no code change; its spec loses the routes on redeploy.
  2. One-shot migration script (apps/user-api/scripts/migrate-drafts.ts) — copies general.proposal_drafts from a DAO database into the User API drafts table.

Migration behaviour

  • Preserves draft ids verbatim → existing share links (?draftId=…) keep resolving.
  • Rows land unclaimed (user_id NULL) with the author wallet in author_address; the User API attaches them to a user on that wallet's first SIWE login (already implemented in DraftsService.listForUser).
  • IdempotentON CONFLICT DO NOTHING, so re-runs are safe and cross-DAO id collisions resolve first-writer-wins (logged as skipped).
  • Validates rows, supports --dry-run. Run once per DAO source database:
    SOURCE_DATABASE_URL=…dao-db DATABASE_URL=…user-db \
      pnpm --filter @anticapture/user-api migrate:drafts --dry-run
    

Safety

Verification

  • apps/api: typecheck + lint clean; offchain tests updated (they incidentally spread the general schema).
  • apps/user-api: 19 tests green incl. 5 new migration tests (unclaimed copy, idempotency, malformed-row skip, dry-run, claim-on-first-login); typecheck clean.
  • @anticapture/client: regenerated, built, typechecks; 0 Draft* symbols remain.
  • apps/dashboard: typecheck green against the draftless client.

Rollout order

Deploy #2044 + #2045 → run this migration (--dry-run first) per DAO db → merge/deploy this PR (route removal) → later: drop the orphaned general.proposal_drafts tables.

Refs DEV-978, DEV-979.

🤖 Generated with Claude Code

brunod-e and others added 2 commits July 10, 2026 07:55
Drafts are now owned by the User API (user-scoped, session-authenticated),
so the DAO APIs no longer serve them. Removes the /{dao}/proposal/drafts*
routes and their controller/service/repository/mappers, the `general`
schema wiring (pgGeneralClient + boot migration) and its drizzle config,
and drops all Draft* symbols from the regenerated @anticapture/client
(fetchers, hooks, MCP tools, models) — breaking for external SDK consumers.

The physical general.proposal_drafts table is intentionally left in each
DAO database for the one-shot migration; a later PR drops it.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Copies general.proposal_drafts rows from a DAO database into the User API
drafts table, preserving ids (share links keep resolving) and timestamps,
lowercasing the author into author_address, and leaving user_id NULL so the
row is claimed on that wallet's first SIWE login. Idempotent via ON CONFLICT
DO NOTHING (also resolves cross-DAO id collisions — first writer wins),
validates rows, and supports --dry-run. Run once per DAO source db.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@vercel

vercel Bot commented Jul 10, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
anticapture-storybook Ready Ready Preview, Comment Jul 10, 2026 7:57pm
1 Skipped Deployment
Project Deployment Actions Updated (UTC)
anticapture Ignored Ignored Jul 10, 2026 7:57pm

Request Review

Copy link
Copy Markdown
Collaborator

🎨 UI Review

Automated review · scope check only

This PR is a backend-only cutover: it removes the draft-proposal routes/controller/service/repository/mappers from apps/api, updates the Drizzle schema/migrations, and adds a one-shot apps/user-api/scripts/migrate-drafts.ts migration script. All 26 changed files are under apps/api and apps/user-api — no .tsx, no apps/dashboard, no packages/ui/design-system files, no rendered UI surface.

The @anticapture/client regeneration removes every Draft* symbol, but per the PR description the dashboard already stopped importing them (#2045) and typechecks clean against the draftless client — no visible consumer-facing change from this PR.

Out of scope for a UI review; no findings to report.


Generated by Claude Code

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 550b982440

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

title: row.title,
discussionUrl: row.discussionUrl,
body: row.body,
actions: row.actions,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Validate draft actions before migrating

If any legacy row has non-array JSON in actions (the source column is plain jsonb, so the database does not enforce the old API's array schema), this copies it into the User API even though DraftResponseSchema later parses actions as an array. That makes the migrated draft fail response validation and return a 500 on GET /drafts/{id}/list instead of being counted as invalid during the migration.

Useful? React with 👍 / 👎.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: cdeb3ab2ef

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment on lines +2 to +3
"@anticapture/api": minor
"@anticapture/gateful": minor

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Mark removed REST routes as major

Because this commit removes /{dao}/proposal/drafts* from the DAO API and therefore from Gateful's OpenAPI surface, keeping @anticapture/api and @anticapture/gateful at minor lets release automation publish a non-breaking version even though REST clients calling those endpoints will fail after deploy. Please make these package changesets major as well; the generated client is already correctly marked major.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants