fix(kit): harden store verification integrity - #313
Conversation
|
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #313 +/- ##
===========================================
- Coverage 84.11% 71.86% -12.26%
===========================================
Files 55 134 +79
Lines 7317 14407 +7090
Branches 1701 4022 +2321
===========================================
+ Hits 6155 10353 +4198
- Misses 714 4054 +3340
+ Partials 448 0 -448
Flags with carried forward coverage won't be shown. Click here to find out more.
🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Actionable comments posted: 6
🧹 Nitpick comments (3)
packages/kit/convex/purchases/amazon-reconciliation.test.ts (1)
51-62: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueHonor the direction argument in the
orderfake.
MemQuery.orderignores_directionand always sorts ascending. The fake therefore passes even if the production claim query switches to"desc", which would select the least-due rows. Apply the direction so the fake keeps detecting that change.♻️ Proposed change
- order(_direction: "asc" | "desc"): MemQuery { + order(direction: "asc" | "desc"): MemQuery { + const sign = direction === "asc" ? 1 : -1; return new MemQuery( [...this.rows].sort((left, right) => { const leftAt = left.nextAmazonReconcileAt; const rightAt = right.nextAmazonReconcileAt; return ( - (typeof leftAt === "number" ? leftAt : -Infinity) - - (typeof rightAt === "number" ? rightAt : -Infinity) + sign * + ((typeof leftAt === "number" ? leftAt : -Infinity) - + (typeof rightAt === "number" ? rightAt : -Infinity)) ); }), ); }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/kit/convex/purchases/amazon-reconciliation.test.ts` around lines 51 - 62, Update MemQuery.order to honor its direction argument instead of ignoring it: retain the current ascending sort for "asc" and reverse the comparison for "desc", while preserving the existing handling of non-numeric nextAmazonReconcileAt values.packages/kit/convex/purchases/internal.ts (1)
536-546: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick winConsider a longer deferral for rows that can never be reconciled.
A malformed row or a row under project deletion is deferred by only
AMAZON_RECONCILE_LEASE_MS(12 minutes). Such rows return to the front of the due index on the next tick and consume claim slots repeatedly. A permanently malformed backlog larger thanAMAZON_RECONCILE_BATCH_LIMITcan starve reconcilable rows. Use the retry interval for the skip path so unusable rows back off further.♻️ Proposed change
- // Keep a malformed legacy row from monopolizing the front of the due - // index while project deletion or an operator repair catches up. - await ctx.db.patch(purchase._id, { nextAmazonReconcileAt: leaseUntil }); + // Keep a malformed legacy row from monopolizing the front of the due + // index while project deletion or an operator repair catches up. Use + // the longer retry interval because this row cannot be probed at all. + await ctx.db.patch(purchase._id, { + nextAmazonReconcileAt: now + AMAZON_RECONCILE_RETRY_MS, + });
AMAZON_RECONCILE_RETRY_MSis already exported from./shared.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/kit/convex/purchases/internal.ts` around lines 536 - 546, Update the skip path in the purchase reconciliation loop around the requestData.store, purchase.remoteId, project, and project.pendingDeletion checks to defer unusable rows using the exported AMAZON_RECONCILE_RETRY_MS interval rather than AMAZON_RECONCILE_LEASE_MS. Keep the existing patch-and-continue behavior unchanged.knowledge/_claude-context/context.md (1)
4-4: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winRegenerate the generated artifacts from their source inputs.
scripts/agent/compile-context.tsgenerates all three files. Update the source inputs, then run(cd scripts/agent && bun run compile:ai). Do not edit the artifacts directly.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@knowledge/_claude-context/context.md` at line 4, Regenerate all three generated artifacts using scripts/agent/compile-context.ts after updating the source inputs; do not edit artifacts directly. Apply this to knowledge/_claude-context/context.md:4-4, packages/docs/public/llms-full.txt:6-6, and packages/docs/public/llms.txt:6-6 by running (cd scripts/agent && bun run compile:ai).Sources: Coding guidelines, Learnings
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@knowledge/external/webhook-mapping.md`:
- Around line 89-92: Update the Amazon RVS reconciliation wording in
knowledge/external/webhook-mapping.md (lines 89-92) to state that the worker
schedules bounded revisits and does not guarantee every row is checked within 72
hours. Regenerate the corresponding corrected wording in
knowledge/_claude-context/context.md (lines 4763-4766) and
packages/docs/public/llms-full.txt (lines 2044-2047), matching the completion
caveat from packages/kit/README.md.
In `@packages/kit/public/llms-full.txt`:
- Around line 84-105: Update the purchases data-model summary near the existing
`purchases/` description to include `amazon` alongside `apple`, `google`, and
`horizon`, ensuring it matches the documented Amazon purchase-row persistence
and refresh behavior.
In `@packages/kit/src/pages/auth/organization/project/products.tsx`:
- Around line 1131-1145: Update the Horizon catalog sync notice styling around
the Info panel so its text and link use contrast-safe colors in the light theme
instead of text-blue-200, while preserving the existing blue informational
appearance and layout.
In `@packages/kit/src/pages/docs/sections/introduction.tsx`:
- Line 101: Update the normalized response summaries to consistently include the
optional environment? field: in
packages/kit/src/pages/docs/sections/introduction.tsx at lines 101-101, add it
to the earlier result near Line 20; in packages/docs/public/llms-full.txt at
lines 2039-2047, add it to the IAPKit response summary near Line 2056, then
regenerate the generated reference.
In `@packages/kit/src/pages/docs/sections/quickstart.tsx`:
- Around line 179-198: Add an Amazon Appstore entry or settings link to the
store-configuration list in the quickstart setup section before the Amazon
verification example. Reference the existing Amazon RVS shared-secret
configuration and Cloud Sandbox opt-in so users can complete the documented flow
without leaving the quickstart.
In `@scripts/assert-lcov-coverage.mjs`:
- Around line 7-12: Update sourcePathSegments to normalize "." and ".." segments
before prefix matching, resolving parent-directory traversal so paths like
convex/../server/api.ts are evaluated under server rather than convex. Add a
regression test covering this traversal path and verify it does not match the
Convex prefix.
---
Nitpick comments:
In `@knowledge/_claude-context/context.md`:
- Line 4: Regenerate all three generated artifacts using
scripts/agent/compile-context.ts after updating the source inputs; do not edit
artifacts directly. Apply this to knowledge/_claude-context/context.md:4-4,
packages/docs/public/llms-full.txt:6-6, and packages/docs/public/llms.txt:6-6 by
running (cd scripts/agent && bun run compile:ai).
In `@packages/kit/convex/purchases/amazon-reconciliation.test.ts`:
- Around line 51-62: Update MemQuery.order to honor its direction argument
instead of ignoring it: retain the current ascending sort for "asc" and reverse
the comparison for "desc", while preserving the existing handling of non-numeric
nextAmazonReconcileAt values.
In `@packages/kit/convex/purchases/internal.ts`:
- Around line 536-546: Update the skip path in the purchase reconciliation loop
around the requestData.store, purchase.remoteId, project, and
project.pendingDeletion checks to defer unusable rows using the exported
AMAZON_RECONCILE_RETRY_MS interval rather than AMAZON_RECONCILE_LEASE_MS. Keep
the existing patch-and-continue behavior unchanged.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: cf78847a-153c-4b69-8c9c-9d5048bca28b
⛔ Files ignored due to path filters (1)
packages/kit/convex/_generated/api.d.tsis excluded by!**/_generated/**
📒 Files selected for processing (49)
.github/workflows/deploy-kit.ymlcodecov.ymlknowledge/_claude-context/context.mdknowledge/external/webhook-mapping.mdpackages/docs/public/llms-full.txtpackages/docs/public/llms.txtpackages/kit/CONVENTION.mdpackages/kit/README.mdpackages/kit/convex/crons.tspackages/kit/convex/projects/mutation.tspackages/kit/convex/purchases/amazon-reconciliation.test.tspackages/kit/convex/purchases/amazon.test.tspackages/kit/convex/purchases/amazon.tspackages/kit/convex/purchases/errors.tspackages/kit/convex/purchases/horizon.test.tspackages/kit/convex/purchases/horizon.tspackages/kit/convex/purchases/internal.tspackages/kit/convex/purchases/save-purchase-idempotency.test.tspackages/kit/convex/purchases/shared.tspackages/kit/convex/schema.tspackages/kit/convex/subscriptions/horizon.tspackages/kit/convex/subscriptions/horizonInternal.test.tspackages/kit/convex/subscriptions/horizonInternal.tspackages/kit/convex/subscriptions/revenueMetrics.test.tspackages/kit/convex/subscriptions/revenueMetrics.tspackages/kit/convex/subscriptions/stats.tspackages/kit/convex/webhooks/internal.tspackages/kit/package.jsonpackages/kit/public/llms-full.txtpackages/kit/server/api/v1/replay-guard.test.tspackages/kit/server/api/v1/replay-guard.tspackages/kit/server/api/v1/route-input-schemas.test.tspackages/kit/server/api/v1/route-input-schemas.tspackages/kit/server/api/v1/route-response-schemas.test.tspackages/kit/server/api/v1/route-response-schemas.tspackages/kit/server/api/v1/routes.test.tspackages/kit/server/api/v1/routes.tspackages/kit/src/pages/auth/organization/project/products.tsxpackages/kit/src/pages/auth/organization/project/settings.test.tsxpackages/kit/src/pages/auth/organization/project/settings.tsxpackages/kit/src/pages/auth/organization/project/webhooks.tsxpackages/kit/src/pages/docs/sections/api.tsxpackages/kit/src/pages/docs/sections/introduction.tsxpackages/kit/src/pages/docs/sections/operations.tsxpackages/kit/src/pages/docs/sections/quickstart.tsxpackages/kit/src/pages/docs/sections/verification-horizon.tsxscripts/assert-lcov-coverage.mjsscripts/assert-lcov-coverage.test.mjsscripts/audit-non-godot-parity.mjs
💤 Files with no reviewable changes (4)
- packages/kit/convex/subscriptions/horizon.ts
- packages/kit/convex/webhooks/internal.ts
- packages/kit/convex/subscriptions/horizonInternal.test.ts
- packages/kit/convex/subscriptions/horizonInternal.ts
bff090e to
3e75b14
Compare
🚥 Pre-merge checks | ✅ 2 | ❌ 3❌ Failed checks (3 warnings)
✅ Passed checks (2 passed)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
The page states it is the canonical changelog and that every shipped PR lands an entry, but the last one was 2026-07-28 while five production changes had deployed since. Entries reconstructed from each PR, dated by its merge to main, which is when deploy-kit.yml ships it: order lookup (#285), sync/verification/MCP session correctness (#292), the production Convex target guard (#314), store verification integrity (#313), and the entitlement defects the conformance suite surfaced (#316). Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Summary
expectedProductIdandenvironmentthrough the GraphQL SSOT, Apple, Google, and every framework SDK while preserving published Kotlin constructor compatibility.Preview
pr-313-kit-store-verification-ui.mp4
Production data audit
A read-only hosted production audit on 2026-08-11 found:
MetaHorizonReconcilereventsThe hosted audit found no Horizon rows requiring repair, so no hosted repair migration was run. A bounded, idempotent
backfillPurchaseStatsStoreBucketsmigration is included for self-hosted deployments that need to populate the new Amazon/Horizon per-store stats buckets; its required migration and duplicate-cleanup ordering is documented.Verification
audit:docs,audit:parity, actionlint, andgit diff --checkpassedDevice E2E
dev.hyo.martie.10bulbslicense-tester order showed the explicit test card/test-order sheet, verified through the compiled local server with HTTP 200 andisValid: true, finished successfully, added exactly one canonical Google row/order/valid count, and created no durable subscription row.expectedProductId,environment: Sandbox, andREADY_TO_CONSUME; purchase/Amazon/valid counters advanced exactly once and no durable subscription row was created. The temporary project sandbox opt-in and local environment flag were restored afterward.project.assets.json; no dependency restore was introduced for the E2E run.Follow-up validation
Live Meta credentials were unavailable, so Meta's real non-entitlement HTTP shape still needs a test-user fixture before changing the conservative 4xx behavior. Amazon valid Sandbox receipts were exercised end to end; a naturally expired/grace-period production subscription fixture was not available, so lifecycle reconciliation continues to rely on Amazon's documented
cancelDateloss-of-access semantics and bounded RVS polling.Package metadata is intentionally not bumped in this feature PR. The additive fields are annotated for future OpenIAP Spec 3.2.0, openiap-apple 3.2.0, and openiap-google 3.3.0 releases; framework packages ship through their own release workflows.
Closes #310
Closes #311
Closes #312
Summary by CodeRabbit
New Features
Bug Fixes
Documentation