88cf6458d0
Application web d'inventaire réseau manuel avec FastAPI, Vue 3 et Docker. Inclut l'authentification JWT, la découverte ICMP, et la topologie en cards CSS. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
125 lines
4.0 KiB
Markdown
125 lines
4.0 KiB
Markdown
# Data Model
|
|
|
|
## Schema Overview
|
|
|
|
```
|
|
users
|
|
id PK
|
|
username UNIQUE NOT NULL
|
|
hashed_password NOT NULL
|
|
|
|
vlans
|
|
id PK
|
|
vlan_id UNIQUE NULL ← NULL = plain LAN (no 802.1Q tag)
|
|
name NOT NULL
|
|
cidr NULL
|
|
color NULL
|
|
|
|
devices
|
|
id PK
|
|
name NOT NULL
|
|
type
|
|
description
|
|
is_gateway BOOL
|
|
is_livebox BOOL
|
|
virt_type NULL ← null | baremetal | lxc | qemu
|
|
url NULL
|
|
|
|
device_interfaces
|
|
id PK
|
|
device_id FK → devices.id NOT NULL
|
|
vlan_id FK → vlans.id NULL ← NULL = no network assignment
|
|
ip_address NULL
|
|
name
|
|
is_upstream BOOL
|
|
|
|
links
|
|
id PK
|
|
source_device_id FK → devices.id NOT NULL
|
|
target_device_id FK → devices.id NOT NULL
|
|
link_type
|
|
description
|
|
```
|
|
|
|
## Relationships
|
|
|
|
- `Device` 1 → N `DeviceInterface` (cascade delete-orphan)
|
|
- `Vlan` 1 → N `DeviceInterface` (nullable FK — deleting a VLAN sets `vlan_id` to NULL on its interfaces)
|
|
- `Link` references `Device` twice (source, target) — links are deleted explicitly in `delete_device` before removing the device
|
|
|
|
## Key Design Decisions
|
|
|
|
### `vlan_id` is nullable
|
|
|
|
A network with `vlan_id = NULL` is a plain LAN without 802.1Q tagging. This allows modelling both tagged and untagged networks in the same table. The UI distinguishes them with "LAN" vs "VLAN X" badges.
|
|
|
|
The `vlans` table was originally created with `vlan_id NOT NULL`. The migration `_migrate_vlan_nullable()` recreates it (SQLite cannot `ALTER COLUMN`).
|
|
|
|
### Interfaces as a separate table
|
|
|
|
A device can belong to multiple networks simultaneously. The `device_interfaces` table is a join table with extra attributes (IP, name, is_upstream). A device appears in every topology card that corresponds to one of its interfaces.
|
|
|
|
### `is_gateway` and `is_livebox`
|
|
|
|
These boolean flags drive the special WAN and Gateway cards in the topology view. They are independent of network membership — a gateway device can also have interfaces in various VLANs.
|
|
|
|
### No foreign key enforcement at the SQLite level
|
|
|
|
SQLAlchemy's `ForeignKey` declarations define the schema, but SQLite does not enforce FK constraints unless `PRAGMA foreign_keys=ON` is set per-connection. The application does not enable this pragma, so referential integrity is maintained by application logic (explicit deletes in the routers).
|
|
|
|
## SQLite Migrations
|
|
|
|
Migrations are idempotent Python functions that run at startup before `Base.metadata.create_all`. They check for the presence of columns or tables before acting, so they are safe to run on every container start.
|
|
|
|
Pattern for adding a nullable column:
|
|
```python
|
|
def _migrate_my_column():
|
|
with engine.connect() as conn:
|
|
if not conn.execute(text(
|
|
"SELECT name FROM sqlite_master WHERE type='table' AND name='devices'"
|
|
)).fetchone():
|
|
return
|
|
cols = [row[1] for row in conn.execute(text("PRAGMA table_info(devices)")).fetchall()]
|
|
if 'my_column' not in cols:
|
|
conn.execute(text("ALTER TABLE devices ADD COLUMN my_column VARCHAR"))
|
|
conn.commit()
|
|
```
|
|
|
|
## Device Types
|
|
|
|
18 valid values for `devices.type`:
|
|
|
|
| Value | Description |
|
|
|-------|-------------|
|
|
| `server` | Physical or virtual server |
|
|
| `switch` | Network switch |
|
|
| `router` | Network router |
|
|
| `nas` | Network-attached storage |
|
|
| `gateway` | Internet gateway / firewall |
|
|
| `livebox` | ISP-provided box (WAN) |
|
|
| `access_point` | Wi-Fi access point |
|
|
| `camera` | IP camera |
|
|
| `temperature` | Temperature sensor |
|
|
| `sensor` | Generic sensor |
|
|
| `hub` | Network hub |
|
|
| `smart_plug` | Smart power plug |
|
|
| `alarm` | Alarm system |
|
|
| `light` | Smart light |
|
|
| `doorbell` | Smart doorbell |
|
|
| `desktop` | Desktop computer |
|
|
| `laptop` | Laptop computer |
|
|
| `other` | Anything else |
|
|
|
|
`url` is hidden in the device form for `desktop` and `laptop` — these types have no web UI.
|
|
|
|
## Virtualisation Types
|
|
|
|
`devices.virt_type` valid values:
|
|
|
|
| Value | Display | Badge |
|
|
|-------|---------|-------|
|
|
| `null` | (not shown) | — |
|
|
| `baremetal` | Bare metal | — |
|
|
| `lxc` | LXC container | blue "LXC" |
|
|
| `qemu` | QEMU/KVM VM | purple "VM" |
|