betterNAS/skeleton.md
2026-04-01 04:04:04 +00:00

8.3 KiB

betterNAS Skeleton

This is the root build skeleton for the monorepo.

Its job is simple:

  • lock the repo shape
  • lock the language per runtime
  • lock the first shared contract surface
  • give agents a safe place to work in parallel
  • keep the list of upstream references we are stealing from

Repo shape

betterNAS/
├── apps/
│   ├── web/                 # Next.js control-plane UI
│   ├── control-plane/       # Go control-plane API
│   ├── node-agent/          # Go NAS runtime + WebDAV surface
│   └── nextcloud-app/       # optional Nextcloud adapter
├── packages/
│   ├── contracts/           # canonical OpenAPI, schemas, TS types
│   ├── ui/                  # shared React UI
│   ├── eslint-config/       # shared lint config
│   └── typescript-config/   # shared TS config
├── infra/
│   └── docker/             # local runtime stack
├── docs/                   # architecture and part docs
├── scripts/                # local helper scripts
├── go.work                 # Go workspace
├── turbo.json              # Turborepo task graph
└── skeleton.md             # this file

Runtime and language choices

Part Language Why
apps/web TypeScript + Next.js best UI velocity, best admin/control-plane UX
apps/control-plane Go strong concurrency, static binaries, operationally simple
apps/node-agent Go best fit for host runtime, WebDAV service, and future Nix deployment
apps/nextcloud-app PHP native language for the Nextcloud adapter surface
packages/contracts OpenAPI + JSON Schema + TypeScript language-neutral source of truth with practical TS ergonomics

Canonical contract rule

The source of truth for shared interfaces is:

  1. docs/architecture.md
  2. packages/contracts/openapi/betternas.v1.yaml
  3. packages/contracts/schemas
  4. packages/contracts/src

Agents must not invent private shared request or response shapes outside those locations.

Parallel lanes

                    shared write surface
      +-------------------------------------------+
      | docs/architecture.md                      |
      | packages/contracts/                       |
      +----------------+--------------------------+
                       |
     +-----------------+-----------------+-----------------+
     |                 |                 |                 |
     v                 v                 v                 v
  NAS node        control plane      local device      cloud layer
  lane            lane               lane              lane

Allowed ownership:

  • NAS node lane
    • apps/node-agent
    • future infra/nix/node-*
  • control-plane lane
    • apps/control-plane
    • DB and queue integration code later
  • local-device lane
    • mount docs first
    • future helper app
  • cloud layer lane
    • apps/nextcloud-app
    • Nextcloud mapping logic
  • shared contract lane
    • packages/contracts
    • docs/architecture.md

The first verification loop

[node-agent]
  serves WebDAV export
        |
        v
[control-plane]
  registers node + export
  issues mount profile
        |
        v
[local device]
  mounts WebDAV in Finder
        |
        v
[cloud layer]
  optionally exposes same export in Nextcloud

If a task does not make one of those steps more real, it is probably too early.

Upstream references to steal from

Monorepo and web

Go control plane

NAS node and WebDAV

Local device and mount UX

Cloud and adapter layer

What we steal vs what we own

Steal

  • Turborepo repo shape and task graph
  • Next.js web-app conventions
  • Go stdlib and proven Go infra libraries
  • Go WebDAV implementation
  • Finder native WebDAV mount UX
  • Nextcloud shell-app and cloud/web primitives

Own

  • the betterNAS domain model
  • the control-plane API
  • the node registration and export model
  • the mount profile model
  • the mapping between cloud mode and mount mode
  • the repo contract and shared schemas
  • the root pnpm verify loop

The first implementation slices after this scaffold

  1. make apps/node-agent serve a real configurable WebDAV export
  2. make apps/control-plane store real node/export records
  3. issue real mount profiles from the control plane
  4. make apps/web let a user pick an export and request a profile
  5. keep apps/nextcloud-app thin and optional