Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Select an option

  • Save Vikaskumargd/e463a7bcc4e2102c3eac5ca00efe9346 to your computer and use it in GitHub Desktop.

Select an option

Save Vikaskumargd/e463a7bcc4e2102c3eac5ca00efe9346 to your computer and use it in GitHub Desktop.
A plan-of-plans for a production-grade end-to-end e-commerce website.

Pink Pulsar — Plan of Plans (Design Spec)

Status: Approved in brainstorming session 2026-07-07 Owner: vikas (human) — executes by dispatching AI per mini-plan using superpowers Repo: pink-pulsar — Astro 7 + @astrojs/cloudflare adapter on Cloudflare Workers 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.


1. Product & business context

Dimension Decision
Products Physical goods, small catalog (~5 products)
Market India (INR, English only for v1)
Goal Full ownership, no platform fees
Payments Razorpay (UPI, cards, netbanking, COD)
Customer auth Guest checkout only — no accounts in v1
Fulfillment Manual packing + flat-rate shipping
Notifications Email now; WhatsApp deferred to future/
Order states Minimal: placed → paid → shipped → delivered (+ cancelled); extensible for provider statuses later
Admin Basic admin in this repo now; full admin panel deferred to future/
Compliance Legal pages now (Privacy, Terms, Returns, Shipping, Contact/About). GST tax handling, GST invoices, DPDP consent deferred to future/.
Marketing Discounts/coupons now. Abandoned cart deferred to future/. Analytics events & funnel now.

2. Non-functional requirements

Performance — Lighthouse 100/100

  • Storefront pages (home, catalog, product detail, legal) prerendered at build (SSG) via Astro. Pure HTML + minimal islands.
  • Only dynamic server-rendered routes: /cart, /checkout, /checkout/success, /admin/orders/*, /orders/[token].
  • Lighthouse CI in GH Actions gates every PR: 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.
  • Long-cache headers for static assets; short cache for HTML.
  • MP-13 closes the loop: image variants, cache headers, critical-CSS inlining, font subsetting, RUM budget assertions.

SEO

  • Full <head> meta (title, description, canonical, robots, OpenGraph, Twitter cards) via a base component in MP-0a.
  • JSON-LD: Product, Offer, BreadcrumbList, Organization, WebSite.
  • @astrojs/sitemap integration for sitemap.xml index (MP-12).
  • Static public/robots.txt.
  • OG-image route per product (MP-12).
  • hreflang stub set up now (IN only for v1) — extends cleanly when multi-language is added later.
  • Custom 404/500 pages (MP-9).

Security — fold into MPs + audit at end (MP-14)

  • Cloudflare automatic DDoS + managed WAF rules cover volumetric threats (zero setup).
  • Workers Rate Limiting binding wired in MP-0d; used per-feature.
  • Security headers (CSP, HSTS, X-Frame-Options, Referrer-Policy, Permissions-Policy) in MP-0d middleware.
  • Cloudflare Turnstile on admin login (MP-7).
  • Astro Actions built-in CSRF protection — verified in MP-0a, used by every Action MP.
  • astro:schema (the astro/zod module) for input validation on every Action — native, no standalone Zod.
  • Razorpay signature verification on every webhook (MP-5).
  • Hashed shared secret in KV + httpOnly secure cookie for admin auth (MP-7).
  • HMAC-signed tokens via Web Crypto for guest order-status links (MP-8).
  • Wrangler secret store for all secrets; .dev.vars for local (MP-0c).
  • MP-14 (security audit) tunes thresholds, tightens CSP, reviews WAF rules, audits dependencies, walks through threats with real traffic data.

Observability & analytics — Cloudflare-native only for v1

  • Workers Observability (already enabled in wrangler.jsonc) for server-side error tracking.
  • Workers Analytics Engine for product analytics events via a first-party /rum beacon endpoint (~50 lines, MP-0d).
  • Zero client-side analytics SDK — preserves Lighthouse 100.
  • Sentry / PostHog / session replay deferred to future/ as lazy-load mini-plans.

3. Architecture

3.1 Pattern: Feature-slice + Astro Actions + Hybrid prerender (D-prime)

Three-tier server delivery, all native Astro, zero extra routers:

  1. 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.
  2. Astro Actions (src/actions/) — type-safe RPC for every app-internal mutation:
    • cart/add, cart/update, cart/remove, cart/clear
    • checkout/createOrder, checkout/capture
    • admin/login, admin/updateOrderStatus, admin/assignTracking
    • orders/getStatus (for the guest order-status page)
    • End-to-end type safety from UI → service via astro:schema for input/output schemas.
  3. Astro API routesexactly one: /api/webhooks/razorpay.ts (raw external webhook needing signature verification + custom body parsing). That's the API-route exception; everything else is an Action.
  4. Dynamic server-rendered routes (opted out of prerender via export const prerender = false): /cart, /checkout, /checkout/success, /admin/orders/*, /orders/[token]. Render via loader + call Actions from client islands.

Hybrid output: output: 'static' (Astro 7 default) with prerender = false only on the dynamic routes above. Storefront build is SSG; dynamic routes are on-demand SSR via the Cloudflare Worker; Actions run on the Worker.

3.2 Folder layout — extends Astro conventions

Astro uses file-based routing in src/pages/, native Actions in src/actions/, native middleware in src/middleware.ts, and has existing src/components/, src/layouts/, src/assets/. We extend these — not replace them. Cross-cutting code lives in src/lib/; feature business logic (non-routing) lives in src/features/.

src/
  pages/                         # Astro file-based routing — ALL pages live here (existing)
    index.astro                  #   home (prerendered)
    products/                    #   catalog (prerendered)
      index.astro                #     product list
      [slug].astro               #     product detail
    cart.astro                   #   cart page (dynamic)
    checkout/                    #   checkout flow (dynamic)
      index.astro                #     address + shipping step
      review.astro               #     review + pay step
      success.astro              #     order confirmed
    orders/                      #   guest order status (dynamic)
      [token].astro
    admin/                       #   basic admin (dynamic, auth-gated)
      login.astro
      orders/
        index.astro
        [id].astro
      coupons/                   #   MP-10 discounts admin
        index.astro
    api/                         #   the ONE api route folder
      webhooks/
        razorpay.ts
    privacy.astro                #   legal pages (prerendered)
    terms.astro
    returns.astro
    shipping.astro
    contact.astro
    about.astro
    health.astro                 #   health check
    rum.ts                       #   analytics beacon endpoint
    404.astro
    500.astro
  actions/                       # Astro Actions — native location (RPC entry points)
    cart.ts                      #   thin: parse → service → return
    checkout.ts
    admin.ts
    orders.ts
  components/                    # Astro components — existing, extended
    ui/                          #   Astro-native shadcn base components (Button, Input, Card, ...)
    cart/                        #   cart-specific components (CartSlideover, CartBadge)
    checkout/                    #   checkout-specific components
    admin/                       #   admin-specific components
    seo/                         #   SEO components (MetaHead, JsonLd)
  layouts/                       # Astro layouts — existing
    Layout.astro                 #   base layout with <head>, tokens, font optimization
  assets/                        # Astro assets — existing (astro:assets)
  styles/                        # Global styles, Tailwind v4 entry, design tokens (CSS variables)
  content/                       # Astro content collections (if legal pages migrate to markdown later)
  middleware.ts                  # Native Astro middleware — security headers, request-id, logger, admin auth guard
  env.d.ts                       # Astro env type definitions
  lib/                           # Cross-cutting code — NOT Astro routing
    core/                        #   framework-agnostic, pure-TS, fully unit-tested
      env.ts                     #     typed binding accessor (D1, R2, KV, Analytics Engine, secrets)
      logger.ts                  #     structured logging + request id (Workers Logs adapter)
      errors.ts                  #     error taxonomy (UserError, ServerError, PaymentError, ...)
      auth.ts                    #     HMAC token sign/verify, admin session helpers
      rate-limit.ts              #     Workers Rate Limiting binding helpers
    db/                          #   Drizzle ORM
      schema/                    #     schema definitions (split by feature: catalog.ts, orders.ts, coupons.ts)
      migrations/                #     Drizzle migrations
      client.ts                  #     Drizzle client factory
    bindings/                    #   provider adapters (concrete impls) + interface types
      payment/                   #     types.ts (PaymentProvider) + razorpay.ts (RazorpayAdapter)
      email/                     #     types.ts (EmailSender) + smtp.ts
      images/                    #     types.ts (ImageRepository) + r2.ts
      cart/                      #     types.ts (CartRepository) + kv.ts
      analytics/                 #     types.ts (AnalyticsSink) + analytics-engine.ts
      logger/                    #     types.ts (Logger) + workers-logs.ts
    app/                         #   composition root — the ONLY place concrete adapters are imported
      prod.ts                    #     wires real adapters → services
      test.ts                    #     wires fakes → services
  features/                      # Feature slices — business logic only (NO routing, NO .astro pages)
    catalog/                     #   MP-1, MP-2
      service.ts  repository.ts  types.ts  tests/
    cart/                        #   MP-3, MP-4
      service.ts  repository.ts  types.ts  tests/
    checkout/                    #   MP-5, MP-6a, MP-6b
      service.ts  repository.ts  types.ts  tests/
    orders/                      #   MP-7, MP-8
      service.ts  repository.ts  types.ts  tests/
    admin/                       #   MP-7 admin business logic
      service.ts  types.ts  tests/
    seo/                         #   MP-12 (JSON-LD helpers, OG-image gen helpers)
      jsonld.ts  og-image.ts  tests/
    legal/                       #   MP-9 (legal page content/metadata)
      content.ts  tests/
public/
  robots.txt                     # static file (MP-12)

Key differences from a non-Astro project:

  • Pages live in src/pages/ (file-based routing) — NOT inside src/features/*/pages/. Pages are thin: they call services and render.
  • Components live in src/components/ (Astro convention) organized by feature subfolder — NOT inside src/features/*/components/.
  • Actions live in src/actions/ (native Astro location).
  • Middleware lives in src/middleware.ts (native Astro middleware) — replaces the custom withMiddleware() helper.
  • Feature slices in src/features/ contain ONLY non-routing business logic: service.ts, repository.ts, types.ts, tests/.

3.3 Loose coupling — every external dependency behind an interface

Concern Interface Default impl Swap target
Database *Repository per feature Drizzle + D1 Postgres, Turso, Mongo — replace that slice's repository only
Payments PaymentProvider RazorpayAdapter Stripe, PayPal — new file in bindings/, wire in app/prod.ts
Email EmailSender SmtpAdapter (Cloudflare Email Service) SES, Postmark, Resend — swap adapter only
Object storage ImageRepository R2Adapter S3, Cloudinary — swap adapter only
Cart store CartRepository KVAdapter D1, Redis (Upstash) — swap adapter only
Analytics AnalyticsSink AnalyticsEngineAdapter PostHog, Rudderstack — swap adapter only
Logger Logger WorkersLogsAdapter Sentry, Datadog — swap adapter only

Composition root: src/lib/app/prod.ts wires real adapters; src/lib/app/test.ts wires fakes. Services take interfaces as constructor args — never import an adapter directly. Tests pass fakes, prod passes the real adapter. To swap payments: write StripeAdapter.ts in src/lib/bindings/payment/, change one line in src/lib/app/prod.ts, done. Zero churn in any feature slice.

3.4 Dependency injection — constructor injection, manual, no framework

Services take adapters as constructor args:

// src/lib/bindings/payment/types.ts
export interface PaymentProvider {
  createOrder(opts: CreateOrderOpts): Promise<{ orderId: string }>;
  verifySignature(opts: VerifyOpts): Promise<boolean>;
  refund(orderId: string, amount: number): Promise<RefundResult>;
}

// src/features/checkout/service.ts
export class CheckoutService {
  constructor(private deps: { payment: PaymentProvider; orders: OrderRepository; email: EmailSender }) {}
  async createOrder(input: CreateOrderInput) { /* uses this.deps.payment */ }
}

// src/lib/app/prod.ts — the only place that knows about real adapters
export const checkout = new CheckoutService({
  payment: new RazorpayAdapter(env.RAZORPAY_KEY, env.RAZORPAY_SECRET),
  orders: new DrizzleOrderRepository(env.DB),
  email: new SmtpAdapter(env.SMTP_URL),
});

// src/actions/checkout.ts — thin
import { checkout } from '~/lib/app/prod';
export const createOrder = defineAction({ handler: async (input) => checkout.createOrder(input) });

Why no DI framework: ~6 services and ~8 adapters — a single app/prod.ts file of ~30 lines wires the whole graph. A framework would add magic + bundle weight for zero benefit at this scale.

3.5 Lint-enforced isolation (ESLint no-restricted-imports)

  • src/actions/* → may import src/features/*/service + src/lib/core/* only
  • src/features/*/service.ts → may import src/features/*/repository (interfaces) + src/lib/bindings/*/types (interfaces only, never concrete adapters) + src/lib/db/ schemas + src/lib/core/*
  • src/lib/bindings/* + src/lib/db/* → only place that touches Cloudflare bindings / vendor SDKs / Drizzle
  • No src/features/A may import src/features/B internals
  • src/lib/app/prod.ts + src/lib/app/test.ts are the ONLY files allowed to import concrete adapters
  • src/pages/* → may import src/features/*/service + src/components/* + src/layouts/* only (pages are thin)

3.6 TypeScript — strict mode

Enabled in MP-0a. strict: true, noUncheckedIndexedAccess: true, exactOptionalPropertyTypes: true. No any without explicit eslint-disable comment explaining why.


4. Astro-native-first principle (standing rule)

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.

Decisions locked under this principle:

Concern Native choice Notes
API/RPC Astro Actions (src/actions/) Native
Webhook route Astro API route (src/pages/api/) One exception for Razorpay
Middleware Astro native middleware (src/middleware.ts) Native — replaces custom withMiddleware()
Input validation astro:schema (astro/zod module) Native, not standalone Zod
Fonts Astro experimental native font optimization MP-0a
Images (build-time) Astro <Image> + astro:assets MP-1, MP-2, MP-14
Images (post-build/admin upload) R2 + Cloudflare Image Resizing Adapter pattern
Sitemap @astrojs/sitemap integration MP-12
Robots.txt Static public/robots.txt file MP-12
Testing astro test (uses Vitest under the hood) Native
Content (if blog ever added) astro:content collections + @astrojs/mdx Future
Rate limiting Workers Rate Limiting binding Platform-native
Analytics Workers Analytics Engine Platform-native
Error tracking Workers Observability Platform-native
Email Cloudflare Email Service Platform-native

External deps kept (no native alternative exists):

  • Tailwind v4 — CSS tool, zero JS shipped, explicitly requested + needed for shadcn token system
  • Drizzle ORM — thinnest D1-compatible ORM, compile-time queries, no runtime weight
  • Astro-native shadcn port — UI components built on the shadcn CSS-variable token system

5. UI/UX stack

  • 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.

6. Storage stack — D1 + KV + R2 + Analytics Engine

Binding Purpose Wired in
D1 (DB) Products, variants, product images metadata, orders, order items, discounts, coupons MP-0b (binding), MP-1 (first tables), MP-6a (orders), MP-10 (discounts)
KV (CART) Cart state, admin session, rate-limit counters MP-0b (binding), MP-3 (cart), MP-7 (admin session)
R2 (IMAGES) Product images (admin-uploaded), generated invoices MP-0b (binding), MP-1 (read), MP-7 (admin upload if added)
Analytics Engine (ANALYTICS) Product events (page_view → purchase funnel) MP-0d (binding + beacon), MP-11 (instrumentation)

Drizzle ORM for D1 — thin, compile-time, D1-compatible. Schema in src/lib/db/schema/ (split by feature). Migrations in src/lib/db/migrations/. Client factory in src/lib/db/client.ts. Repository pattern: each feature defines its *Repository interface in src/features/*/repository.ts and a Drizzle implementation; tests use an in-memory fake.


7. Plan of plans — 19 mini-plans

Each mini-plan is:

  • One PR-sized chunk — small enough for thorough human code review
  • One capability end-to-end (where reasonable)
  • Fully tested (Vitest unit + integration; astro test native runner)
  • Lighthouse CI green (block < 90, warn < 100)
  • Preview deploy verified on Cloudflare before merge
  • Implemented by AI on demand using superpowers; the plan-of-plans is for human use only

Mini-plans are grouped into folders by sub-system so you navigate one area at a time.

00-foundations/ — 4 mini-plans

MP-0a — Repo skeleton & tooling

  • tsconfig paths, strict mode, noUncheckedIndexedAccess, exactOptionalPropertyTypes
  • Tailwind v4 setup (CSS-native config) in src/styles/
  • Astro experimental native font optimization
  • Astro-native shadcn base components in src/components/ui/ (Button, Input, Card, etc.) + shared CSS-variable design tokens
  • Base SEO <head> component in src/components/seo/MetaHead.astro (title, description, canonical, OG, Twitter cards)
  • Base responsive image component scaffold (Astro <Image> + astro:assets)
  • ESLint with no-restricted-imports rules from §3.5; Prettier
  • Vitest via astro test
  • src/layouts/Layout.astro with head + token-driven styles + font optimization
  • .dev.vars skeleton for local secrets
  • Tests: repo boots, layout renders, lint passes, base components render.
  • Pages touched: src/layouts/Layout.astro only.

MP-0b — Storage plumbing

  • D1 binding in wrangler.jsonc + Drizzle migration infra in src/lib/db/ (no tables yet)
  • R2 binding + ImageRepository interface in src/lib/bindings/images/
  • KV binding + CartRepository + SessionRepository interfaces in src/lib/bindings/cart/
  • Analytics Engine binding + AnalyticsSink interface in src/lib/bindings/analytics/
  • src/lib/bindings/ folder 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.

MP-0c — CI/CD pipeline

  • GH Actions workflow: lint + typecheck + astro test + 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 main
  • Wrangler secret store wiring for prod secrets
  • PR template (checklist: tests added, Lighthouse green, preview verified, doc-search-for-native-integrations done)
  • Dependabot enabled (security updates)
  • Tests: pipeline green on a stub route; preview URL reachable.
  • Pages touched: none.

MP-0d — Cross-cutting runtime

  • Typed env/binding accessor in src/lib/core/env.ts
  • Structured logger + request id in src/lib/core/logger.ts (Workers Logs adapter)
  • Error taxonomy in src/lib/core/errors.ts (UserError, ServerError, PaymentError, etc.)
  • Native Astro middleware in src/middleware.ts — security headers (CSP, HSTS, X-Frame-Options, Referrer-Policy, Permissions-Policy), request-id injection, logger setup on locals
  • HMAC token sign/verify helpers in src/lib/core/auth.ts (used by MP-4 checkout links, MP-8 order-status links)
  • Workers Rate Limiting binding wired; per-feature rate-limit helpers in src/lib/core/rate-limit.ts
  • /health route
  • /rum beacon endpoint (~50 lines) → Analytics Engine
  • src/lib/db/ folder layout with empty migration scaffolding; src/features/*/ folders with empty service.ts + repository.ts interface stubs
  • Tests: logger/env/error unit tests; /health and /rum integration tests; middleware security-headers assertion test.
  • Pages touched: /health, /rum (endpoints only).

01-catalog/ — 2 mini-plans

MP-1 — Product data model

  • Drizzle schema for products, variants, product_images in src/lib/db/schema/catalog.ts
  • First migration
  • ProductRepository interface in src/features/catalog/repository.ts + Drizzle impl
  • Seed 5 products (with variants + images) via a seed script
  • Astro <Image> + astro:assets for build-time images
  • Tests: repository CRUD — unit tests against in-memory fake; integration tests against local D1 (Miniflare).
  • Pages touched: none.

MP-2 — Storefront catalog pages

  • Home page at src/pages/index.astro, product list at src/pages/products/index.astro, product detail at src/pages/products/[slug].astro (all prerendered at build)
  • catalog service (getProduct, listProducts) in src/features/catalog/service.ts
  • SEO meta + JSON-LD (Product, Offer, BreadcrumbList) on product pages via src/components/seo/
  • Responsive image rendering via Astro <Image> + R2 for admin-uploaded images
  • Astro-native shadcn components from src/components/ui/ for layout
  • Tests: pages render with seeded data; Lighthouse passes (≥100 perf target).
  • Pages touched: /, /products, /products/[slug].

02-cart/ — 2 mini-plans

MP-3 — Cart persistence & UI

  • CartRepository KV default impl in src/lib/bindings/cart/
  • Cart service (addToCart, updateLine, removeLine, clear, totals) in src/features/cart/service.ts
  • Cart Actions (cart/add, cart/update, cart/remove, cart/clear) in src/actions/cart.ts with astro:schema input validation
  • Cart slide-over UI in src/components/cart/ (Astro-native shadcn components + React island for interactivity)
  • Cart badge in header
  • Tests: cart service + KV impl; UI smoke test.
  • Pages touched: cart slide-over (in Layout), /cart.

MP-4 — Checkout bridge

  • CheckoutDraft typed shape (items, address, shipping method, totals) in src/features/checkout/types.ts
  • Address form + flat-rate shipping method selection page at src/pages/checkout/index.astro
  • Draft persisted to KV with short TTL
  • HMAC-signed checkout link for guest (so customer can resume if they navigate away) — uses src/lib/core/auth.ts
  • astro:schema validation on all form inputs in src/actions/checkout.ts
  • Tests: draft lifecycle (create/read/update/expire), signed-link validation.
  • Pages touched: /checkout (address + shipping step).

03-checkout/ — 3 mini-plans

MP-5 — Razorpay adapter & webhook

  • PaymentProvider interface in src/lib/bindings/payment/types.ts
  • RazorpayAdapter in src/lib/bindings/payment/razorpay.ts
  • Order create + capture flow against Razorpay test mode
  • src/pages/api/webhooks/razorpay.ts — raw body parse, signature verification, idempotency
  • Secrets via Wrangler secret store; .dev.vars for local
  • Tests: adapter against Razorpay test mode; webhook signature verification test; idempotency test.
  • Pages touched: /api/webhooks/razorpay (one API route).

MP-6a — Orders server (orders table + capture)

  • orders + order_items Drizzle schema in src/lib/db/schema/orders.ts + migration
  • OrderRepository interface + Drizzle impl in src/features/orders/
  • checkout service createOrder (creates order in placed state) + capture (transitions to paid on verified webhook)
  • Order state machine: placed → paid → shipped → delivered (+ cancelled)
  • Tests: order state transitions; repository CRUD; end-to-end capture against fake payment provider.
  • Pages touched: none (server-only).

MP-6b — Checkout UI flow

  • Checkout review page (src/pages/checkout/review.astro) — review items + address + shipping + totals
  • Razorpay Checkout (hosted redirect) for v1; Razorpay Embedded can be a future swap if lower-friction UX is wanted
  • Success page (src/pages/checkout/success.astro)
  • Email-on-paid: EmailSender interface + SmtpAdapter in src/lib/bindings/email/ (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, /checkout/success.

04-orders/ — 2 mini-plans

MP-7 — Basic admin

  • Hashed shared secret in KV + http-only secure cookie session
  • Cloudflare Turnstile on login form (bot mitigation)
  • Rate-limited login via Workers Rate Limiting binding (helpers from src/lib/core/rate-limit.ts)
  • /admin/orders list page (filterable by status) at src/pages/admin/orders/index.astro
  • /admin/orders/[id] detail page at src/pages/admin/orders/[id].astro
  • Status change Actions in src/actions/admin.ts (admin/updateOrderStatus, admin/assignTracking) with astro:schema
  • Manual "tracking id" text field (free text, surfaces on customer order-status page)
  • Email on every status change (via EmailSender)
  • Admin business logic in src/features/admin/service.ts
  • Tests: admin auth (success, failure, rate-limit); status transitions; email dispatch on each transition.
  • Pages touched: /admin/login, /admin/orders, /admin/orders/[id].

MP-8 — Guest order-status page

  • /orders/[token] route at src/pages/orders/[token].astro where token is HMAC-signed (Web Crypto) containing order id + expiry
  • Read-only status display + tracking id (if assigned) + items
  • Email-on-status-change already sends the signed link (wired in MP-7)
  • Tests: signed-link validation (valid token, expired token, tampered token); rendering.
  • Pages touched: /orders/[token].

05-compliance/ — 1 mini-plan

MP-9 — Legal pages

  • Privacy Policy page at src/pages/privacy.astro
  • Terms of Service page at src/pages/terms.astro
  • Returns policy page at src/pages/returns.astro
  • Shipping policy page at src/pages/shipping.astro
  • Contact / About page at src/pages/contact.astro and src/pages/about.astro
  • Custom 404 page at src/pages/404.astro
  • Custom 500 page at src/pages/500.astro
  • All prerendered; all linked in footer; SEO meta on each
  • Content as plain Astro pages for v1 (simplest); can migrate to astro:content collection later if markdown editing is preferred
  • Page content/metadata helpers in src/features/legal/content.ts
  • Tests: pages render; footer links resolve; 404/500 routes return correct status codes.
  • Pages touched: /privacy, /terms, /returns, /shipping, /contact, /about, /404, /500.

06-growth/ — 2 mini-plans

MP-10 — Discounts & coupons

  • coupons + coupon_redemptions Drizzle schema in src/lib/db/schema/coupons.ts + migration
  • Coupon types: % off, flat off, free shipping; constraints: min-order, expires, single-use, per-customer-cap
  • DiscountService in src/features/checkout/service.ts (or a dedicated src/features/discounts/) applies at checkout (line or order total)
  • Admin Actions in src/actions/admin.ts to create/list/disable coupons
  • Coupon input on checkout review page
  • Tests: coupon application logic (all types + constraints); redemption tracking; admin Actions.
  • Pages touched: checkout review (add coupon input), /admin/coupons.

MP-11 — Analytics events & funnel

  • Define GA4-style e-commerce event taxonomy: page_view, view_item, add_to_cart, begin_checkout, add_shipping_info, add_payment_info, purchase
  • Instrument storefront pages + cart Actions + checkout flow
  • Events sent to /rum beacon → Analytics Engine (wired in MP-0d) via src/lib/bindings/analytics/
  • Maps to GA4/Meta Pixel standard so you can later add ads without re-instrumenting
  • Tests: event emission assertions per funnel step; Analytics Engine binding receives expected events.
  • Pages touched: instrumentation on existing pages (no new pages).

99-cross-cutting/ — 3 mini-plans

MP-12 — SEO infrastructure

  • @astrojs/sitemap integration for sitemap.xml index
  • Static public/robots.txt
  • OG-image route per product at src/pages/og/[slug].png.ts (generated via satori + sharp; helpers in src/features/seo/og-image.ts)
  • hreflang stub (IN only for v1) — extends cleanly for multi-language later
  • Full JSON-LD: Organization, WebSite in src/features/seo/jsonld.ts (in addition to per-product JSON-LD from MP-2)
  • Canonical URL audit
  • Meta-tag unit tests (every prerendered page has title + description + canonical + OG)
  • Tests: sitemap shape; robots.txt content; JSON-LD validates against schema.org; OG-image route returns image.
  • Pages touched: /sitemap-index.xml, /og/[slug].png (endpoints only).

MP-13 — Performance tuning & Lighthouse ≥100 verification

  • Image variants via R2 + Cloudflare Image Resizing for admin-uploaded images (via src/lib/bindings/images/)
  • Long-cache headers for static assets (R2 + asset binding)
  • Critical-CSS inlining
  • Font subsetting (via Astro native font optimization from MP-0a)
  • Lighthouse CI thresholds tightened (warn < 100 enforced)
  • RUM budget assertions (real-user metrics from /rum beacon)
  • Tests: Lighthouse ≥100 perf on key routes (home, product list, product detail); budget assertions.
  • Pages touched: instrumentation on existing pages (no new pages).

MP-14 — Security audit

  • WAF rule review with human (in Cloudflare dashboard)
  • CSP tightening in src/middleware.ts based on actual third-party scripts used
  • Rate-limit threshold tuning in src/lib/core/rate-limit.ts with real traffic data
  • Dependency audit (Dependabot + manual review)
  • Threat-model walkthrough with human
  • Pen-test-style review of: admin auth, Razorpay webhook, signed order-status links, all Action input validation
  • Tests: security regression test suite (auth bypass attempts, signature forgery, CSRF, XSS attempts).
  • Pages touched: none (audit + config).

8. Deferred to future/ (not in v1)

Listed here so we know they exist. Each will get its own mini-plan when prioritized.

  • Full admin panel (own area or repo)
  • WhatsApp notifications
  • Shiprocket integration / pincode serviceability / auto-shipment creation
  • Multi-currency / multi-language (i18n)
  • Reviews / ratings
  • Returns / RMA / formal refund flow (deferred — for v1, admin can mark an order as cancelled and issue a manual refund/invoice outside the app)
  • Wishlist (needs accounts to be useful)
  • Search (overkill for 5 products)
  • Recommendations / related products
  • Out-of-stock email notifications
  • Newsletter / marketing capture
  • GST tax handling (rate matrix, HSN codes, intra-state/inter-state split)
  • GST-compliant tax invoices (serial-numbered, downloadable)
  • DPDP Act consent capture at checkout
  • Abandoned cart recovery (deferred — needs UX decision on email capture point)
  • Session replay (rrweb — incompatible with Lighthouse 100)
  • Sentry / PostHog / third-party analytics SDKs (lazy-load post-LCP if added)
  • A/B test platform
  • Loyalty program

9. Execution model

  • The plan-of-plans is for human use only. The AI does not execute it.
  • The human dispatches the AI to implement one mini-plan at a time using superpowers.
  • Each mini-plan becomes one PR (or a small number of small PRs if the AI splits further during implementation).
  • After every mini-plan, the human does code review before the next MP is dispatched.
  • Every mini-plan ends with: tests green + Lighthouse CI green + preview deploy verified + human review passed.
  • Before implementing any MP, the AI web-searches Astro + Cloudflare docs to confirm native integrations exist before reaching for external deps (§4).

9.1 Per-mini-plan lifecycle

1.  Human picks the next MP from the plan-of-plans
2.  (Optional) brainstorming skill — if the MP has open design decisions not settled in this spec
3.  Write mini-plan design doc → docs/superpowers/specs/YYYY-MM-DD-MP-XX-<topic>-design.md
4.  Human reviews the mini-plan spec → approve / request changes
5.  writing-plans skill → detailed implementation plan with TDD tasks + verification commands
    saved to docs/superpowers/plans/YYYY-MM-DD-MP-XX-<topic>-plan.md
6.  Human reviews the implementation plan
7.  Execute the plan — either executing-plans (separate session, review checkpoints)
    or subagent-driven-development (current session, dispatch subagents per task)
8.  During execution:
    - test-driven-development — write test first, then impl, per task
    - systematic-debugging — if a test fails or behavior is unexpected
    - verification-before-completion — run verification commands before claiming done
9.  requesting-code-review skill — self-review against requirements
10. Human does code review (the gate)
11. receiving-code-review skill — if human gives feedback, AI processes it rigorously
12. finishing-a-development-branch — decide merge / PR / cleanup
13. Next MP — back to step 1

9.2 AI behavior rule on cross-MP drift

If 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:

  1. Stop and flag — never silently absorb a cross-MP change. Pause implementation.
  2. Write an Impact Note in the current MP's plan doc covering:
    • What was discovered
    • Which MPs are affected and how
    • Severity: trivial / contained / cross-MP / spec-level
  3. 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]; 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.
  4. The trigger MP continues only after the amendment is recorded (for options b and c).

9.3 What triggers an amendment vs. a simple edit

Discovery Action
Affects only the current MP's internals Edit current MP's design doc + plan; no spec change
Affects only the current MP's implementation plan Edit current MP's plan; no spec or design doc change
Changes an interface in src/lib/bindings/*/types.ts that future MPs consume Spec amendment — affects future MPs
Changes MP scope, ordering, or promotes/demotes from future/ Spec amendment
Discovers a new sub-system needed Spec amendment — add new MP
Discovers an MP is unnecessary Spec amendment — demote to future/

9.4 Per-folder review checkpoints

At the end of each folder's last MP, before moving to the next folder, the human runs a checkpoint:

  1. Re-read the plan-of-plans spec against the current code state.
  2. For each remaining MP, ask: "Does the code reality still match this MP's scope and dependencies?"
  3. If no → write an amendment entry, mark affected MP headings.
  4. If a future MP's design doc already exists, mark it for revision when you reach it.
  5. Commit the spec amendment as its own commit: docs: amend plan-of-plans after <folder> checkpoint.

Checkpoint cadence (5 total):

  • After 00-foundations/ (end of MP-0d)
  • After 01-catalog/ (end of MP-2)
  • After 03-checkout/ (end of MP-6b — most complex folder)
  • After 04-orders/ + 05-compliance/ combined (end of MP-9)
  • After 06-growth/ + 99-cross-cutting/ combined (end of MP-14)

9.5 Mechanical drift detection (beyond AI self-reporting)

Don't rely only on AI honesty. Three mechanical signals:

  1. pnpm typecheck at end of every MP — catches interface drift in src/lib/bindings/*/types.ts that later MPs depend on.
  2. Smoke tests for deferred MPs — keep thin "smoke" tests for future/ items that assert their interfaces still typecheck. If MP-5 changes PaymentProvider, MP-6a's smoke test breaks.
  3. Per-folder review checkpoint (§9.4) — re-reads spec against code state, catches silent drift the AI didn't flag.

10. Open items — none

All decisions locked during the brainstorming session. No TBDs.


11. Amendments Log

Append-only. New entries added at the bottom. Never rewrite history.

(No amendments yet — spec as committed on 2026-07-07.)

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