Skip to content

Commit ead0fae

Browse files
committed
Updated
1 parent 2aae3f1 commit ead0fae

3 files changed

Lines changed: 21 additions & 7 deletions

File tree

specs/002-harden-checkout-tenancy/plan.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@ Gates from constitution:
4444
- Testing thresholds (80% services, 100% utils), E2E on critical paths — PLANNED
4545
- Accessibility (WCAG 2.1 AA, axe‑core) — PLANNED ENFORCEMENT
4646

47+
Note: The project constitution contains an inconsistent high-level coverage statement elsewhere (references to 90%). For implementation and CI gates this plan follows the constitution's detailed thresholds: **80% services** and **100% utilities**. If a stricter global threshold is required (e.g., 90%), update the constitution/governance documents and CI policy accordingly.
48+
4749
No violations detected at plan time. Re‑check after Phase 1 artifacts.
4850

4951
## Project Structure

specs/002-harden-checkout-tenancy/spec.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,13 +113,20 @@ As an admin, I receive consistent API responses and can export orders as CSV; sm
113113
- **FR-001**: Reject unauthenticated checkout attempts; require a valid signed-in session.
114114
- **FR-002**: Recalculate all line items, discounts, shipping, and taxes on the server; ignore client-submitted monetary values.
115115
- **FR-003**: Validate the provided payment intent/token with the payment processor prior to order creation; abort on validation failure.
116+
- **FR-003**: Validate the provided payment intent/token with the payment processor prior to order creation; abort on validation failure.
117+
- Clarification: Payment pre-validation MUST verify that the payment intent/authorization exists and that the expected amount and currency match server-side recalculated totals. The system SHOULD accept processor states such as "AUTHORIZED" or equivalent pre-authorized states for later capture; the implementation MUST document which states are merely validated vs which will be captured as part of order finalization.
118+
- Idempotency & retries: Checkout submissions MUST include an idempotency key (client-provided or server-generated) to prevent duplicate captures. The payment adapter MUST implement safe retry/backoff semantics. In case of payment provider outages, the checkout flow MUST abort without creating an order or mutating inventory; a retryable error should be surfaced to the client and reconciliation attempted by background processes when appropriate.
116119
- **FR-004**: Execute order creation, order items, inventory decrement, discount usage mark, and payment record within a single atomic transaction.
117120
- **FR-005**: Resolve the active store from the request domain/subdomain and map it to a tenant identifier; return not-found if no mapping exists. When both a custom domain and subdomain exist, redirect subdomain traffic to the custom domain as the canonical host.
121+
- **FR-005**: Resolve the active store from the request domain/subdomain and map it to a tenant identifier; return not-found if no mapping exists. When both a custom domain and subdomain exist, redirect subdomain traffic to the custom domain as the canonical host.
122+
- Clarification: For storefront GET requests, the canonical redirect SHOULD use HTTP 301 (Permanent Redirect) and the response SHOULD include a `Link: <https://{primary-domain}{path}>; rel="canonical"` header to aid SEO. For non-GET requests (e.g., form POSTs), avoid automatic redirects that change method semantics; prefer returning an informative error so clients can re-submit to the canonical host if applicable.
118123
- **FR-006**: Eliminate hardcoded tenant identifiers from storefront components and services.
119124
- **FR-007**: Provide a newsletter subscription path that validates input, prevents duplicates per email+store, records explicit consent, supports rate limiting, and writes an audit entry; activate subscriptions immediately (single opt-in) with an audit trail.
120125
- **FR-008**: Standardize API responses: success `{ data, meta?, message? }`; error `{ error: { code, message, details? } }`.
121126
- **FR-009**: Enforce tenant scoping for all tenant-owned queries via a guaranteed filter on the tenant identifier.
122127
- **FR-010**: Align data fields where arrays vs delimited strings are inconsistent; add soft-delete fields where missing; validate forward data entry accordingly.
128+
- **FR-010**: Align data fields where arrays vs delimited strings are inconsistent; add soft-delete fields where missing; validate forward data entry accordingly.
129+
- Clarification: Candidate fields for normalization include, but are not limited to: `Product.images` (string[] vs CSV), `Product.tags` (string[] vs CSV), `Variant.attributes` (JSON vs CSV), and any CSV-encoded historical fields. The schema audit (T038) MUST produce an explicit per-field inventory artifact listing current type, recommended normalized type, migration approach, and backward-compatibility notes.
123130
- **FR-011**: Establish cache tag categories for key entities (e.g., products, categories, pages) and provide invalidation on create/update/delete actions.
124131
- **FR-012**: Produce a plan to adopt component-level caching in phases, initially disabled, with documented enablement steps and guardrails.
125132
- **FR-013**: Achieve and enforce test coverage thresholds (services ≥80%, utilities 100%) with tests for fraud scenarios, tenancy isolation, newsletter flows, and error mapping.
@@ -143,6 +150,7 @@ As an admin, I receive consistent API responses and can export orders as CSV; sm
143150
- **AuditLog**: Immutable record of significant actions (checkout created, subscription added) with correlation/request IDs.
144151
- **CacheTag**: Semantic identifiers used to manage cache invalidation across related views.
145152
- **RequestContext**: Correlation/request ID and store resolution used for logging and response headers.
153+
- **RequestContext**: Correlation/request ID and store resolution used for logging and response headers. Implementation note: standardize the canonical store resolver filename to `src/lib/store/resolve-store.ts` across plan/tasks to avoid naming drift.
146154

147155
## Success Criteria *(mandatory)*
148156

specs/002-harden-checkout-tenancy/tasks.md

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -57,12 +57,16 @@ Total tasks: 42 (grouped by phase and user story)
5757
- [ ] T036 [P] Final audit: run grep for hardcoded `storeId`, run coverage, Lighthouse, and axe and store artifacts in `specs/002-harden-checkout-tenancy/artifacts/`
5858

5959
## Remediation & Constitution Tasks (critical follow-ups)
60-
- [ ] T037 Add integration tests for every modified API route under `src/app/api/**/route.ts`; ensure each modified route has a corresponding integration test in `tests/integration/` and fail pre-merge when missing (map to FR-013, constitution MUST)
61-
- [ ] T038 Schema audit: scan `prisma/schema.prisma` and codebase for CSV/string[] inconsistencies (images, tags, other arrays); create per-field migration tasks and tests under `tests/integration/migrations/`
60+
- [ ] T037 Add integration tests for every API route under `src/app/api/**/route.ts`; ensure each route (not only modified ones) has a corresponding integration test in `tests/integration/`. Add a CI check that fails pre-merge if any API route lacks an integration test. (maps to FR-013 and constitution MUST)
61+
- [ ] T038 Schema audit: scan `prisma/schema.prisma` and codebase for CSV/string[] inconsistencies (images, tags, attributes, variants, metadata arrays); create per-field migration tasks and tests under `tests/integration/migrations/` with an explicit inventory output artifact.
6262
- [ ] T039 Add k6 load test scripts for checkout and orders export and add Lighthouse CI job to feature CI pipeline; document thresholds and integrate into `.github/workflows/` (map to constitution performance requirements)
6363
- [ ] T040 Background job infra validation: confirm existing job processing infra (worker/queue); if missing, add lightweight dev stub and update `src/services/export-service.ts` to support stub in dev/test
6464
- [ ] T041 Payment pre-validation robustness: add idempotency key handling, retry/backoff policy, and tests for provider outages (update `src/services/payments/intent-validator.ts` and tests)
65-
- [ ] T042 REST audit: scan `src/app/api/**/route.ts` for REST violations (PUT/PATCH misuse, stray `success` flags) and create remediation subtasks to fix each violating endpoint
65+
- [ ] T042 REST audit: scan `src/app/api/**/route.ts` for REST violations (PUT/PATCH misuse, stray `success` flags). Produce per-endpoint remediation tasks with deadlines and CI gating to ensure fixes are applied before merge.
66+
67+
## Additional Tasks (Governance & CI)
68+
- [ ] T043 Percy + Visual Regression: Integrate Percy visual regression for critical pages and UI components (dashboard, checkout, product list). Add Percy job to feature CI and create snapshot baselines. Map to constitution visual regression requirements.
69+
- [ ] T044 CI k6 & Lighthouse gating: Add CI jobs to run k6 (load) and Lighthouse CI with defined thresholds; fail PRs or block merge if thresholds are not met for PRs touching critical paths.
6670

6771
---
6872

@@ -85,8 +89,8 @@ Total tasks: 42 (grouped by phase and user story)
8589
Path to generated tasks.md: `specs/002-harden-checkout-tenancy/tasks.md`
8690

8791
Summary:
88-
- Total tasks: 36
89-
- Tasks per story: US1:6, US2:5, US3:5, US4:4, Foundational:6, Setup:3, Final/Polish:7
92+
- Total tasks: 42
93+
- Tasks per story (approx): US1:6, US2:6, US3:5, US4:5, Foundational:6, Setup:3, Final/Polish:7
9094
- Parallel opportunities: Foundational helpers (T004–T009) and docs/tests (T033–T036)
9195
- Suggested MVP: US1 minimal slice (T010, T011, T013)
9296

@@ -155,8 +159,8 @@ This plan breaks the specification into implementable tasks with owners, concret
155159
- Schema: add `StoreDomain` model
156160
- `id`, `storeId`, `domain` (unique), `isPrimary` (canonical), timestamps
157161
- Files: `prisma/schema.prisma` (model + `@@unique([domain])`), migration; seed example
158-
- Files: `src/lib/store-resolver.ts` (new): parse host, resolve `storeId` by domain OR `slug.subdomain`
159-
- Proxy: add canonical redirect: if request for subdomain and primary custom domain exists → 308 redirect
162+
- Files: `src/lib/store/resolve-store.ts` (new): parse host, resolve `storeId` by domain OR `slug.subdomain`
163+
- Proxy: add canonical redirect: if request for subdomain and primary custom domain exists → 301 Permanent Redirect; include a `Link: <https://{primary-domain}{path}>; rel="canonical"` header for SEO
160164
- Tests: `tests/unit/store-resolver.test.ts`, `tests/integration/canonical-redirect.test.ts`
161165

162166
- T2.2 Remove hardcoded store IDs and enforce tenant scoping (FR-006, FR-009)

0 commit comments

Comments
 (0)