first commit
This commit is contained in:
147
ARCHITECTURE.md
Normal file
147
ARCHITECTURE.md
Normal file
@@ -0,0 +1,147 @@
|
||||
# Architecture
|
||||
|
||||
Ce document décrit la structure du projet et les principes qui la gouvernent,
|
||||
afin de garder l'application **évolutive** (facile à étendre, sans dette).
|
||||
|
||||
## Principes
|
||||
|
||||
1. **Modular monolith** — un seul projet Next.js, mais des modules métier isolés
|
||||
sous `src/modules/<domaine>/`. Chaque module expose son `service` ; les routes
|
||||
API et l'UI n'accèdent JAMAIS directement à Prisma pour un domaine.
|
||||
2. **Validation à la frontière** — tout input externe (API, formulaire, scanner)
|
||||
est validé via un schéma Zod avant d'atteindre le service.
|
||||
3. **Registry pattern** pour les scanners — ajouter une capacité de découverte se
|
||||
fait en implémentant une interface `Scanner` et en l'enregistrant dans le
|
||||
registre (aucune autre partie du code n'est touchée).
|
||||
4. **DB-agnostic** — Prisma lit `DATABASE_PROVIDER` et `DATABASE_URL` à l'exécution ;
|
||||
SQLite pour commencer, PostgreSQL plus tard sans refactor.
|
||||
|
||||
## Arborescence
|
||||
|
||||
```
|
||||
IPAM/
|
||||
├── docker/ Dockerfile + docker-compose (profils sqlite/postgres)
|
||||
├── prisma/
|
||||
│ ├── schema.prisma Modèle de données (Network, Host, Port, Application, Scan)
|
||||
│ ├── migrations/ Migrations SQL (créées par `db:migrate`)
|
||||
│ └── seed.ts Données d'exemple
|
||||
├── public/ Assets statiques
|
||||
├── scripts/
|
||||
│ └── run-discovery.ts CLI pour lancer une découverte hors UI
|
||||
├── src/
|
||||
│ ├── app/ Next.js App Router
|
||||
│ │ ├── (dashboard)/ Route group → layout UI commun (sidebar, header)
|
||||
│ │ │ ├── hosts/ Pages de gestion des hôtes
|
||||
│ │ │ ├── networks/
|
||||
│ │ │ ├── applications/
|
||||
│ │ │ ├── scans/
|
||||
│ │ │ └── settings/
|
||||
│ │ ├── api/ Route Handlers — FINS, délèguent aux services
|
||||
│ │ │ ├── hosts/
|
||||
│ │ │ ├── networks/
|
||||
│ │ │ ├── applications/
|
||||
│ │ │ ├── ports/
|
||||
│ │ │ ├── scans/
|
||||
│ │ │ └── discovery/
|
||||
│ │ ├── layout.tsx
|
||||
│ │ └── page.tsx
|
||||
│ │
|
||||
│ ├── components/ Composants React
|
||||
│ │ ├── ui/ Primitives (Button, Input, Dialog...)
|
||||
│ │ ├── layout/ Sidebar, Header, Shell
|
||||
│ │ ├── hosts/ networks/ ... Composants spécifiques par domaine
|
||||
│ │ └── common/ Composants réutilisables (DataTable, Skeleton...)
|
||||
│ │
|
||||
│ ├── modules/ ★ Cœur métier — UN DOSSIER PAR DOMAINE
|
||||
│ │ ├── hosts/
|
||||
│ │ │ ├── hosts.schema.ts Validation Zod + types
|
||||
│ │ │ ├── hosts.repository.ts Accès Prisma (seule frontière avec la DB)
|
||||
│ │ │ ├── hosts.service.ts Logique métier
|
||||
│ │ │ └── index.ts
|
||||
│ │ ├── networks/
|
||||
│ │ ├── applications/
|
||||
│ │ ├── ports/
|
||||
│ │ ├── scans/
|
||||
│ │ └── discovery/ ★ Découverte réseau (pluggable)
|
||||
│ │ ├── types.ts Interface `Scanner` + types résultats
|
||||
│ │ ├── registry.ts Enregistrement des scanners
|
||||
│ │ ├── discovery.service.ts Orchestrateur (persiste en DB)
|
||||
│ │ ├── scanners/
|
||||
│ │ │ ├── ping.scanner.ts
|
||||
│ │ │ ├── port.scanner.ts
|
||||
│ │ │ ├── arp.scanner.ts
|
||||
│ │ │ └── mdns.scanner.ts
|
||||
│ │ └── utils/
|
||||
│ │ └── concurrency.ts Runner parallèle borné
|
||||
│ │
|
||||
│ ├── lib/ Utilitaires transverses
|
||||
│ │ ├── db/prisma.ts Client Prisma (singleton)
|
||||
│ │ ├── api/response.ts Helpers NextResponse (ok/badRequest/...)
|
||||
│ │ ├── utils/cn.ts Merge classes Tailwind
|
||||
│ │ └── utils/logger.ts Pino logger configuré
|
||||
│ │
|
||||
│ ├── config/env.ts Env vars typées via Zod (fail-fast)
|
||||
│ ├── hooks/ Hooks React partagés (ex: useHosts)
|
||||
│ ├── types/ Types globaux
|
||||
│ └── styles/globals.css Tailwind + variables de thème
|
||||
│
|
||||
├── tests/ Unitaires + intégration (vitest)
|
||||
├── .env.example
|
||||
├── next.config.mjs output: standalone + ext pkgs réseau
|
||||
├── tsconfig.json Aliases @/modules, @/lib, @/components…
|
||||
└── tailwind.config.ts
|
||||
```
|
||||
|
||||
## Flux d'une requête
|
||||
|
||||
```
|
||||
Client (RSC ou fetch)
|
||||
→ src/app/api/<domaine>/route.ts (validation + handleError)
|
||||
→ src/modules/<domaine>/service.ts (règles métier)
|
||||
→ src/modules/<domaine>/repository (Prisma)
|
||||
→ DB (SQLite | PostgreSQL)
|
||||
```
|
||||
|
||||
## Ajouter un module métier (ex: VLAN)
|
||||
|
||||
1. Créer `src/modules/vlans/` avec `vlans.schema.ts`, `vlans.service.ts`, `index.ts`
|
||||
2. Ajouter le modèle Prisma dans `prisma/schema.prisma` → `npm run db:migrate`
|
||||
3. Créer les routes `src/app/api/vlans/route.ts` (et `[id]/route.ts`) — copier le pattern des hôtes
|
||||
4. Créer la page `src/app/(dashboard)/vlans/page.tsx`
|
||||
5. (Optionnel) Ajouter des composants UI dans `src/components/vlans/`
|
||||
|
||||
Aucun fichier existant ne doit être modifié en dehors de `schema.prisma`.
|
||||
|
||||
## Ajouter un scanner de découverte (ex: SNMP)
|
||||
|
||||
1. Créer `src/modules/discovery/scanners/snmp.scanner.ts` exportant une constante
|
||||
conforme à l'interface `Scanner` (`kind`, `label`, `enabled`, `run`)
|
||||
2. L'importer dans `src/modules/discovery/registry.ts` et l'ajouter au
|
||||
`scannersRegistry` avec sa clé `ScannerKind` (mettre à jour le type union dans
|
||||
`types.ts`)
|
||||
3. Exposer la clé dans `bodySchema` de `src/app/api/discovery/route.ts`
|
||||
|
||||
Il sera automatiquement disponible dans `runSingle()` et, si intégré à
|
||||
`runFull()`, dans le scan complet.
|
||||
|
||||
## Choix techniques clefs
|
||||
|
||||
- **Prisma plutôt que Drizzle** : meilleures migrations pour un homelab, Studio
|
||||
inclus. Drizzle serait envisageable plus tard si on a besoin de SQL brut.
|
||||
- **App Router (pas Pages Router)** : server components, streaming, server
|
||||
actions disponibles quand on voudra simplifier des formulaires.
|
||||
- **Pas de framework "d'auth" pour l'instant** : ajouter NextAuth/Auth.js quand
|
||||
on exposera l'IPAM au-delà du LAN. Un emplacement naturel : `src/modules/auth/`.
|
||||
- **Pas de Redis/queue** : tous les scans tournent dans le process. À prévoir
|
||||
(BullMQ + Redis) uniquement si on planifie des scans récurrents lourds.
|
||||
|
||||
## Futures fonctionnalités envisagées
|
||||
|
||||
- Scans planifiés (cron-like, via BullMQ ou `node-cron`)
|
||||
- Notifications (nouvel hôte, port qui change d'état)
|
||||
- Export CSV / JSON des inventaires
|
||||
- Synchronisation avec un reverse-proxy (Traefik, Nginx Proxy Manager) pour
|
||||
auto-remplir les applications
|
||||
- API d'OUI lookup pour déduire le constructeur depuis la MAC
|
||||
- Authentification multi-utilisateur + RBAC
|
||||
- Topologie graphique (D3 ou React Flow)
|
||||
Reference in New Issue
Block a user