Onboarding dev
Setup complet d'un poste neuf avec la base prod importée
Objectif
Partir d'un clone vierge et arriver à une instance Reciprok qui tourne en local avec les 2790 membres issus de la prod legacy, leurs salles, capacités, tags, photos et embeddings prêts pour Maxy.
Prérequis
- Bun ≥ 1.2 (
curl -fsSL https://bun.sh/install | bash) - Docker + Docker Compose (Docker Desktop ou OrbStack sur macOS)
- macOS / Linux (Windows via WSL2 seulement)
- Accès au dépôt GitHub
Reciprok/Reciprok - Deux fichiers à demander à un mainteneur (envoyés via Drive / WeTransfer / S3 privé) :
- Le dump DB shareable :
reciprok-YYYYMMDD-HHMM-shareable.dump(~25-50 Mo) - Le tarball uploads :
reciprok-uploads-YYYYMMDD-HHMM.tar.gz(~5-15 Go, contient les ~28k photos membres migrées depuis Vercel Blob)
- Le dump DB shareable :
Procédure (15 min)
1. Cloner + installer
git clone git@github.com:Reciprok/Reciprok.git
cd Reciprok
bun install2. Variables d'environnement
Copier les templates et remplir les clés :
cp apps/server/.env.example apps/server/.env
cp apps/web/.env.example apps/web/.env.local # si présentMinimum à remplir dans apps/server/.env :
| Clé | Valeur par défaut | Obligatoire ? |
|---|---|---|
DATABASE_URL | postgresql://postgres:password@localhost:5432/reciprok | ✅ |
BETTER_AUTH_SECRET | (générer avec openssl rand -base64 32) | ✅ |
BETTER_AUTH_URL | http://localhost:3000 | ✅ |
CORS_ORIGIN | http://localhost:3001 | ✅ |
OPENAI_API_KEY | (demander à un mainteneur) | 🟡 pour Whisper + embeddings réels |
ANTHROPIC_API_KEY | (demander à un mainteneur) | 🟡 pour Maxy, sinon mock |
AI_WRITE_TOOLS_ENABLED | true | 🟡 mettre false si tu veux Maxy en lecture seule |
3. Démarrer les conteneurs
bun run docker:upÇa démarre :
- Postgres 18 + pgvector (port 5432)
- RustFS (S3-compatible, ports 9000/9001)
- Reacher (email verify, port 8080)
- Signoz (observabilité, UI sur http://localhost:8080, désactivable)
4. Charger les données
Trois chemins possibles selon ce que tu as sous la main.
🚀 Chemin A, Dump shareable + uploads (recommandé)
Le chemin standard quand un collègue te transmet sa DB. Le dump
shareable contient toutes les données métier (membres, demandes,
catalogues, organisateurs, tags, pools, attributs, KB, embeddings…)
sauf les tables user-scoped (sessions, comptes Better Auth,
notifications push, conversations IA, tickets), celles-là sont
recréées vides chez toi via db:push.
Tu reçois deux fichiers d'un mainteneur (via Drive / WeTransfer / S3 privé, jamais par git) :
reciprok-YYYYMMDD-HHMM-shareable.dump ~25-50 Mo
reciprok-uploads-YYYYMMDD-HHMM.tar.gz ~5-15 Go (28k photos membres)Pose-les n'importe où sur ton disque, puis :
# 1. Stack Docker locale (si pas déjà fait)
bun run docker:up
bun run db:setup # extension pgvector (1ʳᵉ fois)
# 2. Schéma à jour (crée AUSSI les tables exclues du shareable)
bun run db:push
# 3. Restore du dump métier
FORCE=1 bun run db:import ~/Downloads/reciprok-YYYYMMDD-HHMM-shareable.dump
# 4. Restore des uploads dans le bucket RustFS local
bun run db:import-uploads ~/Downloads/reciprok-uploads-YYYYMMDD-HHMM.tar.gzLes deux scripts passent par docker exec pour éviter les problèmes
de version client/serveur. Compte ~1 min pour la DB, 2-5 min pour
les uploads selon ta connexion.
Si tu as déjà des données de test dans ta DB, le
db:importles wipe avant restore. Pas de surprise sansFORCE=1, par défaut, le script affiche juste un preview (quelle DB, quel fichier).
🛠 Chemin B, Bootstrap from scratch depuis l'export legacy Prisma
Plus long, utile si tu n'as ni dump Postgres ni tarball uploads,
seulement l'export JSON legacy. Un mainteneur te fournit un dossier à
extraire dans ~/exports/prod-latest/.
mkdir -p ~/exports
# extraire le zip fourni dans ~/exports/prod-latest/
ls ~/exports/prod-latest/ # doit contenir les *.json de chaque table
bun run db:setup # extension pgvector (1ʳᵉ fois)
bun run db:bootstrap-prodLe bootstrap enchaîne, dans l'ordre :
db:push, applique le schéma Drizzledb:import-prod, charge les 6905 membres depuis~/exports/prod-latest/db:dedupe-members, fusionne les doublons → 2790 membres uniquesdb:backfill-capacities, créeroom_capacity+Salle principalepour les orphelins (30 000 rows générées)db:seed-tags, 79 tags standards (Type/Ambiance/Service/Cuisine/Autre)
Le script est idempotent, si une étape échoue, corrige et relance, les étapes déjà passées ne dupliquent rien. Il fait un pre-flight check des variables d'env, de la connexion postgres et de l'extension pgvector et te dit exactement ce qui manque.
DRY_RUN=1 bun run db:bootstrap-prod # preview sans rien écrireLe chemin B ne ramène pas les photos uploadées (Vercel Blob legacy). Si tu en as besoin, demande à un mainteneur le tarball uploads et applique l'étape 4 du chemin A en complément.
🌱 Chemin C, Seed faker (jeu de démo, sans données réelles)
Si tu veux juste explorer sans charger de prod :
bun run db:setup
bun run db:push
bun run db:seed # 30 membres, 90 photos Pexels, 13 catalogues, etc.Idempotent, ~30 s. Suffisant pour la dev sur des features qui ne dépendent pas du volume réel.
Comment un mainteneur produit ces fichiers pour les partager ?
# Dump DB shareable (sans tables user-scoped)
SHAREABLE=1 bun run db:export
# → ./db-dumps/reciprok-YYYYMMDD-HHMM-shareable.dump
# Tarball des uploads (volume RustFS dev)
bun run db:export-uploads
# → ./db-dumps/reciprok-uploads-YYYYMMDD-HHMM.tar.gzLes deux fichiers sortent dans db-dumps/ qui est gitignoré. Un
mainteneur les envoie ensuite via Drive / WeTransfer / S3 privé,
jamais via git, ils contiennent des emails clients et des
centaines de Mo de photos.
6. (Optionnel) Embeddings sémantiques
Si OPENAI_API_KEY est configurée :
bun run embeddings:refreshCela calcule les embeddings pgvector des 2790 membres + knowledge base.
Coût estimé : ~10¢ avec text-embedding-3-small (1536 dim). Sans clé,
les embeddings mock suffisent pour la démo mais le ranking sémantique sera
faible.
7. Démarrer
bun run dev- Server : http://localhost:3000
- Web : http://localhost:3001
- Fumadocs :
bun run dev:docs→ http://localhost:4000
Compte team par défaut : voir section Auth dans la doc.
Vérifier que tout marche
# Depuis la web UI :
# 1. /dashboard affiche les stats (≥2700 membres, ≥40 demandes)
# 2. /tags affiche 5 catégories remplies
# 3. /chat → "Combien de demandes en cours ?" → Maxy appelle list_requests
# 4. /requests/[id] → bouton "Discuter avec Maxy" → test d'un search_membersProblèmes courants
db:bootstrap-prod échoue sur l'étape import-prod
Check ls ~/exports/prod-latest/, le dossier doit exister et contenir les
exports JSON. Sinon demande-les à un mainteneur.
Maxy répond "mocked" systématiquement
ANTHROPIC_API_KEY manquante dans apps/server/.env. Redémarre le server
après avoir ajouté la clé.
Whisper ne transcrit pas
OPENAI_API_KEY manquante. Le hook front catche gracieusement les 404/501
et affiche "pas encore branché", pas de crash.
0 résultat sur toutes les recherches
Les capacités ne sont pas backfillées. Relance :
bun run db:backfill-capacitiesPools "Rooftop", "Péniche" (etc.) affichent 0 membres
Normal, ce sont des pools legacy d'une ancienne taxonomie. À nettoyer un jour (ticket à créer).
Aller plus loin
- Architecture, entités, IA, infra
- Environnements, dev / staging / prod
- Coûts IA, pricing Claude + optimisations
- RGPD, export / suppression membres