| Couche | Technologie |
|---|---|
| Frontend | Next.js 16, TypeScript, Tailwind CSS |
| Backend | Hono (Node.js), hono-openapi |
| Base de données | PostgreSQL 17, Drizzle ORM |
| Infra locale | Docker Compose, Traefik |
| Monorepo | npm workspaces |
- Node.js ≥ 20
- Docker et Docker Compose
# 1. Installer les dépendances
./init.sh # équivalent à : npm install
# 2. Lancer les services
./start.sh # équivalent à : docker compose up -dL'application est accessible sur http://localhost:3000. Traefik route automatiquement :
http://localhost:3000/→ frontend Next.jshttp://localhost:3000/api/→ API Honohttp://localhost:3000/api/reference→ documentation interactive (Scalar)
monorepo-basic-template/
├── docker-compose.yml # Traefik, app, api, postgres
├── packages/
│ ├── app/ # Frontend Next.js
│ │ └── lib/
│ │ ├── api.ts # Client HTTP typé
│ │ └── generated-api.ts # Types générés depuis l'OpenAPI
│ └── api/ # API Hono
│ ├── drizzle.config.ts # Config Drizzle Kit
│ ├── drizzle/ # Migrations générées
│ └── src/
│ ├── server.ts # Point d'entrée
│ ├── app.ts # Routes Hono
│ └── db/
│ ├── index.ts # Client Drizzle (db)
│ └── schema.ts # Schéma de la base de données
docker compose up api -dL'API tourne sur le port 3000 à l'intérieur du conteneur. Elle redémarre automatiquement grâce à tsx watch.
Ajouter une route :
// src/app.ts
app.get("/hello", describeRoute({ ... }), (c) => c.json({ message: "hi" }));docker compose up app -dLe client HTTP est typé à partir de la spec OpenAPI de l'API. Après avoir modifié des routes, regénérer le client :
docker compose run --rm app npm run generate:clientCette commande appelle l'API depuis le conteneur (http://api:3000/openapi), elle doit donc être exécutée avec Docker en cours d'exécution.
packages/api/.env.local :
DATABASE_URL=postgresql://postgres:postgres@postgres:5432/app- Éditer
packages/api/src/db/schema.ts - Générer la migration :
docker compose run --rm api npm run db:generate- Appliquer la migration :
docker compose run --rm api npm run db:migrateSe connecter en session interactive :
docker compose run --rm -e PGPASSWORD=postgres postgres psql -h postgres -U postgres -d appLister les tables :
docker compose run --rm -e PGPASSWORD=postgres postgres psql -h postgres -U postgres -d app -c "\dt"Inspecter une table :
docker compose run --rm -e PGPASSWORD=postgres postgres psql -h postgres -U postgres -d app -c "\d users"Exécuter une requête :
docker compose run --rm -e PGPASSWORD=postgres postgres psql -h postgres -U postgres -d app -c "SELECT * FROM users LIMIT 10;"import { db } from "../db/index.js";
import { users } from "../db/schema.js";
app.get("/users", async (c) => {
const allUsers = await db.select().from(users);
return c.json(allUsers);
});Chaque package possède son propre fichier .env.local (non versionné). Se baser sur les exemples ci-dessous pour les créer.
packages/api/.env.local
DATABASE_URL=postgresql://postgres:postgres@postgres:5432/apppackages/app/.env.local
# à compléter selon les besoins- Les commits suivent la convention Conventional Commits :
feat:,fix:,chore:, etc. - Le code TypeScript est partagé via les workspaces npm — pas de copier-coller entre packages.
- Les types du client API sont toujours générés, jamais écrits à la main.