mirror of
https://github.com/harivansh-afk/betterNAS.git
synced 2026-04-17 10:02:23 +00:00
skeleton schemas
This commit is contained in:
parent
0032487ca1
commit
4f174ec3a8
9 changed files with 470 additions and 42 deletions
23
README.md
23
README.md
|
|
@ -2,10 +2,23 @@
|
||||||
|
|
||||||
<img width="723" height="354" alt="image" src="https://github.com/user-attachments/assets/4e64fa91-315b-4a31-b191-d54ed1862ff7" />
|
<img width="723" height="354" alt="image" src="https://github.com/user-attachments/assets/4e64fa91-315b-4a31-b191-d54ed1862ff7" />
|
||||||
|
|
||||||
## Architecture
|
## Start here
|
||||||
|
|
||||||
The intended boundary is documented in `docs/architecture.md`. The short version is:
|
The canonical repo contract lives in [docs/architecture.md](/home/rathi/Documents/GitHub/betterNAS/docs/architecture.md).
|
||||||
|
|
||||||
- Nextcloud remains an upstream storage and client-compatibility backend.
|
Read these in order:
|
||||||
- The custom Nextcloud app is a shell and adapter layer.
|
|
||||||
- betterNAS business logic lives in the control-plane service.
|
1. [docs/architecture.md](/home/rathi/Documents/GitHub/betterNAS/docs/architecture.md)
|
||||||
|
2. [docs/01-nas-node.md](/home/rathi/Documents/GitHub/betterNAS/docs/01-nas-node.md)
|
||||||
|
3. [docs/02-control-plane.md](/home/rathi/Documents/GitHub/betterNAS/docs/02-control-plane.md)
|
||||||
|
4. [docs/03-local-device.md](/home/rathi/Documents/GitHub/betterNAS/docs/03-local-device.md)
|
||||||
|
5. [docs/04-cloud-web-layer.md](/home/rathi/Documents/GitHub/betterNAS/docs/04-cloud-web-layer.md)
|
||||||
|
6. [docs/05-build-plan.md](/home/rathi/Documents/GitHub/betterNAS/docs/05-build-plan.md)
|
||||||
|
7. [docs/references.md](/home/rathi/Documents/GitHub/betterNAS/docs/references.md)
|
||||||
|
|
||||||
|
## Current direction
|
||||||
|
|
||||||
|
- betterNAS is WebDAV-first for mount mode.
|
||||||
|
- the control plane is the system of record.
|
||||||
|
- the NAS node serves bytes directly whenever possible.
|
||||||
|
- Nextcloud is an optional cloud/web adapter, not the product center.
|
||||||
|
|
|
||||||
|
|
@ -1,54 +1,160 @@
|
||||||
# betterNAS Architecture Boundary
|
# betterNAS Architecture Contract
|
||||||
|
|
||||||
## Core Decision
|
This file is the canonical contract for the repository.
|
||||||
|
|
||||||
betterNAS treats Nextcloud as an upstream backend, not as the place where betterNAS product logic should accumulate.
|
If the planning docs, scaffold code, or future tasks disagree, this file and
|
||||||
|
[`packages/contracts`](/home/rathi/Documents/GitHub/betterNAS/packages/contracts)
|
||||||
|
win.
|
||||||
|
|
||||||
That leads to three explicit boundaries:
|
## The single first task
|
||||||
|
|
||||||
1. `apps/betternascontrolplane/` is a thin shell inside Nextcloud.
|
Before splitting work across agents, do one foundation task:
|
||||||
2. `exapps/control-plane/` owns betterNAS business logic and internal APIs.
|
|
||||||
3. `packages/contracts/` defines the interface between the shell app and the control plane.
|
|
||||||
|
|
||||||
## Why This Boundary Exists
|
- scaffold the four product parts
|
||||||
|
- lock the shared contracts
|
||||||
|
- define one end-to-end verification loop
|
||||||
|
- enforce clear ownership boundaries
|
||||||
|
|
||||||
Forking `nextcloud/server` would force betterNAS to own upstream patching and compatibility work too early. Pushing betterNAS logic into a traditional Nextcloud app would make the product harder to evolve outside the PHP monolith. The scaffold in this repository is designed to avoid both traps.
|
That first task should leave the repo in a state where later work can be
|
||||||
|
parallelized without interface drift.
|
||||||
|
|
||||||
## Responsibilities
|
## The four parts
|
||||||
|
|
||||||
### Nextcloud shell app
|
```text
|
||||||
|
betterNAS canonical contract
|
||||||
|
|
||||||
The shell app is responsible for:
|
[2] control plane
|
||||||
- navigation entries
|
+-----------------------------------+
|
||||||
- branded entry pages inside Nextcloud
|
| system of record |
|
||||||
- admin-facing integration surfaces
|
| users / devices / nodes / grants |
|
||||||
- adapter calls into the betterNAS control plane
|
| 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 |
|
||||||
|
+----------------------+
|
||||||
|
```
|
||||||
|
|
||||||
The shell app is not responsible for:
|
## Non-negotiable rules
|
||||||
- storage policy rules
|
|
||||||
- orchestration logic
|
|
||||||
- betterNAS-native RBAC decisions
|
|
||||||
- product workflows that may later be reused by desktop, iOS, or standalone web clients
|
|
||||||
|
|
||||||
### Control-plane service
|
1. The control plane is the system of record.
|
||||||
|
2. File bytes should flow as directly as possible between the NAS node and the
|
||||||
|
local device.
|
||||||
|
3. The control plane should issue policy, grants, and profiles. It should not
|
||||||
|
become the default file proxy.
|
||||||
|
4. The NAS node should serve WebDAV directly whenever possible.
|
||||||
|
5. The local device consumes mount profiles. It does not hardcode infra details.
|
||||||
|
6. The cloud/web layer is optional and secondary. Nextcloud is an adapter, not
|
||||||
|
the product center.
|
||||||
|
|
||||||
The control plane is responsible for:
|
## Canonical sources of truth
|
||||||
- domain logic
|
|
||||||
- policy decisions
|
|
||||||
- internal APIs consumed by betterNAS surfaces
|
|
||||||
- Nextcloud integration adapters kept at the service boundary
|
|
||||||
|
|
||||||
### Shared contracts
|
Use these in this order:
|
||||||
|
|
||||||
Contracts live in `packages/contracts/` so request and response shapes do not get duplicated between PHP and TypeScript codebases.
|
1. [`docs/architecture.md`](/home/rathi/Documents/GitHub/betterNAS/docs/architecture.md)
|
||||||
|
for boundaries, ownership, and delivery rules
|
||||||
|
2. [`packages/contracts`](/home/rathi/Documents/GitHub/betterNAS/packages/contracts)
|
||||||
|
for machine-readable types, schemas, and route constants
|
||||||
|
3. the part docs for local detail:
|
||||||
|
- [`docs/01-nas-node.md`](/home/rathi/Documents/GitHub/betterNAS/docs/01-nas-node.md)
|
||||||
|
- [`docs/02-control-plane.md`](/home/rathi/Documents/GitHub/betterNAS/docs/02-control-plane.md)
|
||||||
|
- [`docs/03-local-device.md`](/home/rathi/Documents/GitHub/betterNAS/docs/03-local-device.md)
|
||||||
|
- [`docs/04-cloud-web-layer.md`](/home/rathi/Documents/GitHub/betterNAS/docs/04-cloud-web-layer.md)
|
||||||
|
- [`docs/05-build-plan.md`](/home/rathi/Documents/GitHub/betterNAS/docs/05-build-plan.md)
|
||||||
|
|
||||||
## Local Runtime
|
## The contract surface we need first
|
||||||
|
|
||||||
The local development stack uses Docker Compose so developers can bring up:
|
The first shared contract set should cover only the seams that let all four
|
||||||
- Nextcloud
|
parts exist at once.
|
||||||
- PostgreSQL
|
|
||||||
- Redis
|
|
||||||
- the betterNAS control-plane service
|
|
||||||
|
|
||||||
The Nextcloud shell app is mounted as a custom app and enabled through `./scripts/dev-up`.
|
### 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:
|
||||||
|
- `NasNode`
|
||||||
|
- `StorageExport`
|
||||||
|
- `AccessGrant`
|
||||||
|
- `MountProfile`
|
||||||
|
- `CloudProfile`
|
||||||
|
|
||||||
|
## 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`](/home/rathi/Documents/GitHub/betterNAS/packages/contracts)
|
||||||
|
- this file when the architecture contract changes
|
||||||
|
|
||||||
|
## Verification loop
|
||||||
|
|
||||||
|
This is the first loop every scaffold and agent should target.
|
||||||
|
|
||||||
|
```text
|
||||||
|
[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
|
||||||
|
|
||||||
|
1. No part may invent private request or response shapes for shared flows.
|
||||||
|
2. Contract changes must update
|
||||||
|
[`packages/contracts`](/home/rathi/Documents/GitHub/betterNAS/packages/contracts)
|
||||||
|
first.
|
||||||
|
3. Architecture changes must update this file in the same change.
|
||||||
|
4. Additive contract changes are preferred over breaking ones.
|
||||||
|
5. New tasks should target one part at a time unless they are explicitly
|
||||||
|
contract tasks.
|
||||||
|
|
|
||||||
42
packages/contracts/README.md
Normal file
42
packages/contracts/README.md
Normal file
|
|
@ -0,0 +1,42 @@
|
||||||
|
# `@betternas/contracts`
|
||||||
|
|
||||||
|
This package is the machine-readable source of truth for shared interfaces in
|
||||||
|
betterNAS.
|
||||||
|
|
||||||
|
Use it to keep the four product parts aligned:
|
||||||
|
|
||||||
|
- NAS node
|
||||||
|
- control plane
|
||||||
|
- local device
|
||||||
|
- cloud/web layer
|
||||||
|
|
||||||
|
## What belongs here
|
||||||
|
|
||||||
|
- shared TypeScript types
|
||||||
|
- route constants
|
||||||
|
- JSON schemas for payloads we want to validate outside TypeScript
|
||||||
|
|
||||||
|
## What does not belong here
|
||||||
|
|
||||||
|
- business logic
|
||||||
|
- per-service config
|
||||||
|
- implementation-specific helpers
|
||||||
|
|
||||||
|
## Current contract layers
|
||||||
|
|
||||||
|
- [`src/control-plane.ts`](/home/rathi/Documents/GitHub/betterNAS/packages/contracts/src/control-plane.ts)
|
||||||
|
- current runtime scaffold for health and version
|
||||||
|
- [`src/foundation.ts`](/home/rathi/Documents/GitHub/betterNAS/packages/contracts/src/foundation.ts)
|
||||||
|
- first product-level entities and route constants for node, mount, and cloud flows
|
||||||
|
- [`schemas/`](/home/rathi/Documents/GitHub/betterNAS/packages/contracts/schemas)
|
||||||
|
- JSON schema mirrors for the first shared entities
|
||||||
|
|
||||||
|
## Change rules
|
||||||
|
|
||||||
|
1. Shared API shape changes happen here first.
|
||||||
|
2. If the boundary changes, also update
|
||||||
|
[`docs/architecture.md`](/home/rathi/Documents/GitHub/betterNAS/docs/architecture.md).
|
||||||
|
3. Prefer additive changes until all four parts are live.
|
||||||
|
4. Do not put Nextcloud-only assumptions into the core contracts unless the
|
||||||
|
field is explicitly part of the cloud adapter.
|
||||||
|
5. Keep the first version narrow. Over-modeling early is another form of drift.
|
||||||
30
packages/contracts/schemas/cloud-profile.schema.json
Normal file
30
packages/contracts/schemas/cloud-profile.schema.json
Normal file
|
|
@ -0,0 +1,30 @@
|
||||||
|
{
|
||||||
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||||
|
"$id": "https://betternas.local/schemas/cloud-profile.schema.json",
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": false,
|
||||||
|
"required": [
|
||||||
|
"id",
|
||||||
|
"exportId",
|
||||||
|
"provider",
|
||||||
|
"baseUrl",
|
||||||
|
"path"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"id": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"exportId": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"provider": {
|
||||||
|
"const": "nextcloud"
|
||||||
|
},
|
||||||
|
"baseUrl": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"path": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
41
packages/contracts/schemas/mount-profile.schema.json
Normal file
41
packages/contracts/schemas/mount-profile.schema.json
Normal file
|
|
@ -0,0 +1,41 @@
|
||||||
|
{
|
||||||
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||||
|
"$id": "https://betternas.local/schemas/mount-profile.schema.json",
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": false,
|
||||||
|
"required": [
|
||||||
|
"id",
|
||||||
|
"exportId",
|
||||||
|
"protocol",
|
||||||
|
"displayName",
|
||||||
|
"mountUrl",
|
||||||
|
"readonly",
|
||||||
|
"credentialMode"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"id": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"exportId": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"protocol": {
|
||||||
|
"const": "webdav"
|
||||||
|
},
|
||||||
|
"displayName": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"mountUrl": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"readonly": {
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
|
"credentialMode": {
|
||||||
|
"enum": [
|
||||||
|
"session-token",
|
||||||
|
"app-password"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
52
packages/contracts/schemas/nas-node.schema.json
Normal file
52
packages/contracts/schemas/nas-node.schema.json
Normal file
|
|
@ -0,0 +1,52 @@
|
||||||
|
{
|
||||||
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||||
|
"$id": "https://betternas.local/schemas/nas-node.schema.json",
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": false,
|
||||||
|
"required": [
|
||||||
|
"id",
|
||||||
|
"machineId",
|
||||||
|
"displayName",
|
||||||
|
"agentVersion",
|
||||||
|
"status",
|
||||||
|
"lastSeenAt",
|
||||||
|
"directAddress",
|
||||||
|
"relayAddress"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"id": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"machineId": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"displayName": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"agentVersion": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"status": {
|
||||||
|
"enum": [
|
||||||
|
"online",
|
||||||
|
"offline",
|
||||||
|
"degraded"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"lastSeenAt": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"directAddress": {
|
||||||
|
"type": [
|
||||||
|
"string",
|
||||||
|
"null"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"relayAddress": {
|
||||||
|
"type": [
|
||||||
|
"string",
|
||||||
|
"null"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
47
packages/contracts/schemas/storage-export.schema.json
Normal file
47
packages/contracts/schemas/storage-export.schema.json
Normal file
|
|
@ -0,0 +1,47 @@
|
||||||
|
{
|
||||||
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||||
|
"$id": "https://betternas.local/schemas/storage-export.schema.json",
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": false,
|
||||||
|
"required": [
|
||||||
|
"id",
|
||||||
|
"nasNodeId",
|
||||||
|
"label",
|
||||||
|
"path",
|
||||||
|
"protocols",
|
||||||
|
"capacityBytes",
|
||||||
|
"tags"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"id": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"nasNodeId": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"label": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"path": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"protocols": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"const": "webdav"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"capacityBytes": {
|
||||||
|
"type": [
|
||||||
|
"number",
|
||||||
|
"null"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"tags": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
97
packages/contracts/src/foundation.ts
Normal file
97
packages/contracts/src/foundation.ts
Normal file
|
|
@ -0,0 +1,97 @@
|
||||||
|
export const FOUNDATION_API_ROUTES = {
|
||||||
|
registerNode: "/api/v1/nodes/register",
|
||||||
|
nodeHeartbeat: "/api/v1/nodes/:nodeId/heartbeat",
|
||||||
|
listExports: "/api/v1/exports",
|
||||||
|
issueMountProfile: "/api/v1/mount-profiles/issue",
|
||||||
|
issueCloudProfile: "/api/v1/cloud-profiles/issue"
|
||||||
|
} as const;
|
||||||
|
|
||||||
|
export type NasNodeStatus = "online" | "offline" | "degraded";
|
||||||
|
export type StorageAccessProtocol = "webdav";
|
||||||
|
export type AccessMode = "mount" | "cloud";
|
||||||
|
export type AccessPrincipalType = "user" | "device";
|
||||||
|
export type MountCredentialMode = "session-token" | "app-password";
|
||||||
|
export type CloudProvider = "nextcloud";
|
||||||
|
|
||||||
|
export interface NasNode {
|
||||||
|
id: string;
|
||||||
|
machineId: string;
|
||||||
|
displayName: string;
|
||||||
|
agentVersion: string;
|
||||||
|
status: NasNodeStatus;
|
||||||
|
lastSeenAt: string;
|
||||||
|
directAddress: string | null;
|
||||||
|
relayAddress: string | null;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface StorageExport {
|
||||||
|
id: string;
|
||||||
|
nasNodeId: string;
|
||||||
|
label: string;
|
||||||
|
path: string;
|
||||||
|
protocols: StorageAccessProtocol[];
|
||||||
|
capacityBytes: number | null;
|
||||||
|
tags: string[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface AccessGrant {
|
||||||
|
id: string;
|
||||||
|
exportId: string;
|
||||||
|
principalType: AccessPrincipalType;
|
||||||
|
principalId: string;
|
||||||
|
modes: AccessMode[];
|
||||||
|
readonly: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface MountProfile {
|
||||||
|
id: string;
|
||||||
|
exportId: string;
|
||||||
|
protocol: "webdav";
|
||||||
|
displayName: string;
|
||||||
|
mountUrl: string;
|
||||||
|
readonly: boolean;
|
||||||
|
credentialMode: MountCredentialMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface CloudProfile {
|
||||||
|
id: string;
|
||||||
|
exportId: string;
|
||||||
|
provider: CloudProvider;
|
||||||
|
baseUrl: string;
|
||||||
|
path: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface StorageExportInput {
|
||||||
|
label: string;
|
||||||
|
path: string;
|
||||||
|
protocols: StorageAccessProtocol[];
|
||||||
|
capacityBytes: number | null;
|
||||||
|
tags: string[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface NodeRegistrationRequest {
|
||||||
|
machineId: string;
|
||||||
|
displayName: string;
|
||||||
|
agentVersion: string;
|
||||||
|
directAddress: string | null;
|
||||||
|
relayAddress: string | null;
|
||||||
|
exports: StorageExportInput[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface NodeHeartbeatRequest {
|
||||||
|
nodeId: string;
|
||||||
|
status: NasNodeStatus;
|
||||||
|
lastSeenAt: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface MountProfileRequest {
|
||||||
|
userId: string;
|
||||||
|
deviceId: string;
|
||||||
|
exportId: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface CloudProfileRequest {
|
||||||
|
userId: string;
|
||||||
|
exportId: string;
|
||||||
|
provider: CloudProvider;
|
||||||
|
}
|
||||||
|
|
@ -1,2 +1,2 @@
|
||||||
export * from "./control-plane.js";
|
export * from "./control-plane.js";
|
||||||
|
export * from "./foundation.js";
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue