Skip to content

test(migrate): a covered bundle grant takes its repository at the claim and binds its site - #454

Merged
ABB65 merged 1 commit into
mainfrom
t7/covered-grant-bind-test
Oct 10, 2026
Merged

ABB65 merged 1 commit into
mainfrom
t7/covered-grant-bind-test

Conversation

@ABB65

@ABB65 ABB65 commented Oct 10, 2026

Copy link
Copy Markdown
Member

What

Test only. It proves that a covered "Migrate with Studio" grant still reaches the site binding. Covered means the account's own running plan covers the order. Such a grant is redeemed at provision time, before delivery, and has no repository yet.

Paired with Contentrain/migrate#758, which records the covered Studio line on the Migrate order so its forms wait for this bind (run 3 R3-1/R3-2/R3-3).

The chain (origin/main 66360b0)

  1. server/utils/migrate-provision.ts:97-120 provisionCovered: claimMigrateGrant with kind: 'bundle' and no repository, binds the workspace, markMigrateGrantRedeemed(id, null).
  2. server/api/migrate/claim.post.ts:49 (after delivery, same order): postgres-db/migrate-grants.ts:92-135 does insert … onConflict(order_id).doNothing, then returns the existing row. There is no state filter, so the redeemed grant comes back.
  3. claim.post.ts:62: the same user.
  4. claim.post.ts:69-70: a bundle grant with no repository → setMigrateGrantRepo (:266-281, written only while the repository is null).
  5. connect-project.post.ts:41: bundle + redeemed_at + workspace + owner + name all hold → project + site binding (feat(migrate): bind a bundle's delivered site to its project (studio.json) #452), retried by the sweep (feat(migrate): retry a bundle site's binding and raise the alarm when it stays unbound #453).

Result: no Studio change needed. One thing the contract run showed: Postgres checks migrate_grants_trial_shape on the candidate row before the order conflict, so step 2 works because Migrate always signs trial_days (migrate apps/web/server/api/orders/[orderId]/studio-claim.post.ts:91: the bundle's days, default 60). A claim without trial_days would fail there for every bundle grant, paid or covered. The contract test pins this.

Tests

  • tests/unit/migrate-covered-grant-chain.test.ts (2), run against one stateful grant store with the provider's semantics:
    • the real provisionMigrateBundle (covered) → POST /api/migrate/claim → POST …/connect-project, ending with the project created, the site binding asked for the delivered repository through the workspace's installation, and siteBinding: written;
    • a second claim never moves the repository.
  • tests/contract/migrate-grants.contract.test.ts (+1, postgres:16): the same sequence on the real SQL (covered claim → bind → redeem → delivery claim → existing row → repository set). The stored row passes connect-project's gate.

Gate

Check Result
pnpm test:ci unit 2247 passed / 1 skipped
pnpm test:ci integration 515
pnpm test:ci nuxt 350
contract migrate-grants (postgres:16) 24/24
pnpm typecheck 0 (after contentrain-query generate, as CI does)
pnpm lint 0 errors (7 warnings, all in files this PR does not touch)
hooked commit green

…im and binds its site

A covered bundle grant (the account's own plan covers the order) is redeemed
at provision time, before delivery, with no repository. This proves it still
reaches the site binding. The post-delivery claim hands the redeemed row back
and gives it the delivered repository. connect-project then lets it through
and binds the site.

- unit: the real provisionMigrateBundle (covered) → claim.post →
  connect-project.post over one stateful grant store.
- contract: the same sequence on postgres. The candidate row passes
  migrate_grants_trial_shape (Migrate always signs trial_days) before the
  order conflict.

Pairs with migrate#758.
@ABB65

ABB65 commented Oct 10, 2026

Copy link
Copy Markdown
Member Author

ork2 review @c1f86c58: OK (test-only, paired with migrate#758). It proves ORK's MUST: a covered grant, redeemed before delivery, still gets its repo from the post-delivery claim and passes connect-project → site binding. Unit chain (real provisionMigrateBundle covered → claim.post → connect-project.post) + contract on postgres:16 (24/24). The trial_days / trial_shape fragility is now pinned by the contract test. Gate (t7): test:ci unit 2247 / integration 515 / nuxt 350, typecheck 0.

@ABB65
ABB65 merged commit e852d41 into main Oct 10, 2026
2 checks passed
@ABB65
ABB65 deleted the t7/covered-grant-bind-test branch October 10, 2026 04:33
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