# K — Prompt Sonnet 3 : Formulaire `/contribuer` + Redis rate limit

> **Lancer APRÈS validation checkpoint étape 2 (Sonnet 1).**
> Peut tourner en **parallèle avec Sonnet 2** (étape 3 fiche) — pas de conflit attendu.

## Mission

Construire le formulaire de soumission de nouvelle organisation + setup Redis pour rate limiting.

## Contexte (lis AVANT)

**Racine projet** : `nav-carte/`

Specs (toutes dans `nav-carte/V2-cadrage/`) :
1. Spec session : `H-prompt-session-2-front.md` (section "Étape 6")
2. Wireframes formulaire : `E-spec-frontend.md` (page contribuer)
3. Pipe collaboration : `F-spec-pipe-collaboration.md` (workflow modération + statut `pending`)
4. Palette : `palette-nav-v2.md`
5. VPS infra (Redis dispo ?) : `V2-cadrage/VPS-check.md`

Code base :
- `nav-carte/pages/ajouter.vue` (formulaire V1 à reprendre / refondre)
- `nav-carte/server/routes/` (proxy NocoDB)
- Note Sonnet 1 dans JOURNAL-V2.md : conventions composants

## Livrables

- [ ] Page `/contribuer` (refonte de `ajouter.vue`) ou modal `SubmitModal.vue` (tu tranches selon UX cohérence)
- [ ] Validation **Zod** côté client + serveur
- [ ] Champs :
  - `nom` (required, min 3)
  - `url` (optional, regex URL)
  - `description_user` (required, 50-500 chars)
  - `echelle` (required, enum National/Régional/Local)
  - `fonctions` (required, 1-5 multi parmi 10)
  - `territoire` (required, enum Métropole + 5 DOM-TOM)
  - `localisation_ville` (optional, geocoding Nominatim côté serveur si fourni)
  - `submitted_by_email` (required, format email)
- [ ] Submit :
  - POST `/api/submit` → NocoDB avec `moderation_status: "pending"`, `ai_processed: false`
  - Message confirmation : texte exact `E-spec-frontend.md` §9
  - Worker IA (cron 5 min) traitera plus tard — Session 3 (toi tu ne touches pas le worker)
- [ ] **Rate limit Redis** : 3 submits / IP / jour
  - Setup Redis sur VPS (vérifier `VPS-check.md` — sinon `apt install redis-server` + config localhost only)
  - Connexion depuis Nuxt (`ioredis` ou `redis` npm)
  - En local dev : Redis en Docker ou fallback compteur en mémoire (TODO journal)
- [ ] Endpoint `/api/comment` (Sonnet 2) : ajouter rate limit Redis 5 commentaires/IP/jour — coordonne avec Sonnet 2 via JOURNAL-V2.md

## Règles

- Accents français
- Palette respectée
- Mobile-first
- Pas de Google Fonts
- Pas de touche à : carte, sidebar, page fiche détail, worker IA, schéma NocoDB
- Sécurité : pas de leak token NocoDB côté client (proxy Nuxt obligatoire)

## Délégation cascade autorisée

Sous-agents Task (Sonnet) pour : install Redis VPS via SSH, génération schéma Zod, recherche Nominatim API.

## Credentials VPS

- SSH alias : `vps-hetzner` (port 4422)
- Détails : `_System` ou cf. mémoire (reference_vps_ssh_access)
- App nav-carte : `/opt/nav-carte/`

## Critère de fin

- `npm run dev` charge `/contribuer`
- Soumission valide → fiche en NocoDB avec status pending
- Soumission invalide → erreurs Zod affichées
- 4ᵉ submit même IP/jour → 429 rate limit
- Redis tourne sur VPS (ou fallback documenté en local)
- Mobile testé
- Commits atomiques

## Doute / blocage

- Redis impossible à installer VPS → fallback fichier JSON simple (compteur IP/jour) + TODO journal
- Nominatim rate-limited → skip geocoding, store ville texte brut
- Spec ambiguë → tranche au plus simple, note JOURNAL-V2.md
- Blocage dur → STOP + reporte

## Résumé attendu

```
## S2 Étape 6 — [DONE / BLOCKED]

### Livrables
- ✓ ... / ✗ ...

### Décisions
- Redis : VPS / Docker local / fallback JSON ?
- Page vs modal : ...

### À tester
- /contribuer (submit valide + invalide + rate limit)

### Fichiers modifiés / Commits
- ...

### Coordination Sonnet 2
- Rate limit `/api/comment` : posé pour toi ou à toi de poser ?
```
