Architecture overview¶
The 5-minute mental model.
Layers¶
┌──────────────────────────────────────────┐
│ Server-rendered Django templates │ ← UI today (Tailwind via CDN)
│ Will be replaced by React in Phase 3 │
├──────────────────────────────────────────┤
│ Django views (CBV + FBV mix) │
│ Forms (ModelForm) · Filters · Pagination│
├──────────────────────────────────────────┤
│ ORM models · custom managers │
│ Tenant/VRF scoping · JSONB custom_fields│
├──────────────────────────────────────────┤
│ PostgreSQL 18 │
└──────────────────────────────────────────┘
┌─────────────┐ ┌─────────────┐
│ Redis 7 │ │ RQ workers │ ← async jobs (compliance, import)
└─────────────┘ └─────────────┘ not yet wired in MVP
Two organising principles¶
1. Zero pre-filled data¶
Danbyte ships models, never data. There are no canned device types, no
default tags, no shipped compliance frameworks, no default VLAN list. Every
domain object exposes custom_fields (JSONB) for user-defined attributes and
tags for user-defined categorisation.
Before adding any seed value, default choice list, or hardcoded field, the
check is: can this be custom_fields or a user-created object instead? The
answer is almost always yes.
2. Hard isolation by Tenant + VRF¶
| Boundary | Purpose | Strictness |
|---|---|---|
| Organization | The Danbyte install owner (SaaS account) | Loose — used for billing/admin |
| Tenant | The customer / business unit | Hard — never shown together in the UI |
| VRF | The routing context inside a tenant | Hard — uniqueness is (tenant, vrf, cidr) |
| Site | The location | Soft — multiple sites within a VRF, optionally documented as Site.vrfs |
See Tenant + VRF for details.
Request lifecycle (prefix list)¶
GET /prefixes/?vrf=<uuid>&status=active
│
▼
prefixes_list(request) # api/views.py
│
├─ _get_active_tenant(request)
│ └─ session['current_tenant_id'] OR Tenant.objects.first()
│
├─ Prefix.objects.filter(tenant=tenant) # tenant scoping
│
├─ _apply_filters(qs, request.GET) # status, family, q
├─ Q(vrf=...) | Q(vrf__isnull=True) # VRF facet filter
│
├─ if sort=cidr:
│ bucket by (vrf, family)
│ stack-walk depth per bucket
│ build sections # one per VRF
│
└─ render prefixes.html
File layout¶
danbyte/
api/ # the main Django app
models.py # VRF + Site + Prefix + IPAddress + Device + …
forms.py # PrefixForm + IPAddressForm
views.py # all the server-rendered views
urls.py # /prefixes/* routing
templates/api/
_shell.html # sidebar + topbar shell (extended by every page)
_prefix_row.html # row partial used by the list table
prefixes.html
prefix_detail.html
prefix_form.html
ip_form.html
management/commands/
seed_demo.py # opt-in demo data
core/
models.py # Organization · Tenant · Tag · TaggedItem
design/ # static mockups (the design source of truth)
docs/ # this documentation
services/ # systemd user units
Makefile # dev shortcuts
zensical.toml # docs config
CLAUDE.md # design standard + project notes