Skip to content

Commit 1341dc9

Browse files
alexpmicheletclaude
andcommitted
docs(prod-setup): audit complet env vars Convex vs code vs doc
Audit lancé suite à découverte `KMS_MASTER_KEY` manquante (incident précédent). Comparaison set sur Convex (`npx convex env list`) ⇄ refs code (`grep process.env`) ⇄ doc PROD-SETUP. Trouvé 7 oublis + 4 entrées obsolètes à corriger. Ajouts ------ - `CONVEX_SITE_URL` (auto Convex, jamais à fournir manuellement) — note ajoutée pour éviter qu'on la cherche en prod. - `SLACK_OPS_WEBHOOK_URL` (monitoring runMonitoringScan) — recommandée prod sinon les alerts partent dans le vide. - `MONITORING_PAID_NO_COURSE_GRACE_MS` (tunable monitoring). - `WALLET_WWDR_CERT_BASE64` (cert intermédiaire Apple pour signer .pkpass). - `WALLET_SAVE_ORIGINS` (whitelist CORS endpoint /wallet/save). - `WALLET_APNS_AUTH_KEY` / `WALLET_APNS_KEY_ID` / `WALLET_APNS_TEAM_ID` (push update Apple Wallet quand pass change, optionnel V1). - `GOOGLE_WALLET_ISSUER_ID` (séparé du service account JSON, requis pour générer les JWT Google Wallet save links). - `IS_DEV` clarifie le rôle (branche `[DEV] console.log` dans ResendOTP). Corrections ----------- - Section « Uber Direct » : SUPPRIME les anciennes entrées `UBER_DIRECT_CLIENT_ID` / `_CLIENT_SECRET` / `_BASE_URL` / `UBER_WEBHOOK_SIGNING_KEY` (env globales). C'est OBSOLÈTE : depuis slice 2.6-A, les credentials Uber sont per-tenant + chiffrées dans `tenantCredentials` (envelope encryption via `KMS_MASTER_KEY`). Remplacée par un encadré qui pointe vers l'UI admin a posteriori. État dev mis à jour 2026-06-09. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
1 parent b0aa0d0 commit 1341dc9

1 file changed

Lines changed: 35 additions & 20 deletions

File tree

docs/ops/PROD-SETUP-CHECKLIST.md

Lines changed: 35 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
Référentiel exhaustif de **tout ce qui doit être configuré** pour faire tourner KitchenBoost en production. Mis à jour au fur et à mesure du setup dev pour qu'au passage en prod il suffise de cocher chaque ligne.
44

5-
- **Dernière update** : 2026-06-08
5+
- **Dernière update** : 2026-06-09
66
- **État** : dev en cours (E2E PWA Client en train d'être testé)
77
- **Convention** : ⚠️ = secret à régénérer en prod (jamais réutiliser le secret dev) · 🔒 = secret à garder identique (cert long-lived)
88

@@ -76,13 +76,14 @@ Setter via `npx convex env set <KEY> <VALUE>` depuis `packages/backend/`.
7676

7777
### Auth + identity
7878

79-
| Variable | Rôle | Dev | Prod |
80-
| ----------------- | -------------------------------------- | -------------------------------------------------- | ----------------------------------- |
81-
| `JWT_PRIVATE_KEY` | Clé privée signature JWT (Convex Auth) | ✅ set | ⚠️ régénérer |
82-
| `JWKS` | Clés publiques JWT (Convex Auth) | ✅ set | ⚠️ régénérer |
83-
| `AUTH_RESEND_KEY` | API key Resend pour magic-link auth | `re_LuzFTSdt_...` | ⚠️ clé live Resend distincte |
84-
| `SITE_URL` | URL canonique du site (links emails) | `http://localhost:3000` ⚠️ à corriger en dev aussi |`https://admin.kitchen-boost.com` |
85-
| `IS_DEV` | Flag dev | `true` | `false` ou absent |
79+
| Variable | Rôle | Dev | Prod |
80+
| ----------------- | ------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------- | ----------------------------------- |
81+
| `JWT_PRIVATE_KEY` | Clé privée signature JWT (Convex Auth) | ✅ set | ⚠️ régénérer |
82+
| `JWKS` | Clés publiques JWT (Convex Auth) | ✅ set | ⚠️ régénérer |
83+
| `AUTH_RESEND_KEY` | API key Resend pour magic-link auth | `re_LuzFTSdt_...` | ⚠️ clé live Resend distincte |
84+
| `SITE_URL` | URL canonique du site (links emails) | `http://localhost:3000` ⚠️ à corriger en dev aussi |`https://admin.kitchen-boost.com` |
85+
| `CONVEX_SITE_URL` | URL `.convex.site` (httpAction host). **Auto-set par Convex**, jamais à fournir manuellement — utilisée par `auth.config.ts` JWT iss. | ✅ auto | ✅ auto |
86+
| `IS_DEV` | Flag dev (active la branche `[DEV] console.log` dans `ResendOTP` au lieu d'envoyer l'email Resend, etc.) | `true` | `false` ou absent |
8687

8788
### Stripe
8889

@@ -107,11 +108,17 @@ Setter via `npx convex env set <KEY> <VALUE>` depuis `packages/backend/`.
107108

108109
### Wallet (Apple PassKit + Google Wallet)
109110

110-
| Variable | Rôle | Dev | Prod |
111-
| ------------------------------------ | ------------------------------------------- | ----------------- | -------------------------------------------------------- |
112-
| `WALLET_PASS_CERT_P12_BASE64` | Cert Apple PassKit P12 base64 | ✅ set (cert dev) | ☐ cert prod distinct (Apple Developer Pass Type ID prod) |
113-
| `WALLET_PASS_CERT_PASSWORD` | Password du P12 | ✅ set | ☐ password prod |
114-
| `GOOGLE_WALLET_SERVICE_ACCOUNT_JSON` | Service account Google Wallet (JSON base64) | ✅ set | ☐ service account prod |
111+
| Variable | Rôle | Dev | Prod |
112+
| ------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------- | -------------------------------------------------------- |
113+
| `WALLET_PASS_CERT_P12_BASE64` | Cert Apple PassKit P12 base64 (Pass Type ID) | ✅ set (cert dev) | ☐ cert prod distinct (Apple Developer Pass Type ID prod) |
114+
| `WALLET_PASS_CERT_PASSWORD` | Password du P12 | ✅ set | ☐ password prod |
115+
| `WALLET_WWDR_CERT_BASE64` | Cert intermédiaire Apple WWDR (G4), base64. Requis pour signer chaque `.pkpass` (chaîne PKCS#7). Récupérable sur apple.com/certificateauthority. |**À set** ||
116+
| `WALLET_SAVE_ORIGINS` | Whitelist d'origines (CSV) autorisées à appeler le endpoint `/wallet/save` côté Convex. Ex : `https://test-t1.kitchen-boost.com,https://admin.kitchen-boost.com`. |**À set** ||
117+
| `WALLET_APNS_AUTH_KEY` | Apple APNs auth key (.p8 PEM contenu) pour push update de pass quand le pass change. Optionnel si on n'utilise pas les push Wallet. || ☐ (optionnel V1) |
118+
| `WALLET_APNS_KEY_ID` | Key ID associé à l'APNs auth key (Apple Developer). |||
119+
| `WALLET_APNS_TEAM_ID` | Team ID Apple Developer (pour les push APNs). |||
120+
| `GOOGLE_WALLET_SERVICE_ACCOUNT_JSON` | Service account Google Wallet (JSON base64). | ✅ set | ☐ service account prod |
121+
| `GOOGLE_WALLET_ISSUER_ID` | Issuer ID Google Wallet (numérique, ex `3388000000022000000`). Récupérable sur pay.google.com/business/console. |**À set** | ☐ issuer id prod distinct |
115122

116123
### HMAC channels Convex ↔ Vercel routes
117124

@@ -124,14 +131,22 @@ Setter via `npx convex env set <KEY> <VALUE>` depuis `packages/backend/`.
124131
| `WEB_PUSH_ROUTE_URL` | URL Vercel web `/api/push/send` | `https://test-t1.kitchen-boost.com/api/push/send` ⚠️ tenant-specific | ☐ idem |
125132
| `WALLET_PUSH_ROUTE_URL` | URL Vercel admin `/api/wallet/push` | `https://admin.kitchen-boost.com/api/wallet/push` | ✅ même URL prod |
126133

127-
### Uber Direct (à venir)
134+
### Uber Direct (per-tenant, PAS d'env vars globales)
128135

129-
| Variable | Rôle | Dev | Prod |
130-
| --------------------------- | --------------------------------- | ---------- | ---------------------- |
131-
| `UBER_DIRECT_CLIENT_ID` | OAuth client_id | ☐ (simulé) ||
132-
| `UBER_DIRECT_CLIENT_SECRET` | OAuth client_secret |||
133-
| `UBER_DIRECT_BASE_URL` | `https://api.uber.com` ou sandbox || `https://api.uber.com` |
134-
| `UBER_WEBHOOK_SIGNING_KEY` | HMAC vérif webhook entrant |||
136+
⚠️ **PAS d'env vars `UBER_DIRECT_*` à set.** Les credentials Uber Direct sont **per-tenant** (un compte Uber Direct par restaurant, cf. PRD 40 §1) et stockés **chiffrés** (envelope encryption AES-256-GCM via `KMS_MASTER_KEY` ci-dessus) dans la table `tenantCredentials`, provider `"uber_direct"`. La saisie se fait depuis l'admin :
137+
138+
- **A posteriori** : sidebar tenant → Paramètres → carte « Uber Direct » → « Configurer Uber Direct → » → formulaire 4 champs (Identifiant du client, Identifiant client, Secret client, Clé de signature webhook).
139+
- **Probe** : bouton « Tester la connexion » sur la même page → OAuth + `GET /v1/customers/<id>/deliveries` live.
140+
- **Webhook par tenant** : configuré côté Uber sur `https://<deployment>.convex.site/webhooks/uber/<tenantId>` (cf. section 6 ci-dessous).
141+
142+
Côté code, la seule URL Uber « globale » est hardcodée (`https://api.uber.com/v1` + `https://login.uber.com/oauth/v2/token`) dans `lib/uberDirect/account.ts` + `lib/delivery/*` — pas de switch sandbox/prod via env var (le sandbox Uber utilise les mêmes URLs, c'est le credential qui détermine l'environnement).
143+
144+
### Monitoring ops (optionnel mais recommandé)
145+
146+
| Variable | Rôle | Dev | Prod |
147+
| ------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- | ------------------------------------------------------------ |
148+
| `SLACK_OPS_WEBHOOK_URL` | URL webhook Slack (channel ops). Le scan `runMonitoringScan` (cron 15min) y poste : webhook latency > 30s, KYC pending > 48h, commande payée sans course Uber, chargeback Stripe. Sans = warn log silencieux. || ☐ Recommandé prod (sinon les incidents partent dans le vide) |
149+
| `MONITORING_PAID_NO_COURSE_GRACE_MS` | Override du délai de tolérance « commande payée sans course Uber créée » (défaut hardcodé dans `lib/admin/monitoring.ts`). En millisecondes. Optionnel — laisser unset garde le défaut. | ☐ unset | ☐ unset (sauf besoin de tuning ops) |
135150

136151
---
137152

0 commit comments

Comments
 (0)