/caveman:caveman ultra

# Multideal (מולטידיל) - Project Instructions

Multideal = Hebrew-first PWA marketplace. Connect Israeli businesses to customers via transparent half-price deals. Three revenue layers: deal commission, monthly club settlement, SEO vendor visibility.

**Monorepo:** `apps/web` (main PWA) · `apps/web-do` (DO host worker) · `apps/landing` (waitlist landing). pnpm scripts scoped per app — see nested CLAUDE.md.

**Ground truth docs:**

- `.claude/skills/md-ui-developer/SKILL.md` - UI rules (auto-load on UI edits)
- `.claude/skills/md-server-dev/SKILL.md` - server rules (auto-load on server edits)
- `.claude/skills/md-deploy/SKILL.md` - deploy runbook
- `.claude/skills/md-verify/SKILL.md` - Playwright E2E on live dev.multi.deal
- `Docs/CLOUDFLARE.md` - infra inventory (bindings, secrets, cron, DOs, queues)
- `Docs/CLOUDFLARE-MIGRATION.md` - cron → DO alarms + Queues migration plan

## Skills — when load which

| Editing… | Load skill | Why |
| --- | --- | --- |
| `src/components/ui/**`, `src/features/**`, `src/styles/**`, `src/lib/i18n/**`, any `.tsx` / `.astro` template | **`md-ui-developer`** | Shared-component-only law, design tokens, RTL, IS 5568 a11y, Hebrew+English i18n, `/design-system` registration |
| `src/server/**`, `src/pages/api/**`, Astro server frontmatter, `drizzle.config.ts`, `wrangler.toml`, `src/server/env.ts`, anything under `src/server/{db,auth,middleware,schemas,workflows,payments,storage,email,push,cron,do,queues,ai,admin}/` | **`md-server-dev`** | Infra awareness, zod-at-boundary, query-layer exclusivity, entity-alarm discipline, outbox pattern, CSRF+rate-limit, Neon-HTTP-only, secrets via `env` |
| Deploy, set/rotate secrets, run migrations, debug Worker deploy | **`md-deploy`** | Build-before-deploy rule, secret setup, custom-domain reattach, common-failure table |
| SUMIT payment API work — charge, tokenize, refund, reconcile, webhooks, credentials | **`md-sumit`** | SUMIT credential map, sync payment flow, CRM trigger format, known folder IDs, common mistakes |
| Write/run Playwright tests vs `dev.multi.deal`, verify feature on live | **`md-verify`** | Session injection auth, canvas vs palette selectors, live config, rate-limit avoidance |

**Usage:** request/edit match "Editing…" column → invoke skill via `Skill` tool **before writing code**. Cross-layer task (e.g. API+UI) → load both. UI rules own `src/components/ui/**` + `src/features/**`, server rules own rest.

**Why matter:** entity-alarm arming, outbox dispatch, PII encryption, zod-at-boundary not optional — prevent silent data corruption, missed payouts, OWASP vulns. Skip skill = ship broken/unsafe code.

**Remote:** `https://github.com/alexcodeplace/multideal`

## Bash discipline (BLOCKING for subagents too)

- All `git`/`pnpm`/`npm`/`npx` calls go through RTK proxy automatically (hook rewrites). Never bypass.
- Large-output commands (>20 lines: build, test, lint, broad grep) → use `mcp__plugin_context-mode_context-mode__ctx_batch_execute` or `ctx_execute`. Bash only for git/mkdir/rm/mv/short-output.
- Batch sequential steps with `&&` in one Bash call. Never split one logical operation across multiple tool calls.
- No polling loops; use `run_in_background` + task-notification.

## Environments

Single env. No prod. Worker `multideal-preview` at `https://dev.multi.deal` = live. `pnpm deploy:preview` = ship live. No `deploy:prod` script, no separate prod worker. Say "deploy" or "deploy to dev", not "prod deploy".

---

## Tech stack

| Concern               | Choice                                                                                                                                                     |
| --------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Framework             | Astro 5 + React islands, Cloudflare adapter, hybrid SSR                                                                                                    |
| Styling               | Tailwind v4 w/ CSS-variable design tokens (`@theme`)                                                                                                     |
| Component base        | Radix UI primitives + custom Multideal skin                                                                                                                |
| Design-system gallery | In-app `/design-system` route                                                                                                                              |
| PWA                   | `@vite-pwa/astro` - manifest + service worker + install prompt + Web Push                                                                                  |
| i18n                  | Hebrew (default) + English, navbar toggle                                                                                                                  |
| Database              | Neon Postgres via `@neondatabase/serverless`                                                                                                               |
| ORM                   | Drizzle ORM                                                                                                                                                |
| Auth                  | Custom session (signed cookies) + Firebase phone auth OTP + magic-link guest→user                                                                      |
| Payments              | SUMIT (Israeli marketplace clearing, multi-vendor charge w/ 10% platform fee). Credentials via `wrangler secret put SUMIT_API_KEY` etc. |
| Storage               | Cloudflare R2 + Cloudflare Images (AVIF/WebP/JPEG)                                                                                                         |
| Email                 | Resend (React Email templates)                                                                                                                             |
| Push                  | Web Push API (VAPID) + service worker handlers                                                                                                             |
| Deploy                | `@astrojs/cloudflare` → Cloudflare Workers                                                                                                                 |
| Cron                  | Cloudflare Cron Triggers                                                                                                                                   |
| Icons                 | `lucide-react`                                                                                                                                             |
| Forms                 | `react-hook-form` + `zod` (shared client+server schemas)                                                                                                   |
| State                 | `@tanstack/react-query` (server) + `zustand` (client)                                                                                                      |
| Fonts                 | `@fontsource-variable/heebo` (Hebrew), `@fontsource-variable/inter` (English)                                                                              |
| Testing               | Vitest + Playwright + `@axe-core/playwright`                                                                                                               |
| CI/CD                 | GitHub Actions → Cloudflare Workers                                                                                                                        |
| Observability         | Sentry + Cloudflare Web Analytics                                                                                                                          |

---

## Hard Rules (non-negotiable)

1. **Shared-component-only** — UI all from `@/components/ui/**`. No ad-hoc JSX in pages/features. Create in `ui/**` first, use after.
2. **No hardcoded values** — CSS vars (`var(--color-*)`, `var(--space-*)`) or Tailwind tokens only. Raw values only in `styles/tokens.css` + `styles/contrast-high.css`. ESLint `no-raw-values` enforces.
3. **RTL-first** — logical props only: `ms-*`, `me-*`, `ps-*`, `pe-*`, `start-*`, `end-*`. Never `left`/`right`. Directional icons: `<Icon mirror />`.
4. **A11y IS 5568 / WCAG 2.1 AA** — interactive = `<button>`/`<a>`/Radix primitive. Input has `<Label>`. Image has `alt`. Dialog has title. Respect `prefers-reduced-motion`. Focus rings always visible.
5. **i18n** — user-facing string via `useT(namespace)`. `he.ts` + `en.ts` updated together. `<html lang dir>` live-updates.
6. **SEO** — public page: `<SeoHead>` (title/description/canonical/ogImage/locale/JSON-LD). One `<h1>`. `<Image>` has alt. Hreflang `he`/`en`/`x-default`.
7. **Performance** — images via shared `<Image>` (AVIF → WebP → JPEG). Hero: `eager` + `fetchpriority="high"`. Else: `lazy`. React islands: `client:visible` or `client:idle`.
8. **Security** — zod every API input. No raw HTML render. Parameterized queries. No PII in logs. Secrets in CF bindings only.
9. **Design-system registration** — new component → register on `/design-system` w/ all variants + token usage + a11y notes.
10. **SEO cannibalization** — distinct intent per public page. Search/filter URLs: `noindex`. Unique title+description per page.
11. **Git** — `main` only. Commit per phase (`phase(N): summary`). `gitleaks` blocks secrets. No `--force-push`, no `--no-verify`.
12. **Git scope** — only files needed for Cloudflare deploy belong in git. Tooling config (`.claude/`, editor settings, local scripts), dev artifacts, anything not consumed by build/runtime → gitignored. If not affect Cloudflare Workers ship, stays local.

---

## Directory layout

```
multideal/                      # monorepo root
├── apps/
│   ├── web/                    # Main Astro PWA — see apps/web/CLAUDE.md
│   │   ├── src/
│   │   │   ├── server/         # DB, auth, payments, schemas, DO-client, middleware
│   │   │   ├── components/ui/  # Shared component library (RTL, a11y, i18n)
│   │   │   ├── features/       # Page-level assemblies (compose from ui/**)
│   │   │   ├── pages/          # Thin Astro routes + /api/** handlers
│   │   │   ├── lib/            # i18n (he/en), cn, format, hooks
│   │   │   └── styles/         # tokens.css, globals.css, contrast-high.css
│   │   └── tests/              # unit / components / a11y / e2e / security
│   ├── web-do/                 # DO host worker — see apps/web-do/CLAUDE.md
│   └── landing/                # Waitlist landing page — see apps/landing/CLAUDE.md
├── .claude/skills/             # md-ui-developer, md-server-dev, md-deploy, md-sumit, md-verify
├── Docs/                       # Gitignored: infra docs, secrets inventory, plans
└── pnpm-workspace.yaml
```

---

## Commands

```bash
# Root (monorepo)
pnpm install                    # install all deps
pnpm dev:web                    # start apps/web dev server
pnpm dev:landing                # start apps/landing dev server
pnpm build:web                  # build apps/web
pnpm build:landing              # build apps/landing
pnpm typecheck:web              # typecheck apps/web

# In apps/web/ (full list — see apps/web/CLAUDE.md)
pnpm dev                        # dev server http://localhost:4321
pnpm test                       # vitest unit + component
pnpm test:e2e                   # playwright E2E
pnpm db:migrate                 # drizzle-kit migrate
pnpm deploy:preview             # wrangler deploy (only env — no deploy:prod)
```

---

## Component Registry

> **Registry lives in `md-ui-developer` skill.**
> Load `.claude/skills/md-ui-developer/SKILL.md` (or invoke `md-ui-developer` skill) before UI work. Skill has full registry, hard rules, authoring checklist, forbidden patterns. Never write UI before load skill.

---

## Subtree Guides

- [`apps/web/CLAUDE.md`](apps/web/CLAUDE.md) — main PWA: commands, server layout, test structure
- [`apps/web-do/CLAUDE.md`](apps/web-do/CLAUDE.md) — DO host worker: DO class list, queue consumers, deploy note
- [`apps/landing/CLAUDE.md`](apps/landing/CLAUDE.md) — waitlist landing: components, i18n, deploy

---

## Scripts — batch operations

**Rule: batch bash commands. One tool call > many.**

Fixed sequences repeat across sessions → `scripts/`. One-off combos → chain with `&&` in single Bash call. Never split single logical action across multiple tool calls.

| Script | When to use |
|--------|------------|
| `scripts/check.sh` | Typecheck + lint + test (before committing) |
| `scripts/commit_push.sh "msg"` | Stage → typecheck → commit → push |
| `scripts/deploy.sh "msg"` | Typecheck → build → commit+push → deploy preview |

New fixed sequence → create script in `scripts/`, register here + in relevant skill.

---

## Subagent dispatch contract

Every subagent prompt MUST include closing lines verbatim:

```
Before reporting "done":
1. Run `pnpm --filter web typecheck` — must exit 0.
2. Verify each claim concretely: `grep`/`curl`/`ls dist/` — never assert "X landed" without evidence.
3. If you skip or defer a sub-task, list it explicitly under "Deferred". Do not silently drop.
```

Reason: subagents don't auto-load `verification-before-completion`. Without explicit contract, ship "done" reports that fail downstream typecheck or claim cache-headers/SWR/chunks didn't land.

---

## Known TBDs

- Brand colors: **Blue + White** locked; exact blue ramp tuned in `tokens.css`. Green = semantic vendor-mode accent only.
- SUMIT API: credentials via `wrangler secret put` (see wrangler.toml header). Sandbox org setup Phase 5.
- SMS provider: Firebase phone auth (Google). Israeli deliverability confirmed.
- Loyalty settlement %: configurable env var, set before launch.
- ToS / Privacy copy: skeleton placeholder, legal review later.
- Admin AI agent model: pluggable interface, concrete model TBD.

<!-- code-review-graph MCP tools -->
## MCP Tools: code-review-graph

**IMPORTANT: Project has knowledge graph. ALWAYS use code-review-graph MCP tools BEFORE Grep/Glob/Read to explore codebase.** Graph faster, cheaper (fewer tokens), gives structural context (callers, dependents, test coverage) file scanning cannot.

### When to use graph tools FIRST

- **Exploring code**: `semantic_search_nodes` or `query_graph` instead of Grep
- **Understanding impact**: `get_impact_radius` instead of manually tracing imports
- **Code review**: `detect_changes` + `get_review_context` instead of reading entire files
- **Finding relationships**: `query_graph` with callers_of/callees_of/imports_of/tests_for
- **Architecture questions**: `get_architecture_overview` + `list_communities`

Fall back to Grep/Glob/Read **only** when graph doesn't cover need.

### Key Tools

| Tool | Use when |
|------|----------|
| `detect_changes` | Reviewing code changes — risk-scored analysis |
| `get_review_context` | Need source snippets for review — token-efficient |
| `get_impact_radius` | Understanding blast radius of change |
| `get_affected_flows` | Finding which execution paths impacted |
| `query_graph` | Tracing callers, callees, imports, tests, dependencies |
| `semantic_search_nodes` | Finding functions/classes by name or keyword |
| `get_architecture_overview` | Understanding high-level codebase structure |
| `refactor_tool` | Planning renames, finding dead code |

### Workflow

1. Graph auto-updates on file changes (via hooks).
2. Use `detect_changes` for code review.
3. Use `get_affected_flows` for impact.
4. Use `query_graph` pattern="tests_for" for coverage.
