Vue d'ensemble
Les applications, les packages partagés et les décisions d'architecture pensées pour l'échelle.
Le monorepo en un schéma
Le client web est la cible prioritaire, sous forme de PWA. L'application native Expo existe mais reste gelée tant que le web n'a pas atteint le périmètre du MVP, pour ne pas imposer la maintenance de deux clients à une personne seule.
Les applications
| Application | Rôle | État |
|---|---|---|
apps/server | API Elysia sur Bun, montage de l'authentification, futures macros de sécurité | Squelette, auth câblée |
apps/web | Client web Next.js (App Router), PWA | Scaffold, manifest posé |
apps/native | Application mobile Expo | Gelée pour le MVP |
apps/fumadocs | Site de documentation | Actif, ce site |
Un apps/worker est prévu pour consommer une file de jobs (transcodage vidéo, scan des médias, détection d'acharnement, fan-out du fil). Il n'est pas encore créé.
Les packages partagés
| Package | Rôle |
|---|---|
packages/db | Schéma Drizzle, migrations et accès PostgreSQL |
packages/core | Logique métier pure, testable en isolation |
packages/auth | Configuration Better Auth partagée |
packages/ui | Composants partagés, sur coss et Base UI |
packages/env | Validation des variables d'environnement avec Zod |
Le schéma de packages/db est découpé en modules : identity, content, social, safety, notifications. Le package packages/core contient déjà une première brique testée de la logique de modération, le calcul de priorité d'un signalement.
Les décisions pensées pour l'échelle
Ces choix coûtent cher à défaire plus tard, ils sont donc pris dès maintenant, même si le déploiement initial tient sur un seul VPS.
| Décision | Bénéfice |
|---|---|
| Services stateless | L'état vit dans PostgreSQL, Redis ou le stockage objet, jamais dans le process |
| Asynchrone via file de jobs | Le worker se scale indépendamment, une vidéo ne bloque jamais une requête web |
| Stockage objet dès le départ | Aucun fichier utilisateur sur le disque de l'application, choix réversible via l'API S3 |
| Identifiants ULID | Triables dans le temps, adaptés à la pagination par curseur et à un futur sharding |
| Observabilité intégrée | OpenTelemetry dès le début, sinon on est aveugle à la montée en charge |
La fédération type ActivityPub n'est pas au périmètre du MVP, mais le modèle de contenu est pensé pour ne pas fermer cette porte.