# TODO

## ✅ Done — QA audit backend (2026-06-21)

Branche `fix/backend-qa-audit-2026-06-21`, build vert. 17/18 items backend de
`docs/qa-audit-2026-06-21.md` corrigés (détail + statut dans ce doc).

- [x] **B-C1** Formulaire contact câblé à Resend (`app/api/contact/route.ts`, validation
      zod serveur, échappement HTML, états succès/erreur côté client).
- [x] **B-H1/B-H2/B-L6** JSON-LD : `Organization` (email, contactPoint, sameAs),
      `SoftwareApplication`/`Offer` (url, availability, priceValidUntil), logo width/height.
- [x] **B-H3/B-M5/B-M6/B-L1** Deps : `@types/mdx`→devDeps, `@radix-ui/react-slot` retiré
      (umbrella `radix-ui`), `@heroicons/react` déclaré, `lucide-react`→`@tabler/icons-react`.
- [x] **B-M1/B-M2** `.gitignore` (`.env*` + `!.env.example`) et `.env.example` créés.
- [x] **B-M3** Headers de sécurité (CSP/HSTS/X-Frame/…) dans `next.config.ts`.
- [x] **B-M4** Données contact placeholder centralisées (`CONTACT_INFO`).
- [x] **B-M7** knip : `ignore: ["docs/**"]` retiré.
- [x] **B-L4** `outputFileTracingIncludes` restreint à docs/blog.
- [x] **B-L2/B-L3** Investigués → conservés (double renderer MDX requis ; `shiki` peer dep).

### Follow-ups ouverts par ces fixes (à valider côté produit)

- [ ] Confirmer les vraies URLs `SOCIAL_PROFILES` (placeholders `@seoinsight` dans
      `lib/seo/structured-data.ts`).
- [ ] Renseigner les vraies coordonnées de contact (`CONTACT_INFO` dans
      `contact/page.tsx` encore en placeholder) et l'email `hello@seoinsight.app`.
- [ ] Configurer les variables Resend en prod : `RESEND_API_KEY`, `CONTACT_FROM_EMAIL`,
      `CONTACT_TO_EMAIL` (cf. `.env.example`).
- [ ] CSP : si `NEXT_PUBLIC_OP_API_URL` pointe vers un host OpenPanel auto-hébergé custom,
      l'ajouter au `connect-src` dans `next.config.ts` (sinon POST analytics bloqués).
- [ ] Vérifier les dimensions réelles du logo (512×512 supposé dans le JSON-LD).

## Optional / follow-up

### Cache Components (PPR) — go further

- [ ] **(QA B-L5 — différé)** Add `"use cache"` + `cacheLife()` to the marketing page and its mostly-static
      sections (hero, modules, problem, pipeline, mcp, pricing, faq, cta, footer)
      so the static content is cached explicitly instead of re-rendered per request. - Decide a `cacheLife` profile per section (most are `cacheLife('days')`/`'max'`). - Add `cacheTag()` where on-demand revalidation is wanted (e.g. pricing).
- [ ] Consider `"use cache"` on the `[lang]` layout dictionary load (same for all users).

### Cleanup

- [ ] Remove the now-unused `images.remotePatterns` entry for `images.unsplash.com`
      in `next.config.ts` (all Unsplash images were replaced by real premium mockups).
- [ ] Drop the unused `/public/seo-insight-logo.webp` (replaced by the inline
      `BrandMark` SVG everywhere). **⚠️ QA B-L7 :** ce `.webp` reste pour l'instant le seul
      logo *fetchable* par URL utilisé dans le JSON-LD (`structured-data.ts`) — exporter un
      raster/SVG depuis `BrandMark` AVANT de le supprimer, sinon le `ImageObject` casse.

### i18n polish

- [ ] Localize the internal mockup labels that are still English on the FR site
      (Modules kanban: Idea/Brief/Writing/Done; Backlink checklist: Fetching/
      Processing/Scoring/Curating). They mirror the design (English) for now.

### Design fidelity (nice-to-have)

- [ ] FAQ: optionally switch from premium pills to the design's divided-list style.
- [ ] Review pricing plan cards against the design's `.plan` spec (currently 4 plans
      from `lib/pricing` vs the design's 3).

## Analytics

- [ ] PostHog setup (in progress on `feat/posthog` branch via `@posthog/wizard`).
