148 lines
7.1 KiB
Markdown
148 lines
7.1 KiB
Markdown
# 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)
|