Reciprok Docs

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)

Procédure (15 min)

1. Cloner + installer

git clone git@github.com:Reciprok/Reciprok.git
cd Reciprok
bun install

2. 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ésent

Minimum à remplir dans apps/server/.env :

CléValeur par défautObligatoire ?
DATABASE_URLpostgresql://postgres:password@localhost:5432/reciprok
BETTER_AUTH_SECRET(générer avec openssl rand -base64 32)
BETTER_AUTH_URLhttp://localhost:3000
CORS_ORIGINhttp://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_ENABLEDtrue🟡 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.gz

Les 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:import les wipe avant restore. Pas de surprise sans FORCE=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-prod

Le bootstrap enchaîne, dans l'ordre :

  1. db:push, applique le schéma Drizzle
  2. db:import-prod, charge les 6905 membres depuis ~/exports/prod-latest/
  3. db:dedupe-members, fusionne les doublons → 2790 membres uniques
  4. db:backfill-capacities, crée room_capacity + Salle principale pour les orphelins (30 000 rows générées)
  5. 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 écrire

Le 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.gz

Les 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:refresh

Cela 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

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_members

Problè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-capacities

Pools "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

On this page