Files
olivier 88cf6458d0 Initial commit — Stupid Simple Network Inventory
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>
2026-05-17 09:19:19 +02:00

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" |