6.1 KiB
betterNAS Architecture Contract
This file is the canonical contract for the repository.
If the planning docs, scaffold code, or future tasks disagree, this file and
packages/contracts
win.
The single first task
Before splitting work across agents, do one foundation task:
- scaffold the four product parts
- lock the shared contracts
- define one end-to-end verification loop
- enforce clear ownership boundaries
That first task should leave the repo in a state where later work can be parallelized without interface drift.
The four parts
betterNAS canonical contract
[2] control plane
+-----------------------------------+
| system of record |
| users / devices / nodes / grants |
| mount profiles / cloud profiles |
+---------+---------------+---------+
| |
control/API | | cloud adapter
v v
[1] NAS node [4] cloud / web layer
+-------------------+ +----------------------+
| WebDAV + node | | Nextcloud adapter |
| real file bytes | | browser / mobile |
+---------+---------+ +----------+-----------+
| ^
| mount profile |
v |
[3] local device --------------+
+----------------------+
| Finder mount/helper |
| native user entry |
+----------------------+
Non-negotiable rules
- The control plane is the system of record.
- File bytes should flow as directly as possible between the NAS node and the local device.
- The control plane should issue policy, grants, and profiles. It should not become the default file proxy.
- The NAS node should serve WebDAV directly whenever possible.
- The local device consumes mount profiles. It does not hardcode infra details.
- The cloud/web layer is optional and secondary. Nextcloud is an adapter, not the product center.
Canonical sources of truth
Use these in this order:
docs/architecture.mdfor boundaries, ownership, and delivery rulespackages/contractsfor machine-readable types, schemas, and route constants- the part docs for local detail:
Repo lanes
The monorepo is split into these primary implementation lanes:
Every parallel task should primarily stay inside one of those lanes unless it is an explicit contract task.
The contract surface we need first
The first shared contract set should cover only the seams that let all four parts exist at once.
NAS node -> control plane
- node registration
- node heartbeat
- export inventory
Local device -> control plane
- list allowed exports
- issue mount profile
Cloud/web layer -> control plane
- issue cloud profile
- read export metadata
Control plane internal
- health
- version
- the first domain entities:
NasNodeStorageExportAccessGrantMountProfileCloudProfile
Parallel work boundaries
Each area gets an owner and a narrow write surface.
| Part | Owns | May read | Must not own |
|---|---|---|---|
| NAS node | node runtime, export reporting, WebDAV config | contracts, control-plane docs | product policy |
| Control plane | domain model, grants, profile issuance, registry | everything | direct file serving by default |
| Local device | mount UX, helper flows, credential handling | contracts, control-plane docs | access policy |
| Cloud/web layer | Nextcloud adapter, browser/mobile integration | contracts, control-plane docs | source of truth |
The only shared write surface across teams should be:
packages/contracts- this file when the architecture contract changes
Verification loop
This is the first loop every scaffold and agent should target.
[1] mock or real NAS node exposes a WebDAV export
-> [2] control plane registers the node and export
-> [3] local device asks for a mount profile
-> [3] local device receives a WebDAV mount URL
-> user can mount the export in Finder
-> [4] optional cloud/web layer can expose the same export in cloud mode
If a task does not help one of those steps become real, it is probably too early.
Definition of done for the foundation scaffold
The initial scaffold is complete when:
- all four parts have a documented entry point
- the control plane can represent nodes, exports, grants, and profiles
- the contracts package exports the first shared shapes and schemas
- local verification can prove the mount-profile loop end to end
- future agents can work inside one part without inventing new interfaces
Rules for future tasks and agents
- No part may invent private request or response shapes for shared flows.
- Contract changes must update
packages/contractsfirst. - Architecture changes must update this file in the same change.
- Additive contract changes are preferred over breaking ones.
- New tasks should target one part at a time unless they are explicitly contract tasks.