MOHAN ba22407c22
Some checks failed
CI / Lint, Unit & Integration Tests (push) Has been cancelled
Merge branch 'main' of https://git.metatroncube.in/MetatroncubeSoftwareSolutions/metatrondelivery
2026-08-26 00:30:13 +05:30
2026-08-25 17:28:22 +00:00

Delivery Date & Time

Shopify app: scheduling for Shipping / Local Delivery / Store Pickup, with date-time slots, capacity intelligence, and all-plan checkout enforcement via Cart/Checkout Validation Functions.

Read PRODUCT_STRATEGY.md (why) and IMPLEMENTATION_PLAN.md (how, phased build order) before making changes. CLAUDE.md holds the non-negotiables for AI-assisted work in this repo.

Getting started

npm install
cp .env.example .env        # fill in Shopify app credentials after linking
docker compose up -d        # local Postgres (5433) + Redis (6380)
npx prisma migrate dev
npm run dev                 # shopify app dev — requires `shopify auth login` first

Dev uses Postgres, same as prod, since the schema relies on Prisma enums and (from Phase 5 on) array fields that SQLite can't express. npm run worker runs the BullMQ worker (jobs/worker.ts) once Phase 4 makes it do anything.

shopify.web.toml at the repo root is required — it tells shopify app dev how to run this project's Remix app ([commands] dev = "npm exec remix vite:dev") and lets the CLI wire that local dev server into its reverse proxy/tunnel. Without it, dev still runs the extensions fine but never starts the actual admin app, and the embedded app will show Shopify's generic "Find this app in the pages where you work" fallback with no useful error — application_url/redirect_urls in shopify.app.toml are placeholders that dev overwrites live on Shopify's servers each session once this file exists; don't hand-edit them.

Commands

Command Purpose
npm run dev shopify app dev — local dev against a dev store
npm test Vitest unit tests
npm run test:e2e Playwright E2E
npm run lint / npm run typecheck ESLint / tsc --noEmit
npx prisma migrate dev DB migrations
npm run deploy shopify app deploy — deploy extensions/functions
npm run worker BullMQ worker (hold-expiry, notifications)
npm run test:integration Redis/Postgres-backed tests (slot-hold concurrency, booking flow) — needs docker compose up -d
npm run test:functions Real WASM build + function-runner tests for both Shopify Functions, against fixtures
npm run typegen:functions Regenerate extensions/*/generated/api.ts from each Function's schema.graphql + .graphql query (also runs automatically before npm run typecheck)

Before public launch

The 3 mandatory GDPR compliance webhooks (customers/data_request, customers/redact, shop/redact) are commented out in shopify.app.toml — Shopify refuses to push them until the org requests and is granted Protected customer data access in the Partner Dashboard (Apps → this app → API access → Protected customer data), which is a manual questionnaire/approval step. The handlers are fully implemented against the real schema (app/services/gdpr.server.ts, used by app/routes/webhooks.customers.*.tsx and webhooks.shop.redact.tsx, covered by tests/integration/gdpr.test.ts): customers/data_request compiles and logs the customer's Booking history for the merchant to hand off (Shopify's webhook has no response payload — a self-serve export is a Phase 9+ notification-system enhancement); customers/redact anonymizes customerEmail/customerPhone on matching Bookings while keeping the booking rows for the shop's own revenue/utilization history; shop/redact deletes every shopDomain-scoped row (Booking first, then Location — whose cascade removes SlotTemplate/SlotOverride/BlackoutDate/ Zone/Rate — then Shop and Session; GeocodeCache is deliberately excluded, it's a shared address-keyed cache with no shopDomain). Once Protected customer data access is granted, uncomment the three [[webhooks.subscriptions]] blocks near the bottom of the webhooks section. Required before any public launch or Built-for-Shopify submission — don't ship without it.

Status

Phase 0 (scaffold & CI) through Phase 7 (POS + Checkout UI extensions) are complete — that's the full v1 launch scope per §8 of PRODUCT_STRATEGY.md/§6 of IMPLEMENTATION_PLAN.md. Phase 8 (billing + Built-for-Shopify hardening) is in progress; Phases 9-10 (v1.x fast-follow, v2) are explicitly separate post-launch milestones in the plan, not part of v1.

Billing (Phase 8): real Shopify Billing API integration (app/shopify.server.ts's billing config, built from app/lib/billing-plans.ts's plan/price table — Free/Starter/Growth/Pro per PRODUCT_STRATEGY.md §6). app/routes/app.billing.tsx lets a merchant switch plans (billing.request) or downgrade to Free (billing.cancel); webhooks.app_subscriptions.update.tsx is the durable sync path that keeps Shop.tier correct even when a merchant cancels from Shopify's own billing page instead of this app. Feature gates enforced server-side in both loader and action (not just hidden in the UI): Delivery zones/rates need Growth+ (app.zones._index.tsx, app.rates._index.tsx), the dispatch dashboard needs Starter+ (app.dashboard.tsx, app.dashboard.export.tsx), and location count is capped per tier (Free=1, Starter=3, Growth/Pro= unlimited — app.locations.new.tsx, app.locations._index.tsx's seed-template action). Gated features currently only cover what's actually built in Phases 0-7 — several Growth/Pro features listed in PRODUCT_STRATEGY.md §6 (waitlists, reschedule portal, SMS, etc.) are Phase 9/10 and not yet implemented, so aren't gated on anything yet.

Onboarding & help (Phase 8): app/routes/app._index.tsx shows a "Get set up" checklist (add a location, configure weekly slots, enable the storefront widget, set up delivery zones if Growth+) that auto-detects completion from your actual data, except the storefront-widget step — theme customization isn't visible to this app's database, so it's a manual "Mark as done" acknowledgment stored in Shop.settings.onboarding. app/routes/app.help.tsx (linked from the nav as "Help") is a short in-app reference explaining locations/slots, server-side enforcement, zones/rates, the dashboard, POS/checkout, and data handling.

Not yet verified live: the onboarding checklist and Help page pass typecheck/lint/build but haven't been exercised in an actual embedded admin session — worth a quick look once you're running shopify app dev against a dev store.

Every scheduling surface calls the same two service functions (app/services/availability-request.server.ts, app/services/hold-request.server.ts) — the storefront widget (app-proxy auth), POS (extensions/pos-datetime, session-token auth), and Plus checkout (extensions/checkout-datetime, session-token auth) each have their own thin route wrapper but share the exact same resolution logic and Redis-backed capacity pool, so a slot booked from any one of them is unavailable on the other two. extensions/checkout-datetime's Thank You block and extensions/datetime-widget's new order-confirmation.liquid block both show the confirmed slot after checkout — the Liquid block is what actually satisfies "all plans," since Checkout UI Extensions' thank-you/order-status targets are Plus-only; there's no purchase.order-status.block.render target in this API version (verified against @shopify/ui-extensions' own type definitions — an early guess based on the target name pattern was wrong).

Unverified without a live device/store to test against (noted in-code where relevant): pos-datetime and checkout-datetime both assume process.env.APP_URL is substituted at build time to the app's backend origin, and neither extension's actual runtime behavior has been exercised outside of typechecking against @shopify/ui-extensions' bundled types (which did catch several wrong API-shape guesses during development).

Phase 5's Google Maps / geocoding features (pickup-location map in the widget, radius-zone eligibility, address auto-geocoding on Save Location) are only live if GOOGLE_MAPS_API_KEY is set — either as an env var for server-side geocoding, or as the "Google Maps API key" block setting in the theme editor for the storefront map. Without a key, everything else in Phase 5 (postal-code zones, distance-band rates, delivery-density thresholds) still works — those don't need Maps at all.

The storefront widget's TypeScript source lives in widget-src/datetime-widget/, not inside extensions/datetime-widget/ — a Theme App Extension's directory may only contain assets, blocks, snippets, and locales (the CLI hard-rejects anything else, e.g. a src/ folder, with "Only assets, blocks, snippets, locales directories are allowed"). Editing the widget? Run npm run build:widget to bundle it into extensions/datetime-widget/assets/datetime-widget.js — it also runs automatically before npm run dev / npm run deploy.

Functions are JavaScript, not Rust (extensions/validation-slot/, extensions/delivery-customization/) — no Rust toolchain was available in the environment that built Phase 4, and IMPLEMENTATION_PLAN.md §1 explicitly allows JS as a fallback. Both were generated with shopify app generate extension (once a real Partner login was available) and their business logic (src/evaluate.js in each) is verified two ways: plain Vitest unit tests at the repo root (npm test) and real function-runner fixture tests that compile actual WASM (npm run test:functions, also in CI). extensions/*/generated/ and extensions/*/dist/ aren't committed (matching the CLI's own .gitignore for these extensions) — npm run typegen:functions regenerates the types from the committed schema.graphql, and building runs automatically as part of npm run dev / test:functions.

Description
No description provided
Readme 1.7 MiB
Languages
TypeScript 86.7%
JavaScript 9.2%
Liquid 3%
CSS 1%
Dockerfile 0.1%