{"slug": "a-plan-of-plans-for-a-production-grade-end-to-end-e-commerce-website", "title": "A plan-of-plans for a production-grade end-to-end e-commerce website.", "summary": "A developer outlined a plan-of-plans for a production-grade e-commerce website using Astro 7 on Cloudflare Workers. The site will sell a small catalog of physical goods in India, with Razorpay payments, guest checkout, and manual fulfillment. The plan includes prerendered storefront pages, dynamic server-rendered routes for cart and checkout, and strict Lighthouse performance budgets.", "body_md": "**Status**: Approved in brainstorming session 2026-07-07\n**Owner**: vikas (human) — executes by dispatching AI per mini-plan using superpowers\n**Repo**: `pink-pulsar`\n\n— Astro 7 + `@astrojs/cloudflare`\n\nadapter on Cloudflare Workers\n**Purpose**: A plan-of-plans for a production-grade end-to-end e-commerce website. Each mini-plan is one PR-sized, AI-implementable, fully-tested increment. The plan-of-plans itself is for human use only — the AI does not execute it; it executes one mini-plan at a time on demand.\n\n| Dimension | Decision |\n|---|---|\n| Products | Physical goods, small catalog (~5 products) |\n| Market | India (INR, English only for v1) |\n| Goal | Full ownership, no platform fees |\n| Payments | Razorpay (UPI, cards, netbanking, COD) |\n| Customer auth | Guest checkout only — no accounts in v1 |\n| Fulfillment | Manual packing + flat-rate shipping |\n| Notifications | Email now; WhatsApp deferred to `future/` |\n| Order states | Minimal: `placed → paid → shipped → delivered` (+ `cancelled` ); extensible for provider statuses later |\n| Admin | Basic admin in this repo now; full admin panel deferred to `future/` |\n| Compliance | Legal pages now (Privacy, Terms, Returns, Shipping, Contact/About). GST tax handling, GST invoices, DPDP consent deferred to `future/` . |\n| Marketing | Discounts/coupons now. Abandoned cart deferred to `future/` . Analytics events & funnel now. |\n\n- Storefront pages (home, catalog, product detail, legal)\n**prerendered at build (SSG)** via Astro. Pure HTML + minimal islands. - Only dynamic server-rendered routes:\n`/cart`\n\n,`/checkout`\n\n,`/checkout/success`\n\n,`/admin/orders/*`\n\n,`/orders/[token]`\n\n. - Lighthouse CI in GH Actions gates every PR:\n**block merge if any category < 90, warn if < 100**. - Zero render-blocking JS/CSS. Astro's minimal island runtime shipped only where interactivity is genuinely needed.\n- Long-cache headers for static assets; short cache for HTML.\n- MP-13 closes the loop: image variants, cache headers, critical-CSS inlining, font subsetting, RUM budget assertions.\n\n- Full\n`<head>`\n\nmeta (title, description, canonical, robots, OpenGraph, Twitter cards) via a base component in MP-0a. - JSON-LD:\n`Product`\n\n,`Offer`\n\n,`BreadcrumbList`\n\n,`Organization`\n\n,`WebSite`\n\n. `@astrojs/sitemap`\n\nintegration for`sitemap.xml`\n\nindex (MP-12).- Static\n`public/robots.txt`\n\n. - OG-image route per product (MP-12).\n`hreflang`\n\nstub set up now (IN only for v1) — extends cleanly when multi-language is added later.- Custom 404/500 pages (MP-9).\n\n- Cloudflare automatic DDoS + managed WAF rules cover volumetric threats (zero setup).\n- Workers Rate Limiting binding wired in MP-0d; used per-feature.\n- Security headers (CSP, HSTS, X-Frame-Options, Referrer-Policy, Permissions-Policy) in MP-0d middleware.\n- Cloudflare Turnstile on admin login (MP-7).\n- Astro Actions built-in CSRF protection — verified in MP-0a, used by every Action MP.\n`astro:schema`\n\n(the`astro/zod`\n\nmodule) for input validation on every Action — native, no standalone Zod.- Razorpay signature verification on every webhook (MP-5).\n- Hashed shared secret in KV + httpOnly secure cookie for admin auth (MP-7).\n- HMAC-signed tokens via Web Crypto for guest order-status links (MP-8).\n- Wrangler secret store for all secrets;\n`.dev.vars`\n\nfor local (MP-0c). - MP-14 (security audit) tunes thresholds, tightens CSP, reviews WAF rules, audits dependencies, walks through threats with real traffic data.\n\n**Workers Observability**(already enabled in`wrangler.jsonc`\n\n) for server-side error tracking.**Workers Analytics Engine** for product analytics events via a first-party`/rum`\n\nbeacon endpoint (~50 lines, MP-0d).- Zero client-side analytics SDK — preserves Lighthouse 100.\n- Sentry / PostHog / session replay deferred to\n`future/`\n\nas lazy-load mini-plans.\n\nThree-tier server delivery, **all native Astro, zero extra routers**:\n\n**Astro prerendered (SSG)**— storefront: home, catalog list, product detail, legal pages, 404/500, sitemap, robots. Pure HTML + minimal islands. This is the Lighthouse 100 path.**Astro Actions**(`src/actions/`\n\n) — type-safe RPC for every app-internal mutation:`cart/add`\n\n,`cart/update`\n\n,`cart/remove`\n\n,`cart/clear`\n\n`checkout/createOrder`\n\n,`checkout/capture`\n\n`admin/login`\n\n,`admin/updateOrderStatus`\n\n,`admin/assignTracking`\n\n`orders/getStatus`\n\n(for the guest order-status page)- End-to-end type safety from UI → service via\n`astro:schema`\n\nfor input/output schemas.\n\n**Astro API routes**—** exactly one**:`/api/webhooks/razorpay.ts`\n\n(raw external webhook needing signature verification + custom body parsing). That's the API-route exception; everything else is an Action.**Dynamic server-rendered routes**(opted out of prerender via`export const prerender = false`\n\n):`/cart`\n\n,`/checkout`\n\n,`/checkout/success`\n\n,`/admin/orders/*`\n\n,`/orders/[token]`\n\n. Render via`loader`\n\n+ call Actions from client islands.\n\n**Hybrid output**: `output: 'static'`\n\n(Astro 7 default) with `prerender = false`\n\nonly on the dynamic routes above. Storefront build is SSG; dynamic routes are on-demand SSR via the Cloudflare Worker; Actions run on the Worker.\n\nAstro uses file-based routing in `src/pages/`\n\n, native Actions in `src/actions/`\n\n, native middleware in `src/middleware.ts`\n\n, and has existing `src/components/`\n\n, `src/layouts/`\n\n, `src/assets/`\n\n. We extend these — not replace them. Cross-cutting code lives in `src/lib/`\n\n; feature business logic (non-routing) lives in `src/features/`\n\n.\n\n```\nsrc/\n  pages/                         # Astro file-based routing — ALL pages live here (existing)\n    index.astro                  #   home (prerendered)\n    products/                    #   catalog (prerendered)\n      index.astro                #     product list\n      [slug].astro               #     product detail\n    cart.astro                   #   cart page (dynamic)\n    checkout/                    #   checkout flow (dynamic)\n      index.astro                #     address + shipping step\n      review.astro               #     review + pay step\n      success.astro              #     order confirmed\n    orders/                      #   guest order status (dynamic)\n      [token].astro\n    admin/                       #   basic admin (dynamic, auth-gated)\n      login.astro\n      orders/\n        index.astro\n        [id].astro\n      coupons/                   #   MP-10 discounts admin\n        index.astro\n    api/                         #   the ONE api route folder\n      webhooks/\n        razorpay.ts\n    privacy.astro                #   legal pages (prerendered)\n    terms.astro\n    returns.astro\n    shipping.astro\n    contact.astro\n    about.astro\n    health.astro                 #   health check\n    rum.ts                       #   analytics beacon endpoint\n    404.astro\n    500.astro\n  actions/                       # Astro Actions — native location (RPC entry points)\n    cart.ts                      #   thin: parse → service → return\n    checkout.ts\n    admin.ts\n    orders.ts\n  components/                    # Astro components — existing, extended\n    ui/                          #   Astro-native shadcn base components (Button, Input, Card, ...)\n    cart/                        #   cart-specific components (CartSlideover, CartBadge)\n    checkout/                    #   checkout-specific components\n    admin/                       #   admin-specific components\n    seo/                         #   SEO components (MetaHead, JsonLd)\n  layouts/                       # Astro layouts — existing\n    Layout.astro                 #   base layout with <head>, tokens, font optimization\n  assets/                        # Astro assets — existing (astro:assets)\n  styles/                        # Global styles, Tailwind v4 entry, design tokens (CSS variables)\n  content/                       # Astro content collections (if legal pages migrate to markdown later)\n  middleware.ts                  # Native Astro middleware — security headers, request-id, logger, admin auth guard\n  env.d.ts                       # Astro env type definitions\n  lib/                           # Cross-cutting code — NOT Astro routing\n    core/                        #   framework-agnostic, pure-TS, fully unit-tested\n      env.ts                     #     typed binding accessor (D1, R2, KV, Analytics Engine, secrets)\n      logger.ts                  #     structured logging + request id (Workers Logs adapter)\n      errors.ts                  #     error taxonomy (UserError, ServerError, PaymentError, ...)\n      auth.ts                    #     HMAC token sign/verify, admin session helpers\n      rate-limit.ts              #     Workers Rate Limiting binding helpers\n    db/                          #   Drizzle ORM\n      schema/                    #     schema definitions (split by feature: catalog.ts, orders.ts, coupons.ts)\n      migrations/                #     Drizzle migrations\n      client.ts                  #     Drizzle client factory\n    bindings/                    #   provider adapters (concrete impls) + interface types\n      payment/                   #     types.ts (PaymentProvider) + razorpay.ts (RazorpayAdapter)\n      email/                     #     types.ts (EmailSender) + smtp.ts\n      images/                    #     types.ts (ImageRepository) + r2.ts\n      cart/                      #     types.ts (CartRepository) + kv.ts\n      analytics/                 #     types.ts (AnalyticsSink) + analytics-engine.ts\n      logger/                    #     types.ts (Logger) + workers-logs.ts\n    app/                         #   composition root — the ONLY place concrete adapters are imported\n      prod.ts                    #     wires real adapters → services\n      test.ts                    #     wires fakes → services\n  features/                      # Feature slices — business logic only (NO routing, NO .astro pages)\n    catalog/                     #   MP-1, MP-2\n      service.ts  repository.ts  types.ts  tests/\n    cart/                        #   MP-3, MP-4\n      service.ts  repository.ts  types.ts  tests/\n    checkout/                    #   MP-5, MP-6a, MP-6b\n      service.ts  repository.ts  types.ts  tests/\n    orders/                      #   MP-7, MP-8\n      service.ts  repository.ts  types.ts  tests/\n    admin/                       #   MP-7 admin business logic\n      service.ts  types.ts  tests/\n    seo/                         #   MP-12 (JSON-LD helpers, OG-image gen helpers)\n      jsonld.ts  og-image.ts  tests/\n    legal/                       #   MP-9 (legal page content/metadata)\n      content.ts  tests/\npublic/\n  robots.txt                     # static file (MP-12)\n```\n\n**Key differences from a non-Astro project:**\n\n- Pages live in\n`src/pages/`\n\n(file-based routing) — NOT inside`src/features/*/pages/`\n\n. Pages are thin: they call services and render. - Components live in\n`src/components/`\n\n(Astro convention) organized by feature subfolder — NOT inside`src/features/*/components/`\n\n. - Actions live in\n`src/actions/`\n\n(native Astro location). - Middleware lives in\n`src/middleware.ts`\n\n(native Astro middleware) — replaces the custom`withMiddleware()`\n\nhelper. - Feature slices in\n`src/features/`\n\ncontain ONLY non-routing business logic:`service.ts`\n\n,`repository.ts`\n\n,`types.ts`\n\n,`tests/`\n\n.\n\n| Concern | Interface | Default impl | Swap target |\n|---|---|---|---|\n| Database | `*Repository` per feature |\nDrizzle + D1 | Postgres, Turso, Mongo — replace that slice's repository only |\n| Payments | `PaymentProvider` |\n`RazorpayAdapter` |\nStripe, PayPal — new file in `bindings/` , wire in `app/prod.ts` |\n`EmailSender` |\n`SmtpAdapter` (Cloudflare Email Service) |\nSES, Postmark, Resend — swap adapter only | |\n| Object storage | `ImageRepository` |\n`R2Adapter` |\nS3, Cloudinary — swap adapter only |\n| Cart store | `CartRepository` |\n`KVAdapter` |\nD1, Redis (Upstash) — swap adapter only |\n| Analytics | `AnalyticsSink` |\n`AnalyticsEngineAdapter` |\nPostHog, Rudderstack — swap adapter only |\n| Logger | `Logger` |\n`WorkersLogsAdapter` |\nSentry, Datadog — swap adapter only |\n\n**Composition root**: `src/lib/app/prod.ts`\n\nwires real adapters; `src/lib/app/test.ts`\n\nwires fakes. Services take interfaces as constructor args — never `import`\n\nan adapter directly. **Tests pass fakes, prod passes the real adapter.** To swap payments: write `StripeAdapter.ts`\n\nin `src/lib/bindings/payment/`\n\n, change one line in `src/lib/app/prod.ts`\n\n, done. Zero churn in any feature slice.\n\nServices take adapters as constructor args:\n\n```\n// src/lib/bindings/payment/types.ts\nexport interface PaymentProvider {\n  createOrder(opts: CreateOrderOpts): Promise<{ orderId: string }>;\n  verifySignature(opts: VerifyOpts): Promise<boolean>;\n  refund(orderId: string, amount: number): Promise<RefundResult>;\n}\n\n// src/features/checkout/service.ts\nexport class CheckoutService {\n  constructor(private deps: { payment: PaymentProvider; orders: OrderRepository; email: EmailSender }) {}\n  async createOrder(input: CreateOrderInput) { /* uses this.deps.payment */ }\n}\n\n// src/lib/app/prod.ts — the only place that knows about real adapters\nexport const checkout = new CheckoutService({\n  payment: new RazorpayAdapter(env.RAZORPAY_KEY, env.RAZORPAY_SECRET),\n  orders: new DrizzleOrderRepository(env.DB),\n  email: new SmtpAdapter(env.SMTP_URL),\n});\n\n// src/actions/checkout.ts — thin\nimport { checkout } from '~/lib/app/prod';\nexport const createOrder = defineAction({ handler: async (input) => checkout.createOrder(input) });\n```\n\n**Why no DI framework**: ~6 services and ~8 adapters — a single `app/prod.ts`\n\nfile of ~30 lines wires the whole graph. A framework would add magic + bundle weight for zero benefit at this scale.\n\n`src/actions/*`\n\n→ may import`src/features/*/service`\n\n+`src/lib/core/*`\n\nonly`src/features/*/service.ts`\n\n→ may import`src/features/*/repository`\n\n(interfaces) +`src/lib/bindings/*/types`\n\n(interfaces only, never concrete adapters) +`src/lib/db/`\n\nschemas +`src/lib/core/*`\n\n`src/lib/bindings/*`\n\n+`src/lib/db/*`\n\n→ only place that touches Cloudflare bindings / vendor SDKs / Drizzle- No\n`src/features/A`\n\nmay import`src/features/B`\n\ninternals `src/lib/app/prod.ts`\n\n+`src/lib/app/test.ts`\n\nare the ONLY files allowed to import concrete adapters`src/pages/*`\n\n→ may import`src/features/*/service`\n\n+`src/components/*`\n\n+`src/layouts/*`\n\nonly (pages are thin)\n\nEnabled in MP-0a. `strict: true`\n\n, `noUncheckedIndexedAccess: true`\n\n, `exactOptionalPropertyTypes: true`\n\n. No `any`\n\nwithout explicit eslint-disable comment explaining why.\n\n**Before implementing any mini-plan, the AI must web-search the relevant Astro and Cloudflare docs to confirm whether a native integration exists before reaching for any external dependency.**\n\nDecisions locked under this principle:\n\n| Concern | Native choice | Notes |\n|---|---|---|\n| API/RPC | Astro Actions (`src/actions/` ) |\nNative |\n| Webhook route | Astro API route (`src/pages/api/` ) |\nOne exception for Razorpay |\n| Middleware | Astro native middleware (`src/middleware.ts` ) |\nNative — replaces custom withMiddleware() |\n| Input validation | `astro:schema` (`astro/zod` module) |\nNative, not standalone Zod |\n| Fonts | Astro experimental native font optimization | MP-0a |\n| Images (build-time) | Astro `<Image>` + `astro:assets` |\nMP-1, MP-2, MP-14 |\n| Images (post-build/admin upload) | R2 + Cloudflare Image Resizing | Adapter pattern |\n| Sitemap | `@astrojs/sitemap` integration |\nMP-12 |\n| Robots.txt | Static `public/robots.txt` file |\nMP-12 |\n| Testing | `astro test` (uses Vitest under the hood) |\nNative |\n| Content (if blog ever added) | `astro:content` collections + `@astrojs/mdx` |\nFuture |\n| Rate limiting | Workers Rate Limiting binding | Platform-native |\n| Analytics | Workers Analytics Engine | Platform-native |\n| Error tracking | Workers Observability | Platform-native |\n| Cloudflare Email Service | Platform-native |\n\n**External deps kept (no native alternative exists)**:\n\n- Tailwind v4 — CSS tool, zero JS shipped, explicitly requested + needed for shadcn token system\n- Drizzle ORM — thinnest D1-compatible ORM, compile-time queries, no runtime weight\n- Astro-native shadcn port — UI components built on the shadcn CSS-variable token system\n\n**Tailwind v4** for styling — CSS-native config, zero runtime JS.**Astro-native shadcn port**— port shadcn components as native Astro components using the same CSS-variable token system (the shadcn token system is CSS-only, framework-agnostic). Same look/feel as shadcn proper.**React islands only where genuinely interactive**— cart slide-over (MP-3), Razorpay checkout flow (MP-6b), admin order management (MP-7). Everything else is pure Astro HTML — preserves Lighthouse 100.**Design tokens** defined once in MP-0a (CSS variables: colors, spacing, typography, radii, shadows) and consumed by both Astro components and any React islands.\n\n| Binding | Purpose | Wired in |\n|---|---|---|\nD1 (`DB` ) |\nProducts, variants, product images metadata, orders, order items, discounts, coupons | MP-0b (binding), MP-1 (first tables), MP-6a (orders), MP-10 (discounts) |\nKV (`CART` ) |\nCart state, admin session, rate-limit counters | MP-0b (binding), MP-3 (cart), MP-7 (admin session) |\nR2 (`IMAGES` ) |\nProduct images (admin-uploaded), generated invoices | MP-0b (binding), MP-1 (read), MP-7 (admin upload if added) |\nAnalytics Engine (`ANALYTICS` ) |\nProduct events (page_view → purchase funnel) | MP-0d (binding + beacon), MP-11 (instrumentation) |\n\n**Drizzle ORM** for D1 — thin, compile-time, D1-compatible. Schema in `src/lib/db/schema/`\n\n(split by feature). Migrations in `src/lib/db/migrations/`\n\n. Client factory in `src/lib/db/client.ts`\n\n. Repository pattern: each feature defines its `*Repository`\n\ninterface in `src/features/*/repository.ts`\n\nand a Drizzle implementation; tests use an in-memory fake.\n\nEach mini-plan is:\n\n- One PR-sized chunk — small enough for thorough human code review\n- One capability end-to-end (where reasonable)\n- Fully tested (Vitest unit + integration;\n`astro test`\n\nnative runner) - Lighthouse CI green (block < 90, warn < 100)\n- Preview deploy verified on Cloudflare before merge\n- Implemented by AI on demand using superpowers; the plan-of-plans is for human use only\n\nMini-plans are grouped into folders by sub-system so you navigate one area at a time.\n\n- tsconfig paths, strict mode,\n`noUncheckedIndexedAccess`\n\n,`exactOptionalPropertyTypes`\n\n- Tailwind v4 setup (CSS-native config) in\n`src/styles/`\n\n- Astro experimental native font optimization\n- Astro-native shadcn base components in\n`src/components/ui/`\n\n(Button, Input, Card, etc.) + shared CSS-variable design tokens - Base SEO\n`<head>`\n\ncomponent in`src/components/seo/MetaHead.astro`\n\n(title, description, canonical, OG, Twitter cards) - Base responsive image component scaffold (Astro\n`<Image>`\n\n+`astro:assets`\n\n) - ESLint with\n`no-restricted-imports`\n\nrules from §3.5; Prettier - Vitest via\n`astro test`\n\n`src/layouts/Layout.astro`\n\nwith head + token-driven styles + font optimization`.dev.vars`\n\nskeleton for local secrets**Tests**: repo boots, layout renders, lint passes, base components render.** Pages touched**:`src/layouts/Layout.astro`\n\nonly.\n\n- D1 binding in\n`wrangler.jsonc`\n\n+ Drizzle migration infra in`src/lib/db/`\n\n(no tables yet) - R2 binding +\n`ImageRepository`\n\ninterface in`src/lib/bindings/images/`\n\n- KV binding +\n`CartRepository`\n\n+`SessionRepository`\n\ninterfaces in`src/lib/bindings/cart/`\n\n- Analytics Engine binding +\n`AnalyticsSink`\n\ninterface in`src/lib/bindings/analytics/`\n\n`src/lib/bindings/`\n\nfolder layout with interface types only (no concrete impls yet beyond stubs)**Tests**: binding stubs reachable from a stub route; interfaces typecheck against fakes.** Pages touched**: none.\n\n- GH Actions workflow: lint + typecheck +\n`astro test`\n\n+**Lighthouse CI**(block < 90, warn < 100) on every PR **Wrangler preview deploy per PR**(preview URL posted as PR comment)- Prod deploy on merge to\n`main`\n\n- Wrangler secret store wiring for prod secrets\n- PR template (checklist: tests added, Lighthouse green, preview verified, doc-search-for-native-integrations done)\n- Dependabot enabled (security updates)\n**Tests**: pipeline green on a stub route; preview URL reachable.** Pages touched**: none.\n\n- Typed env/binding accessor in\n`src/lib/core/env.ts`\n\n- Structured logger + request id in\n`src/lib/core/logger.ts`\n\n(Workers Logs adapter) - Error taxonomy in\n`src/lib/core/errors.ts`\n\n(UserError, ServerError, PaymentError, etc.) **Native Astro middleware** in`src/middleware.ts`\n\n— security headers (CSP, HSTS, X-Frame-Options, Referrer-Policy, Permissions-Policy), request-id injection, logger setup on`locals`\n\n- HMAC token sign/verify helpers in\n`src/lib/core/auth.ts`\n\n(used by MP-4 checkout links, MP-8 order-status links) - Workers Rate Limiting binding wired; per-feature rate-limit helpers in\n`src/lib/core/rate-limit.ts`\n\n`/health`\n\nroute`/rum`\n\nbeacon endpoint (~50 lines) → Analytics Engine`src/lib/db/`\n\nfolder layout with empty migration scaffolding;`src/features/*/`\n\nfolders with empty`service.ts`\n\n+`repository.ts`\n\ninterface stubs**Tests**: logger/env/error unit tests;`/health`\n\nand`/rum`\n\nintegration tests; middleware security-headers assertion test.**Pages touched**:`/health`\n\n,`/rum`\n\n(endpoints only).\n\n- Drizzle schema for\n`products`\n\n,`variants`\n\n,`product_images`\n\nin`src/lib/db/schema/catalog.ts`\n\n- First migration\n`ProductRepository`\n\ninterface in`src/features/catalog/repository.ts`\n\n+ Drizzle impl- Seed 5 products (with variants + images) via a seed script\n- Astro\n`<Image>`\n\n+`astro:assets`\n\nfor build-time images **Tests**: repository CRUD — unit tests against in-memory fake; integration tests against local D1 (Miniflare).** Pages touched**: none.\n\n- Home page at\n`src/pages/index.astro`\n\n, product list at`src/pages/products/index.astro`\n\n, product detail at`src/pages/products/[slug].astro`\n\n(all prerendered at build) `catalog`\n\nservice (`getProduct`\n\n,`listProducts`\n\n) in`src/features/catalog/service.ts`\n\n- SEO meta + JSON-LD (\n`Product`\n\n,`Offer`\n\n,`BreadcrumbList`\n\n) on product pages via`src/components/seo/`\n\n- Responsive image rendering via Astro\n`<Image>`\n\n+ R2 for admin-uploaded images - Astro-native shadcn components from\n`src/components/ui/`\n\nfor layout **Tests**: pages render with seeded data; Lighthouse passes (≥100 perf target).** Pages touched**:`/`\n\n,`/products`\n\n,`/products/[slug]`\n\n.\n\n`CartRepository`\n\nKV default impl in`src/lib/bindings/cart/`\n\n- Cart service (\n`addToCart`\n\n,`updateLine`\n\n,`removeLine`\n\n,`clear`\n\n,`totals`\n\n) in`src/features/cart/service.ts`\n\n- Cart Actions (\n`cart/add`\n\n,`cart/update`\n\n,`cart/remove`\n\n,`cart/clear`\n\n) in`src/actions/cart.ts`\n\nwith`astro:schema`\n\ninput validation - Cart slide-over UI in\n`src/components/cart/`\n\n(Astro-native shadcn components + React island for interactivity) - Cart badge in header\n**Tests**: cart service + KV impl; UI smoke test.** Pages touched**: cart slide-over (in`Layout`\n\n),`/cart`\n\n.\n\n`CheckoutDraft`\n\ntyped shape (items, address, shipping method, totals) in`src/features/checkout/types.ts`\n\n- Address form + flat-rate shipping method selection page at\n`src/pages/checkout/index.astro`\n\n- Draft persisted to KV with short TTL\n- HMAC-signed checkout link for guest (so customer can resume if they navigate away) — uses\n`src/lib/core/auth.ts`\n\n`astro:schema`\n\nvalidation on all form inputs in`src/actions/checkout.ts`\n\n**Tests**: draft lifecycle (create/read/update/expire), signed-link validation.** Pages touched**:`/checkout`\n\n(address + shipping step).\n\n`PaymentProvider`\n\ninterface in`src/lib/bindings/payment/types.ts`\n\n`RazorpayAdapter`\n\nin`src/lib/bindings/payment/razorpay.ts`\n\n- Order create + capture flow against Razorpay test mode\n`src/pages/api/webhooks/razorpay.ts`\n\n— raw body parse, signature verification, idempotency- Secrets via Wrangler secret store;\n`.dev.vars`\n\nfor local **Tests**: adapter against Razorpay test mode; webhook signature verification test; idempotency test.** Pages touched**:`/api/webhooks/razorpay`\n\n(one API route).\n\n`orders`\n\n+`order_items`\n\nDrizzle schema in`src/lib/db/schema/orders.ts`\n\n+ migration`OrderRepository`\n\ninterface + Drizzle impl in`src/features/orders/`\n\n`checkout`\n\nservice`createOrder`\n\n(creates order in`placed`\n\nstate) +`capture`\n\n(transitions to`paid`\n\non verified webhook)- Order state machine:\n`placed → paid → shipped → delivered`\n\n(+`cancelled`\n\n) **Tests**: order state transitions; repository CRUD; end-to-end capture against fake payment provider.** Pages touched**: none (server-only).\n\n- Checkout review page (\n`src/pages/checkout/review.astro`\n\n) — review items + address + shipping + totals - Razorpay Checkout (hosted redirect) for v1; Razorpay Embedded can be a future swap if lower-friction UX is wanted\n- Success page (\n`src/pages/checkout/success.astro`\n\n) - Email-on-paid:\n`EmailSender`\n\ninterface +`SmtpAdapter`\n\nin`src/lib/bindings/email/`\n\n(Cloudflare Email Service); order confirmation email with order details **Tests**: end-to-end checkout flow against Razorpay test; order state assertions; email dispatch assertion.** Pages touched**:`/checkout/review`\n\n,`/checkout/success`\n\n.\n\n- Hashed shared secret in KV + http-only secure cookie session\n- Cloudflare Turnstile on login form (bot mitigation)\n- Rate-limited login via Workers Rate Limiting binding (helpers from\n`src/lib/core/rate-limit.ts`\n\n) `/admin/orders`\n\nlist page (filterable by status) at`src/pages/admin/orders/index.astro`\n\n`/admin/orders/[id]`\n\ndetail page at`src/pages/admin/orders/[id].astro`\n\n- Status change Actions in\n`src/actions/admin.ts`\n\n(`admin/updateOrderStatus`\n\n,`admin/assignTracking`\n\n) with`astro:schema`\n\n- Manual \"tracking id\" text field (free text, surfaces on customer order-status page)\n- Email on every status change (via\n`EmailSender`\n\n) - Admin business logic in\n`src/features/admin/service.ts`\n\n**Tests**: admin auth (success, failure, rate-limit); status transitions; email dispatch on each transition.** Pages touched**:`/admin/login`\n\n,`/admin/orders`\n\n,`/admin/orders/[id]`\n\n.\n\n`/orders/[token]`\n\nroute at`src/pages/orders/[token].astro`\n\nwhere token is HMAC-signed (Web Crypto) containing order id + expiry- Read-only status display + tracking id (if assigned) + items\n- Email-on-status-change already sends the signed link (wired in MP-7)\n**Tests**: signed-link validation (valid token, expired token, tampered token); rendering.** Pages touched**:`/orders/[token]`\n\n.\n\n- Privacy Policy page at\n`src/pages/privacy.astro`\n\n- Terms of Service page at\n`src/pages/terms.astro`\n\n- Returns policy page at\n`src/pages/returns.astro`\n\n- Shipping policy page at\n`src/pages/shipping.astro`\n\n- Contact / About page at\n`src/pages/contact.astro`\n\nand`src/pages/about.astro`\n\n- Custom 404 page at\n`src/pages/404.astro`\n\n- Custom 500 page at\n`src/pages/500.astro`\n\n- All prerendered; all linked in footer; SEO meta on each\n- Content as plain Astro pages for v1 (simplest); can migrate to\n`astro:content`\n\ncollection later if markdown editing is preferred - Page content/metadata helpers in\n`src/features/legal/content.ts`\n\n**Tests**: pages render; footer links resolve; 404/500 routes return correct status codes.** Pages touched**:`/privacy`\n\n,`/terms`\n\n,`/returns`\n\n,`/shipping`\n\n,`/contact`\n\n,`/about`\n\n,`/404`\n\n,`/500`\n\n.\n\n`coupons`\n\n+`coupon_redemptions`\n\nDrizzle schema in`src/lib/db/schema/coupons.ts`\n\n+ migration- Coupon types: % off, flat off, free shipping; constraints: min-order, expires, single-use, per-customer-cap\n`DiscountService`\n\nin`src/features/checkout/service.ts`\n\n(or a dedicated`src/features/discounts/`\n\n) applies at checkout (line or order total)- Admin Actions in\n`src/actions/admin.ts`\n\nto create/list/disable coupons - Coupon input on checkout review page\n**Tests**: coupon application logic (all types + constraints); redemption tracking; admin Actions.** Pages touched**: checkout review (add coupon input),`/admin/coupons`\n\n.\n\n- Define GA4-style e-commerce event taxonomy:\n`page_view`\n\n,`view_item`\n\n,`add_to_cart`\n\n,`begin_checkout`\n\n,`add_shipping_info`\n\n,`add_payment_info`\n\n,`purchase`\n\n- Instrument storefront pages + cart Actions + checkout flow\n- Events sent to\n`/rum`\n\nbeacon → Analytics Engine (wired in MP-0d) via`src/lib/bindings/analytics/`\n\n- Maps to GA4/Meta Pixel standard so you can later add ads without re-instrumenting\n**Tests**: event emission assertions per funnel step; Analytics Engine binding receives expected events.** Pages touched**: instrumentation on existing pages (no new pages).\n\n`@astrojs/sitemap`\n\nintegration for`sitemap.xml`\n\nindex- Static\n`public/robots.txt`\n\n- OG-image route per product at\n`src/pages/og/[slug].png.ts`\n\n(generated via`satori`\n\n+`sharp`\n\n; helpers in`src/features/seo/og-image.ts`\n\n) `hreflang`\n\nstub (IN only for v1) — extends cleanly for multi-language later- Full JSON-LD:\n`Organization`\n\n,`WebSite`\n\nin`src/features/seo/jsonld.ts`\n\n(in addition to per-product JSON-LD from MP-2) - Canonical URL audit\n- Meta-tag unit tests (every prerendered page has title + description + canonical + OG)\n**Tests**: sitemap shape; robots.txt content; JSON-LD validates against schema.org; OG-image route returns image.** Pages touched**:`/sitemap-index.xml`\n\n,`/og/[slug].png`\n\n(endpoints only).\n\n- Image variants via R2 + Cloudflare Image Resizing for admin-uploaded images (via\n`src/lib/bindings/images/`\n\n) - Long-cache headers for static assets (R2 + asset binding)\n- Critical-CSS inlining\n- Font subsetting (via Astro native font optimization from MP-0a)\n- Lighthouse CI thresholds tightened (warn < 100 enforced)\n- RUM budget assertions (real-user metrics from\n`/rum`\n\nbeacon) **Tests**: Lighthouse ≥100 perf on key routes (home, product list, product detail); budget assertions.** Pages touched**: instrumentation on existing pages (no new pages).\n\n- WAF rule review with human (in Cloudflare dashboard)\n- CSP tightening in\n`src/middleware.ts`\n\nbased on actual third-party scripts used - Rate-limit threshold tuning in\n`src/lib/core/rate-limit.ts`\n\nwith real traffic data - Dependency audit (Dependabot + manual review)\n- Threat-model walkthrough with human\n- Pen-test-style review of: admin auth, Razorpay webhook, signed order-status links, all Action input validation\n**Tests**: security regression test suite (auth bypass attempts, signature forgery, CSRF, XSS attempts).** Pages touched**: none (audit + config).\n\nListed here so we know they exist. Each will get its own mini-plan when prioritized.\n\n- Full admin panel (own area or repo)\n- WhatsApp notifications\n- Shiprocket integration / pincode serviceability / auto-shipment creation\n- Multi-currency / multi-language (i18n)\n- Reviews / ratings\n- Returns / RMA / formal refund flow (deferred — for v1, admin can mark an order as cancelled and issue a manual refund/invoice outside the app)\n- Wishlist (needs accounts to be useful)\n- Search (overkill for 5 products)\n- Recommendations / related products\n- Out-of-stock email notifications\n- Newsletter / marketing capture\n- GST tax handling (rate matrix, HSN codes, intra-state/inter-state split)\n- GST-compliant tax invoices (serial-numbered, downloadable)\n- DPDP Act consent capture at checkout\n- Abandoned cart recovery (deferred — needs UX decision on email capture point)\n- Session replay (rrweb — incompatible with Lighthouse 100)\n- Sentry / PostHog / third-party analytics SDKs (lazy-load post-LCP if added)\n- A/B test platform\n- Loyalty program\n\n- The plan-of-plans is for\n**human use only**. The AI does not execute it. - The human dispatches the AI to implement one mini-plan at a time using superpowers.\n- Each mini-plan becomes one PR (or a small number of small PRs if the AI splits further during implementation).\n- After every mini-plan, the human does code review before the next MP is dispatched.\n- Every mini-plan ends with: tests green + Lighthouse CI green + preview deploy verified + human review passed.\n- Before implementing any MP, the AI web-searches Astro + Cloudflare docs to confirm native integrations exist before reaching for external deps (§4).\n\n```\n1.  Human picks the next MP from the plan-of-plans\n2.  (Optional) brainstorming skill — if the MP has open design decisions not settled in this spec\n3.  Write mini-plan design doc → docs/superpowers/specs/YYYY-MM-DD-MP-XX-<topic>-design.md\n4.  Human reviews the mini-plan spec → approve / request changes\n5.  writing-plans skill → detailed implementation plan with TDD tasks + verification commands\n    saved to docs/superpowers/plans/YYYY-MM-DD-MP-XX-<topic>-plan.md\n6.  Human reviews the implementation plan\n7.  Execute the plan — either executing-plans (separate session, review checkpoints)\n    or subagent-driven-development (current session, dispatch subagents per task)\n8.  During execution:\n    - test-driven-development — write test first, then impl, per task\n    - systematic-debugging — if a test fails or behavior is unexpected\n    - verification-before-completion — run verification commands before claiming done\n9.  requesting-code-review skill — self-review against requirements\n10. Human does code review (the gate)\n11. receiving-code-review skill — if human gives feedback, AI processes it rigorously\n12. finishing-a-development-branch — decide merge / PR / cleanup\n13. Next MP — back to step 1\n```\n\nIf during any MP's implementation the AI discovers a change that crosses MP boundaries — interface changes, scope changes, ordering changes, or promoting/demoting items between §7 and §8 — the AI MUST:\n\n**Stop and flag**— never silently absorb a cross-MP change. Pause implementation.** Write an Impact Note**in the current MP's plan doc covering:- What was discovered\n- Which MPs are affected and how\n- Severity:\n`trivial`\n\n/`contained`\n\n/`cross-MP`\n\n/`spec-level`\n\n**Hand the decision to the human**, who chooses one of:**(a) Absorb into current MP**— change is small and contained to current MP. Just update the current MP's design doc + implementation plan; no plan-of-plans change.**(b) Update plan-of-plans spec**— change affects future MPs' scope, sequence, or interfaces. Append a dated entry to the Amendments Log (§11); mark affected MP entries inline with`[amended YYYY-MM-DD]`\n\n; re-plan affected MPs when you reach them.**(c) Add/split/reorder MPs**— significant new work or structural shift. Amend spec + create new design doc(s) for affected MPs before continuing.\n\n**The trigger MP continues only after the amendment is recorded**(for options b and c).\n\n| Discovery | Action |\n|---|---|\n| Affects only the current MP's internals | Edit current MP's design doc + plan; no spec change |\n| Affects only the current MP's implementation plan | Edit current MP's plan; no spec or design doc change |\nChanges an interface in `src/lib/bindings/*/types.ts` that future MPs consume |\nSpec amendment — affects future MPs |\nChanges MP scope, ordering, or promotes/demotes from `future/` |\nSpec amendment |\n| Discovers a new sub-system needed | Spec amendment — add new MP |\n| Discovers an MP is unnecessary | Spec amendment — demote to `future/` |\n\nAt the end of each folder's last MP, before moving to the next folder, the human runs a checkpoint:\n\n- Re-read the plan-of-plans spec against the current code state.\n- For each remaining MP, ask: \"Does the code reality still match this MP's scope and dependencies?\"\n- If no → write an amendment entry, mark affected MP headings.\n- If a future MP's design doc already exists, mark it for revision when you reach it.\n- Commit the spec amendment as its own commit:\n`docs: amend plan-of-plans after <folder> checkpoint`\n\n.\n\n**Checkpoint cadence (5 total)**:\n\n- After\n`00-foundations/`\n\n(end of MP-0d) - After\n`01-catalog/`\n\n(end of MP-2) - After\n`03-checkout/`\n\n(end of MP-6b — most complex folder) - After\n`04-orders/`\n\n+`05-compliance/`\n\ncombined (end of MP-9) - After\n`06-growth/`\n\n+`99-cross-cutting/`\n\ncombined (end of MP-14)\n\nDon't rely only on AI honesty. Three mechanical signals:\n\n— catches interface drift in`pnpm typecheck`\n\nat end of every MP`src/lib/bindings/*/types.ts`\n\nthat later MPs depend on.**Smoke tests for deferred MPs**— keep thin \"smoke\" tests for`future/`\n\nitems that assert their interfaces still typecheck. If MP-5 changes`PaymentProvider`\n\n, MP-6a's smoke test breaks.**Per-folder review checkpoint**(§9.4) — re-reads spec against code state, catches silent drift the AI didn't flag.\n\nAll decisions locked during the brainstorming session. No TBDs.\n\nAppend-only. New entries added at the bottom. Never rewrite history.\n\n*(No amendments yet — spec as committed on 2026-07-07.)*", "url": "https://wpnews.pro/news/a-plan-of-plans-for-a-production-grade-end-to-end-e-commerce-website", "canonical_source": "https://gist.github.com/Vikaskumargd/e463a7bcc4e2102c3eac5ca00efe9346", "published_at": "2026-07-07 09:02:22+00:00", "updated_at": "2026-07-07 09:28:38.907239+00:00", "lang": "en", "topics": ["developer-tools", "ai-products"], "entities": ["Astro", "Cloudflare Workers", "Razorpay", "GitHub Actions", "Lighthouse CI", "Cloudflare Turnstile", "Workers Analytics Engine", "Workers Observability"], "alternates": {"html": "https://wpnews.pro/news/a-plan-of-plans-for-a-production-grade-end-to-end-e-commerce-website", "markdown": "https://wpnews.pro/news/a-plan-of-plans-for-a-production-grade-end-to-end-e-commerce-website.md", "text": "https://wpnews.pro/news/a-plan-of-plans-for-a-production-grade-end-to-end-e-commerce-website.txt", "jsonld": "https://wpnews.pro/news/a-plan-of-plans-for-a-production-grade-end-to-end-e-commerce-website.jsonld"}}