dominus-sdk-nodejs 1.23.0 → 1.24.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +58 -43
- package/dist/namespaces/db.d.ts +32 -4
- package/dist/namespaces/db.d.ts.map +1 -1
- package/dist/namespaces/db.js +43 -11
- package/dist/namespaces/db.js.map +1 -1
- package/docs/architecture.md +186 -23
- package/docs/services.md +479 -0
- package/package.json +1 -1
- package/docs/development.md +0 -30
- package/docs/namespaces.md +0 -38
package/README.md
CHANGED
|
@@ -1,66 +1,81 @@
|
|
|
1
1
|
# Dominus SDK for Node.js
|
|
2
2
|
|
|
3
|
-
TypeScript SDK for CareBridge Dominus services. Provides a single, async-first client that routes through the Dominus Gateway, handles JWT minting/caching, and exposes service namespaces for secrets,
|
|
3
|
+
TypeScript SDK for CareBridge Dominus services. Provides a single, async-first client that routes through the Dominus Gateway, handles JWT minting/caching, and exposes service namespaces for secrets, database, files, auth, AI workflows, and more.
|
|
4
4
|
|
|
5
5
|
## What This Is
|
|
6
|
-
|
|
7
|
-
-
|
|
8
|
-
-
|
|
6
|
+
|
|
7
|
+
- **Server-side SDK** for Node.js 18+ (ESM-only, native fetch)
|
|
8
|
+
- **Gateway-first routing** -- all requests route through the Dominus Gateway (`/api/*` transformed to `/svc/*`)
|
|
9
|
+
- **Base64-encoded JSON bodies** for all request/response payloads (handled transparently)
|
|
10
|
+
- **19 service namespaces** plus root-level shortcuts for common operations
|
|
11
|
+
- **Built-in resilience**: retries with exponential backoff, circuit breaker, JWT caching
|
|
9
12
|
|
|
10
13
|
## Quick Start
|
|
11
14
|
|
|
12
|
-
```
|
|
15
|
+
```typescript
|
|
13
16
|
import { dominus } from 'dominus-sdk-nodejs';
|
|
14
17
|
|
|
15
18
|
process.env.DOMINUS_TOKEN = 'your-psk-token';
|
|
16
19
|
|
|
20
|
+
// Database CRUD
|
|
17
21
|
const users = await dominus.db.query('users', { filters: { status: 'active' } });
|
|
22
|
+
await dominus.db.insert('users', { name: 'John', status: 'active' });
|
|
23
|
+
|
|
24
|
+
// Cache and locks
|
|
18
25
|
await dominus.redis.set('session:123', { user: 'john' }, { ttl: 3600 });
|
|
26
|
+
|
|
27
|
+
// File storage
|
|
19
28
|
const file = await dominus.files.upload(buffer, 'report.pdf', { category: 'reports' });
|
|
29
|
+
|
|
30
|
+
// AI agents and workflows
|
|
31
|
+
const result = await dominus.ai.runAgent({ conversationId: 'conv-1', userPrompt: 'analyze data' });
|
|
20
32
|
```
|
|
21
33
|
|
|
22
|
-
##
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
## 2026-02-21 Workflow Contract Alignment
|
|
46
|
-
- `workflow.list()` -> `GET /api/workflow/workflows`
|
|
47
|
-
- `workflow.listCategories()` -> `GET /api/workflow/categories`
|
|
48
|
-
- `workflow.reorderCategory()` -> `PUT /api/workflow/categories/{category_id}/workflows/order`
|
|
34
|
+
## Features
|
|
35
|
+
|
|
36
|
+
| Category | Services |
|
|
37
|
+
|----------|----------|
|
|
38
|
+
| **Data & Persistence** | Database CRUD (`db`), secure audit-logged tables (`secure`), secrets (`secrets`), files via B2 (`files`), Redis cache/locks (`redis`) |
|
|
39
|
+
| **Auth & Access** | User/role/scope/tenant/page CRUD (`auth`), session management (`portal`), access control |
|
|
40
|
+
| **AI & Orchestration** | LLM completions multi-provider (`ai`), RAG, artifacts, speech STT/TTS, workflows (`workflow`), agent execution, Oracle streaming STT (`stt`) |
|
|
41
|
+
| **Infrastructure** | Schema DDL + migrations + Schema Builder (`ddl`), structured logging (`logs`), job queue (`jobs`/`processor`), email delivery (`courier`), provisioning (`db.syncSchema`) |
|
|
42
|
+
| **Admin & Ops** | Admin reseed/reset (`admin`), KV sync (`sync`), artifact storage (`artifacts`), health checks (`health`) |
|
|
43
|
+
| **Resilience** | Retries with backoff + jitter, circuit breaker (5 failures / 30s recovery), JWT caching (14 min) |
|
|
44
|
+
|
|
45
|
+
## Database Architecture
|
|
46
|
+
|
|
47
|
+
The platform uses a **3-role Neon PostgreSQL model**:
|
|
48
|
+
|
|
49
|
+
| Role | Database | Purpose |
|
|
50
|
+
|------|----------|---------|
|
|
51
|
+
| `neondb_owner` | both | DDL provisioning, schema sync, migrations |
|
|
52
|
+
| `dominus_user` | `dominus` | Backend schemas: auth, logs, meta, object, rag, agent, observability, workflow, tenant_admin |
|
|
53
|
+
| `open_user` | `dominus_open` | User-facing schemas: tenant_*, cat_* |
|
|
54
|
+
|
|
55
|
+
`dominus.db.syncSchema()` is the idempotent provisioning entry point. It creates missing schemas, tables, indexes, and seeds default data across both databases using the appropriate roles.
|
|
49
56
|
|
|
50
57
|
## Configuration
|
|
51
|
-
Required:
|
|
52
|
-
- `DOMINUS_TOKEN` (PSK)
|
|
53
58
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
+
| Variable | Required | Default | Purpose |
|
|
60
|
+
|----------|----------|---------|---------|
|
|
61
|
+
| `DOMINUS_TOKEN` | Yes | -- | PSK for JWT minting |
|
|
62
|
+
| `DOMINUS_GATEWAY_URL` | No | `https://gateway.getdominus.app` | Gateway base URL |
|
|
63
|
+
| `DOMINUS_BASE_URL` | No | Gateway URL | Override base URL for all requests |
|
|
64
|
+
| `DOMINUS_DEBUG` | No | `false` | Enable debug logging |
|
|
65
|
+
| `DOMINUS_CAPTURE_CONSOLE` | No | `false` | Auto-capture console.log to Dominus logs |
|
|
66
|
+
| `DOMINUS_HTTP_PROXY` | No | -- | HTTP proxy hint (informational) |
|
|
67
|
+
| `DOMINUS_HTTPS_PROXY` | No | -- | HTTPS proxy hint (informational) |
|
|
59
68
|
|
|
60
69
|
## Documentation
|
|
61
|
-
|
|
62
|
-
-
|
|
63
|
-
-
|
|
70
|
+
|
|
71
|
+
- [CLAUDE.md](CLAUDE.md) -- LLM and developer guide: conventions, repo map, workflow
|
|
72
|
+
- [docs/architecture.md](docs/architecture.md) -- Technical architecture, request flow, resilience patterns
|
|
73
|
+
- [docs/services.md](docs/services.md) -- Comprehensive reference of all 19 namespaces, endpoints, and methods
|
|
74
|
+
|
|
75
|
+
## Version
|
|
76
|
+
|
|
77
|
+
Current: **1.24.0** (see `package.json`)
|
|
64
78
|
|
|
65
79
|
## License
|
|
66
|
-
|
|
80
|
+
|
|
81
|
+
Proprietary -- CareBridge Systems
|
package/dist/namespaces/db.d.ts
CHANGED
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
import type { DominusClient } from '../lib/client.js';
|
|
8
8
|
export interface QueryOptions {
|
|
9
9
|
schema?: string;
|
|
10
|
+
open?: boolean;
|
|
10
11
|
filters?: Record<string, unknown>;
|
|
11
12
|
sortBy?: string;
|
|
12
13
|
sortOrder?: 'ASC' | 'DESC';
|
|
@@ -39,14 +40,18 @@ export declare class DbNamespace {
|
|
|
39
40
|
*
|
|
40
41
|
* @returns List of schema names
|
|
41
42
|
*/
|
|
42
|
-
schemas(
|
|
43
|
+
schemas(options?: {
|
|
44
|
+
open?: boolean;
|
|
45
|
+
}): Promise<string[]>;
|
|
43
46
|
/**
|
|
44
47
|
* List tables in a schema.
|
|
45
48
|
*
|
|
46
49
|
* @param schema - Schema name (default: "public")
|
|
47
50
|
* @returns List of table metadata
|
|
48
51
|
*/
|
|
49
|
-
tables(schema?: string
|
|
52
|
+
tables(schema?: string, options?: {
|
|
53
|
+
open?: boolean;
|
|
54
|
+
}): Promise<TableInfo[]>;
|
|
50
55
|
/**
|
|
51
56
|
* List columns in a table.
|
|
52
57
|
*
|
|
@@ -54,7 +59,9 @@ export declare class DbNamespace {
|
|
|
54
59
|
* @param schema - Schema name (default: "public")
|
|
55
60
|
* @returns List of column metadata
|
|
56
61
|
*/
|
|
57
|
-
columns(table: string, schema?: string
|
|
62
|
+
columns(table: string, schema?: string, options?: {
|
|
63
|
+
open?: boolean;
|
|
64
|
+
}): Promise<ColumnInfo[]>;
|
|
58
65
|
/**
|
|
59
66
|
* Query table data with filtering, sorting, and pagination.
|
|
60
67
|
*
|
|
@@ -73,6 +80,7 @@ export declare class DbNamespace {
|
|
|
73
80
|
*/
|
|
74
81
|
insert(table: string, data: Record<string, unknown>, options?: {
|
|
75
82
|
schema?: string;
|
|
83
|
+
open?: boolean;
|
|
76
84
|
reason?: string;
|
|
77
85
|
actor?: string;
|
|
78
86
|
}): Promise<Record<string, unknown>>;
|
|
@@ -87,6 +95,7 @@ export declare class DbNamespace {
|
|
|
87
95
|
*/
|
|
88
96
|
update(table: string, data: Record<string, unknown>, filters: Record<string, unknown>, options?: {
|
|
89
97
|
schema?: string;
|
|
98
|
+
open?: boolean;
|
|
90
99
|
reason?: string;
|
|
91
100
|
actor?: string;
|
|
92
101
|
}): Promise<{
|
|
@@ -102,11 +111,27 @@ export declare class DbNamespace {
|
|
|
102
111
|
*/
|
|
103
112
|
delete(table: string, filters: Record<string, unknown>, options?: {
|
|
104
113
|
schema?: string;
|
|
114
|
+
open?: boolean;
|
|
105
115
|
reason?: string;
|
|
106
116
|
actor?: string;
|
|
107
117
|
}): Promise<{
|
|
108
118
|
affected_rows: number;
|
|
109
119
|
}>;
|
|
120
|
+
/**
|
|
121
|
+
* Execute raw SQL queries.
|
|
122
|
+
*
|
|
123
|
+
* @param sql - SQL query with $1, $2 style placeholders
|
|
124
|
+
* @param params - Parameter values for placeholders
|
|
125
|
+
* @param options - Query options (schema, reason, actor)
|
|
126
|
+
* @returns Query result with rows and total count
|
|
127
|
+
*/
|
|
128
|
+
raw(sql: string, params?: unknown[], options?: {
|
|
129
|
+
schema?: string;
|
|
130
|
+
open?: boolean;
|
|
131
|
+
reason?: string;
|
|
132
|
+
actor?: string;
|
|
133
|
+
use_shared?: boolean;
|
|
134
|
+
}): Promise<QueryResult>;
|
|
110
135
|
/**
|
|
111
136
|
* Insert multiple rows at once using a transaction.
|
|
112
137
|
*
|
|
@@ -129,7 +154,10 @@ export declare class DbNamespace {
|
|
|
129
154
|
* Creates missing schemas, tables, indexes, and seeds default data.
|
|
130
155
|
* This is fully idempotent - safe to call multiple times.
|
|
131
156
|
*
|
|
132
|
-
*
|
|
157
|
+
* 3-role model: neondb_owner (provisioning), dominus_user (backend),
|
|
158
|
+
* open_user (user DB). Syncs backend schemas (auth, logs, meta, object,
|
|
159
|
+
* rag, agent, observability, workflow, tenant_admin) to dominus DB and
|
|
160
|
+
* user schemas (tenant_*, cat_*) to dominus_open DB.
|
|
133
161
|
*
|
|
134
162
|
* @returns Sync result with created schemas, tables, indexes
|
|
135
163
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"db.d.ts","sourceRoot":"","sources":["../../src/namespaces/db.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAEtD,MAAM,WAAW,YAAY;IAC3B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,KAAK,GAAG,MAAM,CAAC;IAC3B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IACrC,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,qBAAa,WAAW;IACV,OAAO,CAAC,MAAM;gBAAN,MAAM,EAAE,aAAa;IAEzC;;;;;;;OAOG;IACG,OAAO,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"db.d.ts","sourceRoot":"","sources":["../../src/namespaces/db.ts"],"names":[],"mappings":"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"}
|
package/dist/namespaces/db.js
CHANGED
|
@@ -17,10 +17,10 @@ export class DbNamespace {
|
|
|
17
17
|
*
|
|
18
18
|
* @returns List of schema names
|
|
19
19
|
*/
|
|
20
|
-
async schemas() {
|
|
20
|
+
async schemas(options = {}) {
|
|
21
21
|
const result = await this.client.request({
|
|
22
22
|
endpoint: '/api/database/schemas',
|
|
23
|
-
body: {},
|
|
23
|
+
body: { open: options.open },
|
|
24
24
|
});
|
|
25
25
|
return result.schemas || [];
|
|
26
26
|
}
|
|
@@ -30,10 +30,10 @@ export class DbNamespace {
|
|
|
30
30
|
* @param schema - Schema name (default: "public")
|
|
31
31
|
* @returns List of table metadata
|
|
32
32
|
*/
|
|
33
|
-
async tables(schema = 'public') {
|
|
33
|
+
async tables(schema = 'public', options = {}) {
|
|
34
34
|
const result = await this.client.request({
|
|
35
35
|
endpoint: '/api/database/tables',
|
|
36
|
-
body: { schema },
|
|
36
|
+
body: { schema, open: options.open },
|
|
37
37
|
});
|
|
38
38
|
return result.tables || [];
|
|
39
39
|
}
|
|
@@ -44,10 +44,10 @@ export class DbNamespace {
|
|
|
44
44
|
* @param schema - Schema name (default: "public")
|
|
45
45
|
* @returns List of column metadata
|
|
46
46
|
*/
|
|
47
|
-
async columns(table, schema = 'public') {
|
|
47
|
+
async columns(table, schema = 'public', options = {}) {
|
|
48
48
|
const result = await this.client.request({
|
|
49
49
|
endpoint: '/api/database/columns',
|
|
50
|
-
body: { table, schema },
|
|
50
|
+
body: { table, schema, open: options.open },
|
|
51
51
|
});
|
|
52
52
|
return result.columns || [];
|
|
53
53
|
}
|
|
@@ -59,7 +59,7 @@ export class DbNamespace {
|
|
|
59
59
|
* @returns Query result with rows and total count
|
|
60
60
|
*/
|
|
61
61
|
async query(table, options = {}) {
|
|
62
|
-
const { schema = 'public', filters, sortBy, sortOrder = 'ASC', limit = 100, offset = 0, } = options;
|
|
62
|
+
const { schema = 'public', open, filters, sortBy, sortOrder = 'ASC', limit = 100, offset = 0, } = options;
|
|
63
63
|
// Build order_by in DB Worker format: [{column, direction}]
|
|
64
64
|
const order_by = sortBy
|
|
65
65
|
? [{ column: sortBy, direction: sortOrder }]
|
|
@@ -69,6 +69,7 @@ export class DbNamespace {
|
|
|
69
69
|
body: {
|
|
70
70
|
table,
|
|
71
71
|
schema,
|
|
72
|
+
open,
|
|
72
73
|
where: filters,
|
|
73
74
|
order_by,
|
|
74
75
|
limit,
|
|
@@ -89,12 +90,13 @@ export class DbNamespace {
|
|
|
89
90
|
* @returns Inserted row data
|
|
90
91
|
*/
|
|
91
92
|
async insert(table, data, options = {}) {
|
|
92
|
-
const { schema = 'public' } = options;
|
|
93
|
+
const { schema = 'public', open } = options;
|
|
93
94
|
const result = await this.client.request({
|
|
94
95
|
endpoint: '/api/database/insert',
|
|
95
96
|
body: {
|
|
96
97
|
table,
|
|
97
98
|
schema,
|
|
99
|
+
open,
|
|
98
100
|
data,
|
|
99
101
|
returning: ['*'],
|
|
100
102
|
},
|
|
@@ -112,12 +114,13 @@ export class DbNamespace {
|
|
|
112
114
|
* @returns Affected rows count
|
|
113
115
|
*/
|
|
114
116
|
async update(table, data, filters, options = {}) {
|
|
115
|
-
const { schema = 'public' } = options;
|
|
117
|
+
const { schema = 'public', open } = options;
|
|
116
118
|
const result = await this.client.request({
|
|
117
119
|
endpoint: '/api/database/update',
|
|
118
120
|
body: {
|
|
119
121
|
table,
|
|
120
122
|
schema,
|
|
123
|
+
open,
|
|
121
124
|
data,
|
|
122
125
|
where: filters,
|
|
123
126
|
returning: ['*'],
|
|
@@ -134,18 +137,44 @@ export class DbNamespace {
|
|
|
134
137
|
* @returns Affected rows count
|
|
135
138
|
*/
|
|
136
139
|
async delete(table, filters, options = {}) {
|
|
137
|
-
const { schema = 'public' } = options;
|
|
140
|
+
const { schema = 'public', open } = options;
|
|
138
141
|
const result = await this.client.request({
|
|
139
142
|
endpoint: '/api/database/delete',
|
|
140
143
|
body: {
|
|
141
144
|
table,
|
|
142
145
|
schema,
|
|
146
|
+
open,
|
|
143
147
|
where: filters,
|
|
144
148
|
returning: ['*'],
|
|
145
149
|
},
|
|
146
150
|
});
|
|
147
151
|
return { affected_rows: result.row_count ?? 0 };
|
|
148
152
|
}
|
|
153
|
+
/**
|
|
154
|
+
* Execute raw SQL queries.
|
|
155
|
+
*
|
|
156
|
+
* @param sql - SQL query with $1, $2 style placeholders
|
|
157
|
+
* @param params - Parameter values for placeholders
|
|
158
|
+
* @param options - Query options (schema, reason, actor)
|
|
159
|
+
* @returns Query result with rows and total count
|
|
160
|
+
*/
|
|
161
|
+
async raw(sql, params = [], options = {}) {
|
|
162
|
+
const { schema = 'public', open, use_shared = false } = options;
|
|
163
|
+
const result = await this.client.request({
|
|
164
|
+
endpoint: '/api/database/raw',
|
|
165
|
+
body: {
|
|
166
|
+
sql,
|
|
167
|
+
params,
|
|
168
|
+
schema,
|
|
169
|
+
open,
|
|
170
|
+
use_shared,
|
|
171
|
+
},
|
|
172
|
+
});
|
|
173
|
+
return {
|
|
174
|
+
rows: result.rows || [],
|
|
175
|
+
total: result.row_count ?? 0,
|
|
176
|
+
};
|
|
177
|
+
}
|
|
149
178
|
/**
|
|
150
179
|
* Insert multiple rows at once using a transaction.
|
|
151
180
|
*
|
|
@@ -192,7 +221,10 @@ export class DbNamespace {
|
|
|
192
221
|
* Creates missing schemas, tables, indexes, and seeds default data.
|
|
193
222
|
* This is fully idempotent - safe to call multiple times.
|
|
194
223
|
*
|
|
195
|
-
*
|
|
224
|
+
* 3-role model: neondb_owner (provisioning), dominus_user (backend),
|
|
225
|
+
* open_user (user DB). Syncs backend schemas (auth, logs, meta, object,
|
|
226
|
+
* rag, agent, observability, workflow, tenant_admin) to dominus DB and
|
|
227
|
+
* user schemas (tenant_*, cat_*) to dominus_open DB.
|
|
196
228
|
*
|
|
197
229
|
* @returns Sync result with created schemas, tables, indexes
|
|
198
230
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"db.js","sourceRoot":"","sources":["../../src/namespaces/db.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;
|
|
1
|
+
{"version":3,"file":"db.js","sourceRoot":"","sources":["../../src/namespaces/db.ts"],"names":[],"mappings":"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"}
|
package/docs/architecture.md
CHANGED
|
@@ -1,34 +1,197 @@
|
|
|
1
1
|
# Architecture
|
|
2
2
|
|
|
3
3
|
## Request Flow
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
4
|
+
|
|
5
|
+
### JWT Minting and Caching
|
|
6
|
+
1. SDK reads `DOMINUS_TOKEN` (PSK) from env or constructor
|
|
7
|
+
2. First request triggers health check (`GET /health` on gateway) for cold-start warmup
|
|
8
|
+
3. Gateway called: `POST /jwt/mint` with base64-encoded body containing PSK
|
|
9
|
+
4. JWT returned and cached in `dominusCache` (encrypted with PSK)
|
|
10
|
+
5. JWT refreshed before expiry (~14 min cache for 15-min lifetime, 1-min buffer)
|
|
11
|
+
6. Concurrent requests share a single mint via mutex (`client.ts:582`)
|
|
12
|
+
|
|
13
|
+
### Base64 Encoding
|
|
14
|
+
- **Request**: JSON body encoded to base64 string before transmission
|
|
15
|
+
- **Response**: Base64 string decoded to JSON before returning to caller
|
|
16
|
+
- Handled transparently by `client.ts` -- namespace code never touches encoding
|
|
17
|
+
- Binary operations (`binaryUpload`/`binaryDownload`) bypass base64
|
|
18
|
+
|
|
19
|
+
### Service Routing
|
|
20
|
+
- SDK uses `/api/*` paths internally
|
|
21
|
+
- `transformEndpointForGateway()` converts to `/svc/*` for gateway (`client.ts:430`)
|
|
22
|
+
- Example: `dominus.secrets.get()` -> `POST /api/secrets/get` -> gateway -> `/svc/secrets/get`
|
|
23
|
+
|
|
24
|
+
### HTTP Method Resolution
|
|
25
|
+
- Default method: `POST`
|
|
26
|
+
- GET requests must explicitly set `method: 'GET'` and send no body
|
|
27
|
+
- Content-Type for JSON: `text/plain` (base64-encoded body)
|
|
28
|
+
- Content-Type for binary: `multipart/form-data` (via FormData)
|
|
9
29
|
|
|
10
30
|
## Gateway Routing
|
|
11
|
-
- Default base URL is the gateway (`DOMINUS_GATEWAY_URL`).
|
|
12
|
-
- `DOMINUS_BASE_URL` can override the base (defaults to gateway).
|
|
13
|
-
- `useGateway: true` forces gateway base URL for a request.
|
|
14
31
|
|
|
15
|
-
|
|
16
|
-
-
|
|
17
|
-
-
|
|
18
|
-
-
|
|
19
|
-
|
|
32
|
+
### URL Resolution
|
|
33
|
+
- **Default**: `DOMINUS_GATEWAY_URL` or `https://gateway.getdominus.app`
|
|
34
|
+
- **Override**: `DOMINUS_BASE_URL` (defaults to gateway URL if unset)
|
|
35
|
+
- **Per-request**: `useGateway: true` forces gateway base URL (used for agent-runtime, workflow-manager, sync-worker)
|
|
36
|
+
|
|
37
|
+
### Header Injection
|
|
38
|
+
- `Authorization`: `Bearer <jwt>` (service JWT or user JWT)
|
|
39
|
+
- `Content-Type`: `text/plain` for JSON, omitted for FormData (browser sets boundary)
|
|
40
|
+
- `Accept`: `text/event-stream` for SSE streaming, `audio/*` for binary download
|
|
41
|
+
|
|
42
|
+
## Database Architecture: 3-Role Model
|
|
43
|
+
|
|
44
|
+
The platform uses **Neon PostgreSQL** with a hybrid tenant model and three database roles:
|
|
45
|
+
|
|
46
|
+
| Role | Database | Purpose | Schemas |
|
|
47
|
+
|------|----------|---------|---------|
|
|
48
|
+
| `neondb_owner` | both | DDL provisioning, schema sync, migrations | Creates/alters all schemas |
|
|
49
|
+
| `dominus_user` | `dominus` | Backend application queries | auth, logs, meta, object, rag, agent, observability, workflow, tenant_admin |
|
|
50
|
+
| `open_user` | `dominus_open` | User-facing data queries | tenant_*, cat_* |
|
|
51
|
+
|
|
52
|
+
### Provisioning: `syncSchema()`
|
|
53
|
+
- Entry point: `dominus.db.syncSchema()` (`src/namespaces/db.ts:327`)
|
|
54
|
+
- Endpoint: `POST /api/provision/sync`
|
|
55
|
+
- Timeout: 2 minutes
|
|
56
|
+
- Fully idempotent -- safe to call repeatedly
|
|
57
|
+
- Creates missing schemas, tables, indexes across both databases
|
|
58
|
+
- Seeds default data (admin tenant, scopes, roles, pages)
|
|
59
|
+
- Runs with `neondb_owner` credentials for full DDL access
|
|
60
|
+
|
|
61
|
+
### Schema Builder (DDL Namespace)
|
|
62
|
+
The `ddl` namespace provides category-scoped migrations via the Schema Builder:
|
|
63
|
+
- **Preview**: Generate migration SQL without applying
|
|
64
|
+
- **Apply**: Execute migration across all tenant schemas in a category
|
|
65
|
+
- **Sync**: Bring lagging tenants up to the latest migration version
|
|
66
|
+
- **Reset**: Factory-reset a category or individual tenant schema
|
|
67
|
+
- Migrations stored in B2 storage, tracked in `meta.alembic_version`
|
|
68
|
+
|
|
69
|
+
## Resilience Patterns
|
|
70
|
+
|
|
71
|
+
### Retries
|
|
72
|
+
- **Default**: 3 attempts (`client.ts:66`)
|
|
73
|
+
- **Backoff**: Exponential with jitter (base 1s, max 15s) (`client.ts:128-136`)
|
|
74
|
+
- **4xx errors**: NOT retried (client errors are deterministic)
|
|
75
|
+
- **5xx errors**: Retried with backoff
|
|
76
|
+
- **JWT mint retries**: Separate loop, 3 attempts with base 2s, max 10s (`client.ts:457`)
|
|
77
|
+
|
|
78
|
+
### Circuit Breaker
|
|
79
|
+
- **Opens after**: 5 consecutive failures (`client.ts:85`)
|
|
80
|
+
- **Recovery**: 30 seconds (`client.ts:86`)
|
|
81
|
+
- **States**: closed -> open -> half-open -> closed
|
|
82
|
+
- **Scope**: Global in-memory state (not per-service)
|
|
83
|
+
|
|
84
|
+
### Timeouts
|
|
85
|
+
- **Default**: 30 seconds per request (`client.ts:67`)
|
|
86
|
+
- **Maximum**: 5 minutes (300,000ms cap in `client.ts:832`)
|
|
87
|
+
- **JWT mint**: 30 seconds
|
|
88
|
+
- **Health check**: 15 seconds with 2 retries
|
|
89
|
+
- **Streaming**: 5 minutes default
|
|
90
|
+
- **Schema sync / migrations**: 2 minutes
|
|
91
|
+
|
|
92
|
+
## JWT Verification
|
|
93
|
+
|
|
94
|
+
### Local Verification (`verifyJwtLocally()`)
|
|
95
|
+
- Fetches JWKS from `GET /jwt/jwks` on gateway
|
|
96
|
+
- Verifies RS256 signature using Web Crypto API
|
|
97
|
+
- Checks expiry (`exp`), not-before (`nbf`), issued-at (`iat`) claims
|
|
98
|
+
|
|
99
|
+
### JWKS Caching
|
|
100
|
+
- Cached 1 hour after fetch
|
|
101
|
+
- Stale cache used if refresh fails (fail-open for availability)
|
|
102
|
+
- Key rotation: if `kid` not found, cache invalidated and JWKS re-fetched
|
|
20
103
|
|
|
21
|
-
|
|
22
|
-
- `
|
|
23
|
-
-
|
|
104
|
+
### JWT Claims
|
|
105
|
+
- `iss`: Issuer (gateway)
|
|
106
|
+
- `sub`: Subject (user ID)
|
|
107
|
+
- `project_id`: Project identifier
|
|
108
|
+
- `is_system`: Boolean for system/admin users
|
|
109
|
+
- `iat`, `exp`: Issue and expiration timestamps
|
|
110
|
+
|
|
111
|
+
### JWT Delegation (`delegateJwt()`)
|
|
112
|
+
- Mints a JWT for a target project via `POST /jwt/delegate`
|
|
113
|
+
- Used by admin-level services (MCP) for cross-project operations
|
|
114
|
+
- Accepts `targetProjectId`, `targetEnvironment`, optional `useShared`
|
|
24
115
|
|
|
25
116
|
## Streaming and Binary
|
|
26
|
-
|
|
27
|
-
-
|
|
117
|
+
|
|
118
|
+
### Server-Sent Events (SSE)
|
|
119
|
+
- `streamRequest()` in `client.ts:996`
|
|
120
|
+
- Handles connection management and SSE event parsing
|
|
121
|
+
- Yields parsed JSON chunks as `AsyncGenerator`
|
|
122
|
+
- Supports `event:` and `data:` SSE fields
|
|
123
|
+
- `[DONE]` sentinel terminates stream
|
|
124
|
+
- Used by `ai.streamAgent()`, `ai.completeStream()`
|
|
125
|
+
|
|
126
|
+
### Binary Upload
|
|
127
|
+
- `binaryUpload()` in `client.ts:1105`
|
|
128
|
+
- Uses `multipart/form-data` via native `FormData`
|
|
129
|
+
- No base64 wrapping -- raw bytes
|
|
130
|
+
- Used for file uploads, STT audio, RAG document ingest
|
|
131
|
+
|
|
132
|
+
### Binary Download
|
|
133
|
+
- `binaryDownload()` in `client.ts:1180`
|
|
134
|
+
- Returns raw `Buffer`
|
|
135
|
+
- Used for TTS playback, artifact retrieval
|
|
28
136
|
|
|
29
137
|
## Environment Variables
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
138
|
+
|
|
139
|
+
| Variable | Required | Default | Purpose |
|
|
140
|
+
|----------|----------|---------|---------|
|
|
141
|
+
| `DOMINUS_TOKEN` | Yes | -- | PSK for JWT minting |
|
|
142
|
+
| `DOMINUS_GATEWAY_URL` | No | `https://gateway.getdominus.app` | Gateway base URL |
|
|
143
|
+
| `DOMINUS_BASE_URL` | No | Gateway URL | Override base URL |
|
|
144
|
+
| `DOMINUS_DEBUG` | No | `false` | Verbose debug logging |
|
|
145
|
+
| `DOMINUS_CAPTURE_CONSOLE` | No | `false` | Forward console output to logs |
|
|
146
|
+
| `DOMINUS_HTTP_PROXY` | No | -- | HTTP proxy (informational) |
|
|
147
|
+
| `DOMINUS_HTTPS_PROXY` | No | -- | HTTPS proxy (informational) |
|
|
148
|
+
|
|
149
|
+
## Error Handling
|
|
150
|
+
|
|
151
|
+
### HTTP Status to Error Class Mapping
|
|
152
|
+
| Status | Error Class | Cause |
|
|
153
|
+
|--------|-------------|-------|
|
|
154
|
+
| 400 | `ValidationError` | Invalid input |
|
|
155
|
+
| 401 | `AuthenticationError` | Invalid/expired JWT |
|
|
156
|
+
| 403 | `AuthorizationError` | Permission denied |
|
|
157
|
+
| 404 | `NotFoundError` | Resource not found |
|
|
158
|
+
| 409 | `ConflictError` | Duplicate/conflict |
|
|
159
|
+
| 5xx | `ServiceError` | Server error |
|
|
160
|
+
| Network | `ConnectionError` | Network/DNS failure |
|
|
161
|
+
| Timeout | `TimeoutError` | Request exceeded timeout |
|
|
162
|
+
|
|
163
|
+
### Error Properties
|
|
164
|
+
```typescript
|
|
165
|
+
error.message // Human-readable message
|
|
166
|
+
error.statusCode // HTTP status (if applicable)
|
|
167
|
+
error.details // Response body object (if applicable)
|
|
168
|
+
error.endpoint // Endpoint that failed
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
## Security
|
|
172
|
+
|
|
173
|
+
### PSK Management
|
|
174
|
+
- `DOMINUS_TOKEN` never exposed in logs (masked in debug output)
|
|
175
|
+
- PSK used only for JWT minting, not stored long-term
|
|
176
|
+
- JWT used for all subsequent requests
|
|
177
|
+
|
|
178
|
+
### Base64 Encoding
|
|
179
|
+
- Base64 is encoding, NOT encryption
|
|
180
|
+
- All security provided by TLS/HTTPS in transit
|
|
181
|
+
- Backend validates all inputs regardless of encoding
|
|
182
|
+
|
|
183
|
+
### Secure Tables
|
|
184
|
+
- Registered via `auth.createSecureTable()`
|
|
185
|
+
- Every access requires `reason` (audit context) and `actor` (user identifier)
|
|
186
|
+
- Server-side audit trail recorded with reason + actor
|
|
187
|
+
|
|
188
|
+
## Observability
|
|
189
|
+
|
|
190
|
+
### Debug Logging
|
|
191
|
+
`DOMINUS_DEBUG=true` enables: request/response bodies, retry attempts, circuit breaker state changes, JWT lifecycle.
|
|
192
|
+
|
|
193
|
+
### Console Capture
|
|
194
|
+
`DOMINUS_CAPTURE_CONSOLE=true` forwards `console.log/warn/error/debug/info` to Dominus logs. Fire-and-forget, never blocks. Call `dominus.captureConsole()` / `dominus.releaseConsole()` programmatically.
|
|
195
|
+
|
|
196
|
+
### Request Timing
|
|
197
|
+
Each request tracks: total time including retries, individual attempt times, circuit breaker recovery time.
|
package/docs/services.md
ADDED
|
@@ -0,0 +1,479 @@
|
|
|
1
|
+
# Services Reference
|
|
2
|
+
|
|
3
|
+
All 19 service namespaces with actual endpoints and method signatures from source code.
|
|
4
|
+
|
|
5
|
+
Gateway routing: all `/api/*` paths are transformed to `/svc/*` by the client.
|
|
6
|
+
|
|
7
|
+
## 1. secrets (Warden)
|
|
8
|
+
|
|
9
|
+
Encrypted secrets management. Single endpoint with action-based dispatch.
|
|
10
|
+
|
|
11
|
+
| Method | Endpoint | Action |
|
|
12
|
+
|--------|----------|--------|
|
|
13
|
+
| `get(key)` | `POST /api/warden/secrets` | `get` |
|
|
14
|
+
| `upsert(key, value, comment?)` | `POST /api/warden/secrets` | `update` (falls back to `create`) |
|
|
15
|
+
| `list(prefix?)` | `POST /api/warden/secrets` | `list` |
|
|
16
|
+
| `delete(key)` | `POST /api/warden/secrets` | `delete` |
|
|
17
|
+
|
|
18
|
+
**Root shortcuts:** `dominus.get(key)`, `dominus.upsert(key, value, comment?)`
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## 2. db (Scribe)
|
|
23
|
+
|
|
24
|
+
Database CRUD via DB Worker. Includes provisioning.
|
|
25
|
+
|
|
26
|
+
| Method | Endpoint | HTTP |
|
|
27
|
+
|--------|----------|------|
|
|
28
|
+
| `schemas()` | `/api/database/schemas` | POST |
|
|
29
|
+
| `tables(schema?)` | `/api/database/tables` | POST |
|
|
30
|
+
| `columns(table, schema?)` | `/api/database/columns` | POST |
|
|
31
|
+
| `query(table, options?)` | `/api/database/select` | POST |
|
|
32
|
+
| `insert(table, data, options?)` | `/api/database/insert` | POST |
|
|
33
|
+
| `update(table, data, filters, options?)` | `/api/database/update` | POST |
|
|
34
|
+
| `delete(table, filters, options?)` | `/api/database/delete` | POST |
|
|
35
|
+
| `raw(sql, params?, options?)` | `/api/database/raw` | POST |
|
|
36
|
+
| `bulkInsert(table, rows, options?)` | `/api/database/raw` | POST |
|
|
37
|
+
| `syncSchema()` | `/api/provision/sync` | POST |
|
|
38
|
+
|
|
39
|
+
**Root shortcuts:** `dominus.listTables()`, `dominus.queryTable()`, `dominus.insertRow()`, `dominus.updateRows()`, `dominus.deleteRows()`, `dominus.listColumns()`
|
|
40
|
+
|
|
41
|
+
### Provisioning: syncSchema()
|
|
42
|
+
|
|
43
|
+
Idempotent schema provisioning using the **3-role model**:
|
|
44
|
+
|
|
45
|
+
| Role | Database | Schemas |
|
|
46
|
+
|------|----------|---------|
|
|
47
|
+
| `neondb_owner` | both | DDL provisioning (runs syncSchema) |
|
|
48
|
+
| `dominus_user` | `dominus` | auth, logs, meta, object, rag, agent, observability, workflow, tenant_admin |
|
|
49
|
+
| `open_user` | `dominus_open` | tenant_*, cat_* |
|
|
50
|
+
|
|
51
|
+
Creates missing schemas, tables, indexes, and seeds default data. 2-minute timeout.
|
|
52
|
+
|
|
53
|
+
Source: `src/namespaces/db.ts:327`
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
## 3. secure (Scribe)
|
|
58
|
+
|
|
59
|
+
Audit-logged table access. All operations require `SecureAccessContext` with `reason` and `actor`.
|
|
60
|
+
|
|
61
|
+
| Method | Endpoint | HTTP |
|
|
62
|
+
|--------|----------|------|
|
|
63
|
+
| `tables(schema?)` | `/api/scribe/data/{schema}/tables` | GET |
|
|
64
|
+
| `columns(table, schema?)` | `/api/scribe/data/{schema}/{table}/columns` | GET |
|
|
65
|
+
| `query(table, context, options?)` | `/api/scribe/data/{schema}/{table}/query` | POST |
|
|
66
|
+
| `insert(table, data, context, schema?)` | `/api/scribe/data/{schema}/{table}/insert` | POST |
|
|
67
|
+
| `update(table, data, filters, context, schema?)` | `/api/scribe/data/{schema}/{table}/update` | POST |
|
|
68
|
+
| `delete(table, filters, context, schema?)` | `/api/scribe/data/{schema}/{table}/delete` | POST |
|
|
69
|
+
| `bulkInsert(table, rows, context, schema?)` | `/api/scribe/data/{schema}/{table}/bulk-insert` | POST |
|
|
70
|
+
|
|
71
|
+
---
|
|
72
|
+
|
|
73
|
+
## 4. redis (Whisperer)
|
|
74
|
+
|
|
75
|
+
Redis cache via Upstash REST API. TTL enforced: 60s-86400s.
|
|
76
|
+
|
|
77
|
+
| Method | Endpoint | HTTP |
|
|
78
|
+
|--------|----------|------|
|
|
79
|
+
| `set(key, value, ttl?, category?)` | `/api/whisperer/set` | POST |
|
|
80
|
+
| `get(key, options?)` | `/api/whisperer/get` | POST |
|
|
81
|
+
| `delete(key, category?)` | `/api/whisperer/delete` | POST |
|
|
82
|
+
| `list(options?)` | `/api/whisperer/list` | POST |
|
|
83
|
+
| `mget(keys)` | `/api/whisperer/mget` | POST |
|
|
84
|
+
| `setnx(key, value, ttl?, category?)` | `/api/whisperer/setnx` | POST |
|
|
85
|
+
| `incr(key, delta?, ttl?, category?)` | `/api/whisperer/incr` | POST |
|
|
86
|
+
| `hset(key, field, value, ttl?, category?)` | `/api/whisperer/hset` | POST |
|
|
87
|
+
| `hget(key, field, category?)` | `/api/whisperer/hget` | POST |
|
|
88
|
+
| `hgetall(key, category?)` | `/api/whisperer/hgetall` | POST |
|
|
89
|
+
| `hdel(key, field, category?)` | `/api/whisperer/hdel` | POST |
|
|
90
|
+
| `type(key, category?)` | `/api/whisperer/type` | POST |
|
|
91
|
+
| `smembers(key, category?)` | `/api/whisperer/smembers` | POST |
|
|
92
|
+
| `lrange(key, options?)` | `/api/whisperer/lrange` | POST |
|
|
93
|
+
|
|
94
|
+
---
|
|
95
|
+
|
|
96
|
+
## 5. files (Archivist)
|
|
97
|
+
|
|
98
|
+
File storage via Backblaze B2. Supports upload, download, browse, views, and folders.
|
|
99
|
+
|
|
100
|
+
| Method | Endpoint | HTTP |
|
|
101
|
+
|--------|----------|------|
|
|
102
|
+
| `upload(data, filename, options?)` | `/api/archivist/upload` | POST |
|
|
103
|
+
| `download(options)` | `/api/archivist/download` | POST |
|
|
104
|
+
| `fetch(options)` | `/api/archivist/fetch` | POST |
|
|
105
|
+
| `list(options?)` | `/api/archivist/list` | POST |
|
|
106
|
+
| `delete(options)` | `/api/archivist/delete` | POST |
|
|
107
|
+
| `move(fileId, options)` | `/api/archivist/move` | POST |
|
|
108
|
+
| `updateMeta(fileId, options)` | `/api/archivist/update` | POST |
|
|
109
|
+
| `browse(options)` | `/api/archivist/browse` | POST |
|
|
110
|
+
| `getStorageStats()` | `/api/archivist/stats` | POST |
|
|
111
|
+
| `listCategories()` | `/api/archivist/categories` | POST |
|
|
112
|
+
| `listViews(options?)` | `/api/archivist/views` | POST |
|
|
113
|
+
| `listCategoriesInView(view)` | `/api/archivist/view-categories` | POST |
|
|
114
|
+
| `createFolder(options)` | `/api/archivist/folder` | POST |
|
|
115
|
+
| `deleteFolder(options)` | `/api/archivist/folder` | DELETE |
|
|
116
|
+
| `factoryReset(options?)` | `/api/admin/factory-reset-storage` | POST |
|
|
117
|
+
|
|
118
|
+
---
|
|
119
|
+
|
|
120
|
+
## 6. auth (Guardian)
|
|
121
|
+
|
|
122
|
+
User, role, scope, client, tenant, page management. Full CRUD. Source: `src/namespaces/auth.ts`
|
|
123
|
+
|
|
124
|
+
**Users:** `createUser`, `getUser`, `updateUser`, `deleteUser`, `listUsers`, `inviteUser`
|
|
125
|
+
- Endpoints: `/api/guardian/users`, `/api/guardian/users/{id}`
|
|
126
|
+
|
|
127
|
+
**Roles:** `createRole`, `getRole`, `updateRole`, `deleteRole`, `listRoles`
|
|
128
|
+
- Endpoints: `/api/guardian/roles`, `/api/guardian/roles/{id}`
|
|
129
|
+
|
|
130
|
+
**Scopes:** `createScope`, `getScope`, `updateScope`, `deleteScope`, `listScopes`
|
|
131
|
+
- Endpoints: `/api/guardian/scopes`, `/api/guardian/scopes/{id}`
|
|
132
|
+
|
|
133
|
+
**Clients:** `createClient`, `getClient`, `updateClient`, `deleteClient`, `listClients`
|
|
134
|
+
- Endpoints: `/api/guardian/clients`, `/api/guardian/clients/{id}`
|
|
135
|
+
|
|
136
|
+
**Tenants:** `createTenant`, `getTenant`, `updateTenant`, `deleteTenant`, `listTenants`
|
|
137
|
+
- Endpoints: `/api/guardian/tenants`, `/api/guardian/tenants/{id}`
|
|
138
|
+
|
|
139
|
+
**Tenant Categories:** `createTenantCategory`, `listTenantCategories`, `getTenantCategory`, `deleteTenantCategory`
|
|
140
|
+
- Endpoints: `/api/guardian/tenant-categories`, `/api/guardian/tenant-categories/{id}`
|
|
141
|
+
|
|
142
|
+
**Pages:** `createPage`, `getPage`, `updatePage`, `deletePage`, `listPages`
|
|
143
|
+
- Endpoints: `/api/guardian/pages`, `/api/guardian/pages/{id}`
|
|
144
|
+
|
|
145
|
+
**Navigation:** `createNavItem`, `updateNavItem`, `deleteNavItem`, `listNavItems`, `reorderNavItems`
|
|
146
|
+
- Endpoints: `/api/guardian/navigation`, `/api/guardian/navigation/{id}`, `/api/guardian/navigation/reorder`
|
|
147
|
+
|
|
148
|
+
**Secure Tables:** `createSecureTable`, `listSecureTables`, `getSecureTable`, `deleteSecureTable`
|
|
149
|
+
- Endpoints: `/api/guardian/secure-tables`, `/api/guardian/secure-tables/{id}`
|
|
150
|
+
|
|
151
|
+
**Role/Scope Assignments:** `assignRoleToUser`, `removeRoleFromUser`, `assignScopeToRole`, `removeScopeFromRole`
|
|
152
|
+
- Endpoints: `/api/guardian/users/{id}/roles/{roleId}`, `/api/guardian/roles/{id}/scopes/{scopeId}`
|
|
153
|
+
|
|
154
|
+
---
|
|
155
|
+
|
|
156
|
+
## 7. portal (Portal)
|
|
157
|
+
|
|
158
|
+
User-facing authentication, sessions, profile, navigation, registration.
|
|
159
|
+
|
|
160
|
+
| Method | Endpoint | HTTP |
|
|
161
|
+
|--------|----------|------|
|
|
162
|
+
| `login(username, password, tenantId?)` | `/api/portal/auth/login` | POST |
|
|
163
|
+
| `loginClient(psk, tenantId?)` | `/api/portal/auth/login-client` | POST |
|
|
164
|
+
| `logout(userToken?)` | `/api/portal/auth/logout` | POST |
|
|
165
|
+
| `refresh(userToken?)` | `/api/portal/auth/refresh` | POST |
|
|
166
|
+
| `me(userToken?)` | `/api/portal/auth/me` | GET |
|
|
167
|
+
| `switchTenant(tenantId, userToken?)` | `/api/portal/auth/switch-tenant` | POST |
|
|
168
|
+
| `changePassword(current, new, userToken?)` | `/api/portal/security/change-password` | POST |
|
|
169
|
+
| `requestPasswordReset(email)` | `/api/portal/security/request-reset` | POST |
|
|
170
|
+
| `confirmPasswordReset(token, newPassword)` | `/api/portal/security/confirm-reset` | POST |
|
|
171
|
+
| `listSessions(userToken?)` | `/api/portal/security/sessions` | GET |
|
|
172
|
+
| `revokeSession(sessionId, userToken?)` | `/api/portal/security/sessions/{id}` | DELETE |
|
|
173
|
+
| `revokeAllSessions(userToken?)` | `/api/portal/security/sessions/revoke-all` | POST |
|
|
174
|
+
| `getProfile(userToken?)` | `/api/portal/profile` | GET |
|
|
175
|
+
| `updateProfile(params, userToken?)` | `/api/portal/profile` | PUT |
|
|
176
|
+
| `getPreferences(userToken?)` | `/api/portal/profile/preferences` | GET |
|
|
177
|
+
| `updatePreferences(params, userToken?)` | `/api/portal/profile/preferences` | PUT |
|
|
178
|
+
| `getNavigation(userToken?, options?)` | `/api/portal/nav` | GET |
|
|
179
|
+
| `checkPageAccess(pagePath, userToken?)` | `/api/portal/nav/check-access` | POST |
|
|
180
|
+
| `register(username, email, password, tenantId)` | `/api/portal/register` | POST |
|
|
181
|
+
| `verifyEmail(token)` | `/api/portal/register/verify` | POST |
|
|
182
|
+
| `resendVerification(email)` | `/api/portal/register/resend-verification` | POST |
|
|
183
|
+
| `acceptInvitation(token, password)` | `/api/portal/register/accept-invitation` | POST |
|
|
184
|
+
|
|
185
|
+
---
|
|
186
|
+
|
|
187
|
+
## 8. ddl (Smith)
|
|
188
|
+
|
|
189
|
+
Schema DDL, migrations, provisioning, and Schema Builder.
|
|
190
|
+
|
|
191
|
+
### Direct DDL
|
|
192
|
+
| Method | Endpoint | HTTP |
|
|
193
|
+
|--------|----------|------|
|
|
194
|
+
| `createTable(name, columns, schema?)` | `/api/smith/schema/create-table` | POST |
|
|
195
|
+
| `dropTable(name, schema?)` | `/api/smith/schema/drop-table` | POST |
|
|
196
|
+
| `addColumn(table, column, schema?)` | `/api/smith/schema/add-column` | POST |
|
|
197
|
+
| `dropColumn(table, column, schema?)` | `/api/smith/schema/drop-column` | POST |
|
|
198
|
+
| `alterColumn(table, column, changes, schema?)` | `/api/smith/schema/alter-column` | POST |
|
|
199
|
+
| `createIndex(table, name, columns, options?)` | `/api/smith/schema/create-index` | POST |
|
|
200
|
+
| `dropIndex(name, schema?)` | `/api/smith/schema/drop-index` | POST |
|
|
201
|
+
|
|
202
|
+
### Category DDL (atomic multi-schema)
|
|
203
|
+
| Method | Endpoint |
|
|
204
|
+
|--------|----------|
|
|
205
|
+
| `categoryCreateTable(slug, name, columns)` | `/api/smith/category/create-table` |
|
|
206
|
+
| `categoryAddColumn(slug, name, column)` | `/api/smith/category/add-column` |
|
|
207
|
+
|
|
208
|
+
### Migrations
|
|
209
|
+
| Method | Endpoint | HTTP |
|
|
210
|
+
|--------|----------|------|
|
|
211
|
+
| `listMigrations(schema)` | `/api/smith/migrations/list/{schema}` | GET |
|
|
212
|
+
| `listCategoryMigrations(slug)` | `/api/smith/migrations/category/{slug}/list` | GET |
|
|
213
|
+
| `applyMigration(schema, id)` | `/api/smith/migrations/apply` | POST |
|
|
214
|
+
| `rollbackMigration(schema, id)` | `/api/smith/migrations/rollback` | POST |
|
|
215
|
+
|
|
216
|
+
### Provisioning
|
|
217
|
+
| Method | Endpoint |
|
|
218
|
+
|--------|----------|
|
|
219
|
+
| `provisionTenantSchema(slug, categorySlug?)` | `/api/smith/provision/tenant-schema` |
|
|
220
|
+
| `provisionTenantFromCategory(slug, categorySlug)` | `/api/smith/provision/tenant-from-category` |
|
|
221
|
+
|
|
222
|
+
### Schema Builder
|
|
223
|
+
| Method | Endpoint | HTTP |
|
|
224
|
+
|--------|----------|------|
|
|
225
|
+
| `getCategoryStructure(slug)` | `/api/database/builder/category/{slug}/structure` | GET |
|
|
226
|
+
| `getCategoryMigrationHistory(slug)` | `/api/database/builder/category/{slug}/migrations` | GET |
|
|
227
|
+
| `previewMigration(slug, op, params, name)` | `/api/database/builder/category/{slug}/preview-migration` | POST |
|
|
228
|
+
| `applyBuilderMigration(slug, op, params, name)` | `/api/database/builder/category/{slug}/apply-migration` | POST |
|
|
229
|
+
| `getMigrationFile(slug, versionId)` | `/api/database/builder/category/{slug}/migrations/{id}` | GET |
|
|
230
|
+
| `getTenantSyncStatus(slug)` | `/api/database/builder/category/{slug}/sync-status` | GET |
|
|
231
|
+
| `syncTenantsToLatest(slug)` | `/api/database/builder/category/{slug}/sync-tenants` | POST |
|
|
232
|
+
| `resetCategorySchema(slug)` | `/api/database/builder/category/{slug}/reset` | DELETE |
|
|
233
|
+
| `resetTenantSchema(slug, tenant)` | `/api/database/builder/category/{slug}/tenants/{t}/reset` | DELETE |
|
|
234
|
+
| `deleteMigration(slug, versionId)` | `/api/database/builder/category/{slug}/migrations/{id}` | DELETE |
|
|
235
|
+
|
|
236
|
+
**Root shortcuts:** `dominus.addTable()`, `dominus.deleteTable()`, `dominus.addColumn()`, `dominus.deleteColumn()`
|
|
237
|
+
|
|
238
|
+
---
|
|
239
|
+
|
|
240
|
+
## 9. open (Scribe Open)
|
|
241
|
+
|
|
242
|
+
Direct database access for advanced use cases.
|
|
243
|
+
|
|
244
|
+
| Method | Endpoint | HTTP |
|
|
245
|
+
|--------|----------|------|
|
|
246
|
+
| `dsn()` | `/api/scribe/open/dsn` | GET |
|
|
247
|
+
| `execute(sql, params?)` | `/api/scribe/open/execute` | POST |
|
|
248
|
+
|
|
249
|
+
---
|
|
250
|
+
|
|
251
|
+
## 10. logs (Herald)
|
|
252
|
+
|
|
253
|
+
Structured logging via Logs Worker. `useGateway: true`.
|
|
254
|
+
|
|
255
|
+
| Method | Endpoint | HTTP |
|
|
256
|
+
|--------|----------|------|
|
|
257
|
+
| `debug(msg, context?, category?)` | `/api/logs/ingest` | POST |
|
|
258
|
+
| `info(msg, context?, category?)` | `/api/logs/ingest` | POST |
|
|
259
|
+
| `notice(msg, context?, category?)` | `/api/logs/ingest` | POST |
|
|
260
|
+
| `warn(msg, context?, category?)` | `/api/logs/ingest` | POST |
|
|
261
|
+
| `error(msg, context?, options?)` | `/api/logs/ingest` | POST |
|
|
262
|
+
| `critical(msg, context?, options?)` | `/api/logs/ingest` | POST |
|
|
263
|
+
| `tail(options?)` | `/api/logs/tail` | GET |
|
|
264
|
+
| `query(options?)` | `/api/logs/tail` | GET |
|
|
265
|
+
| `batch(events)` | `/api/logs/ingest` | POST |
|
|
266
|
+
|
|
267
|
+
All log methods auto-capture callsite (file, function) from the stack. Batch max: 100 events.
|
|
268
|
+
|
|
269
|
+
---
|
|
270
|
+
|
|
271
|
+
## 11. health
|
|
272
|
+
|
|
273
|
+
Service health checks. No authentication required for `check()`.
|
|
274
|
+
|
|
275
|
+
| Method | Endpoint | HTTP |
|
|
276
|
+
|--------|----------|------|
|
|
277
|
+
| `check()` | `/api/health` | GET (direct fetch, no base64) |
|
|
278
|
+
| `ping()` | `/api/health/ping` | GET |
|
|
279
|
+
| `warmup()` | `/api/health/warmup` | GET |
|
|
280
|
+
|
|
281
|
+
---
|
|
282
|
+
|
|
283
|
+
## 12. courier (Courier)
|
|
284
|
+
|
|
285
|
+
Email delivery via Postmark templates.
|
|
286
|
+
|
|
287
|
+
| Method | Endpoint | HTTP |
|
|
288
|
+
|--------|----------|------|
|
|
289
|
+
| `send(templateAlias, to, from, model, options?)` | `/api/courier/send` | POST |
|
|
290
|
+
| `sendWelcome(to, from, params)` | `/api/courier/send` | POST |
|
|
291
|
+
| `sendPasswordReset(to, from, params)` | `/api/courier/send` | POST |
|
|
292
|
+
| `sendEmailVerification(to, from, params)` | `/api/courier/send` | POST |
|
|
293
|
+
| `sendInvitation(to, from, params)` | `/api/courier/send` | POST |
|
|
294
|
+
|
|
295
|
+
---
|
|
296
|
+
|
|
297
|
+
## 13. ai (Agent Runtime)
|
|
298
|
+
|
|
299
|
+
LLM agent execution, completions, RAG, artifacts, speech, workflows. `useGateway: true`.
|
|
300
|
+
|
|
301
|
+
**Agent execution:** `runAgent(params)`, `streamAgent(params)`, `runAgentAsync(params)`
|
|
302
|
+
**LLM completions:** `complete(params)`, `completeStream(params)`
|
|
303
|
+
**Speech:** `stt(audio, options?)`, `tts(text, options?)`
|
|
304
|
+
**Setup:** `setup(options?)`
|
|
305
|
+
|
|
306
|
+
**Sub-namespaces:**
|
|
307
|
+
- `ai.rag.*` -- RAG corpus management (ensure, upsert, search, list, ingest, getStats)
|
|
308
|
+
- `ai.artifacts.*` -- Artifact CRUD (create, fetch, list, delete)
|
|
309
|
+
- `ai.results.*` -- Async task polling (poll)
|
|
310
|
+
- `ai.workflow.*` -- Workflow execution (execute, cancel, list)
|
|
311
|
+
- `ai.tools.*` -- Tool registry (list, enable, disable)
|
|
312
|
+
|
|
313
|
+
---
|
|
314
|
+
|
|
315
|
+
## 14. workflow (Workflow Manager)
|
|
316
|
+
|
|
317
|
+
Workflow CRUD, categories/pipelines, templates, tools, execution. `useGateway: true`.
|
|
318
|
+
|
|
319
|
+
### Workflows
|
|
320
|
+
| Method | Endpoint | HTTP |
|
|
321
|
+
|--------|----------|------|
|
|
322
|
+
| `save(options)` | `/api/workflow/workflows` | POST |
|
|
323
|
+
| `get(id, options?)` | `/api/workflow/workflows/{id}` | GET |
|
|
324
|
+
| `list(options?)` | `/api/workflow/workflows` | GET |
|
|
325
|
+
| `delete(id)` | `/api/workflow/workflows/{id}` | DELETE |
|
|
326
|
+
|
|
327
|
+
### Categories
|
|
328
|
+
| Method | Endpoint | HTTP |
|
|
329
|
+
|--------|----------|------|
|
|
330
|
+
| `createCategory(options)` | `/api/workflow/categories` | POST |
|
|
331
|
+
| `getCategory(id, options?)` | `/api/workflow/categories/{id}` | GET |
|
|
332
|
+
| `listCategories(options?)` | `/api/workflow/categories` | GET |
|
|
333
|
+
| `deleteCategory(id)` | `/api/workflow/categories/{id}` | DELETE |
|
|
334
|
+
| `addToCategory(catId, wfId, pos?)` | `/api/workflow/categories/{id}/workflows` | POST |
|
|
335
|
+
| `removeFromCategory(catId, wfId)` | `/api/workflow/categories/{id}/workflows/{wfId}` | DELETE |
|
|
336
|
+
| `reorderCategory(catId, order)` | `/api/workflow/categories/{id}/workflows/order` | PUT |
|
|
337
|
+
|
|
338
|
+
### Templates
|
|
339
|
+
| Method | Endpoint | HTTP |
|
|
340
|
+
|--------|----------|------|
|
|
341
|
+
| `listTemplates()` | `/api/workflow/templates` | GET |
|
|
342
|
+
| `getTemplate(id, options?)` | `/api/workflow/templates/{id}` | GET |
|
|
343
|
+
| `copyTemplate(id, options?)` | `/api/workflow/templates/{id}/copy` | POST |
|
|
344
|
+
|
|
345
|
+
### Execution
|
|
346
|
+
| Method | Endpoint | HTTP |
|
|
347
|
+
|--------|----------|------|
|
|
348
|
+
| `execute(wfId, context?)` | `/api/workflow/execute/workflow` | POST |
|
|
349
|
+
| `executeAsync(wfId, options?)` | `/api/workflow/execute/workflow` | POST |
|
|
350
|
+
| `executeCategory(catId, options?)` | `/api/workflow/execute/category` | POST |
|
|
351
|
+
|
|
352
|
+
### Tools
|
|
353
|
+
| Method | Endpoint | HTTP |
|
|
354
|
+
|--------|----------|------|
|
|
355
|
+
| `listTools(options?)` | `/api/workflow/tools` | GET |
|
|
356
|
+
| `getTool(id)` | `/api/workflow/tools/{id}` | GET |
|
|
357
|
+
| `registerTool(options)` | `/api/workflow/tools` | POST |
|
|
358
|
+
| `updateTool(id, options)` | `/api/workflow/tools/{id}` | PUT |
|
|
359
|
+
| `deleteTool(id)` | `/api/workflow/tools/{id}` | DELETE |
|
|
360
|
+
| `enableTool(id)` | `/api/workflow/tools/{id}/enable` | POST |
|
|
361
|
+
| `disableTool(id)` | `/api/workflow/tools/{id}/disable` | POST |
|
|
362
|
+
|
|
363
|
+
### Admin
|
|
364
|
+
| Method | Endpoint | HTTP |
|
|
365
|
+
|--------|----------|------|
|
|
366
|
+
| `seed(options?)` | `/api/workflow/admin/seed` | POST |
|
|
367
|
+
| `factoryReset(options)` | `/api/workflow/admin/factory-reset` | POST |
|
|
368
|
+
|
|
369
|
+
---
|
|
370
|
+
|
|
371
|
+
## 15. stt / oracle (Oracle)
|
|
372
|
+
|
|
373
|
+
Streaming speech-to-text with WebSocket and VAD. Browser-side only.
|
|
374
|
+
|
|
375
|
+
```typescript
|
|
376
|
+
const session = dominus.stt.createSession(userJwt);
|
|
377
|
+
session.onUtterance = (text) => handleText(text);
|
|
378
|
+
session.onVADStateChange = (state) => updateUI(state);
|
|
379
|
+
await session.start();
|
|
380
|
+
// ... user speaks ...
|
|
381
|
+
await session.stop();
|
|
382
|
+
```
|
|
383
|
+
|
|
384
|
+
VAD states: `IDLE` -> `ARMED` -> `SPEAKING` -> `TRAILING`
|
|
385
|
+
|
|
386
|
+
---
|
|
387
|
+
|
|
388
|
+
## 16. admin
|
|
389
|
+
|
|
390
|
+
Infrastructure operations with elevated privileges. Uses `neondb_owner` credentials.
|
|
391
|
+
|
|
392
|
+
| Method | Endpoint | HTTP | Notes |
|
|
393
|
+
|--------|----------|------|-------|
|
|
394
|
+
| `reseedAdminCategory()` | `/api/admin/reseed-admin-category` | POST | Idempotent, seeds baseline data |
|
|
395
|
+
| `resetAdminCategory()` | `/api/admin/reset-admin-category` | DELETE | DESTRUCTIVE: drops tenant_admin |
|
|
396
|
+
| `exportTokens()` | `/api/admin/tokens/export` | GET | `useGateway: true` |
|
|
397
|
+
| `seedKV()` | `/api/admin/kv/seed` | POST | `useGateway: true` |
|
|
398
|
+
|
|
399
|
+
---
|
|
400
|
+
|
|
401
|
+
## 17. sync (Sync Worker)
|
|
402
|
+
|
|
403
|
+
KV cache synchronization. `useGateway: true`. Requires admin system level.
|
|
404
|
+
|
|
405
|
+
| Method | Endpoint | HTTP |
|
|
406
|
+
|--------|----------|------|
|
|
407
|
+
| `triggerSync()` | `/api/sync/` | POST |
|
|
408
|
+
| `getHealth()` | `/api/sync/health` | GET |
|
|
409
|
+
|
|
410
|
+
---
|
|
411
|
+
|
|
412
|
+
## 18. artifacts (Artifact Worker)
|
|
413
|
+
|
|
414
|
+
Temporary artifact storage (Redis < 1MB, B2 >= 1MB). `useGateway: true`.
|
|
415
|
+
|
|
416
|
+
| Method | Endpoint | HTTP |
|
|
417
|
+
|--------|----------|------|
|
|
418
|
+
| `list(options?)` | `/api/artifact/list` | POST |
|
|
419
|
+
| `getHealth()` | `/api/artifact/health` | GET |
|
|
420
|
+
| `store(options)` | `/api/artifact/store` | POST |
|
|
421
|
+
| `retrieve(key)` | `/api/artifact/retrieve` | POST |
|
|
422
|
+
| `delete(key)` | `/api/artifact/delete` | POST |
|
|
423
|
+
| `cleanup(options?)` | `/api/artifact/cleanup` | POST |
|
|
424
|
+
|
|
425
|
+
---
|
|
426
|
+
|
|
427
|
+
## 19. jobs (Job Worker) + processor (Job Processor)
|
|
428
|
+
|
|
429
|
+
### jobs -- `useGateway: true`
|
|
430
|
+
| Method | Endpoint | HTTP |
|
|
431
|
+
|--------|----------|------|
|
|
432
|
+
| `enqueue(jobType, payload)` | `/api/job/enqueue` | POST |
|
|
433
|
+
| `getStatus(jobId)` | `/api/job/status` | POST |
|
|
434
|
+
| `getResult(jobId, timeoutMs?)` | `/api/job/result` | POST |
|
|
435
|
+
| `listDeadLetterJobs(jobType?)` | `/api/job/dead-letter` | POST |
|
|
436
|
+
| `retryJob(jobId)` | `/api/job/dead-letter` | POST |
|
|
437
|
+
| `discardJob(jobId)` | `/api/job/dead-letter` | POST |
|
|
438
|
+
| `list(options?)` | `/api/job/list` | POST |
|
|
439
|
+
| `getHealth()` | `/api/job/health` | GET |
|
|
440
|
+
|
|
441
|
+
Job types: `db_query`, `db_ddl`, `db_migration`, `file_upload`, `workflow_exec`
|
|
442
|
+
|
|
443
|
+
### processor -- `useGateway: true`
|
|
444
|
+
| Method | Endpoint | HTTP |
|
|
445
|
+
|--------|----------|------|
|
|
446
|
+
| `getHealth()` | `/api/processor/health` | GET |
|
|
447
|
+
| `processAll(jobType?)` | `/api/processor/process` | POST |
|
|
448
|
+
| `processOne(jobType?)` | `/api/processor/process-one` | POST |
|
|
449
|
+
|
|
450
|
+
---
|
|
451
|
+
|
|
452
|
+
## Summary
|
|
453
|
+
|
|
454
|
+
| # | Namespace | Backend Service | Endpoint Prefix | Gateway |
|
|
455
|
+
|---|-----------|----------------|-----------------|---------|
|
|
456
|
+
| 1 | secrets | Warden | `/api/warden/` | default |
|
|
457
|
+
| 2 | db | Scribe (DB Worker) | `/api/database/`, `/api/provision/` | default |
|
|
458
|
+
| 3 | secure | Scribe | `/api/scribe/data/` | default |
|
|
459
|
+
| 4 | redis | Whisperer | `/api/whisperer/` | default |
|
|
460
|
+
| 5 | files | Archivist (B2 Worker) | `/api/archivist/` | default |
|
|
461
|
+
| 6 | auth | Guardian | `/api/guardian/` | default |
|
|
462
|
+
| 7 | portal | Portal | `/api/portal/` | default |
|
|
463
|
+
| 8 | ddl | Smith | `/api/smith/`, `/api/database/builder/` | default |
|
|
464
|
+
| 9 | open | Scribe Open | `/api/scribe/open/` | default |
|
|
465
|
+
| 10 | logs | Herald (Logs Worker) | `/api/logs/` | explicit |
|
|
466
|
+
| 11 | health | Gateway | `/api/health/` | default |
|
|
467
|
+
| 12 | courier | Courier | `/api/courier/` | default |
|
|
468
|
+
| 13 | ai | Agent Runtime | `/api/agent/` | explicit |
|
|
469
|
+
| 14 | workflow | Workflow Manager | `/api/workflow/` | explicit |
|
|
470
|
+
| 15 | stt | Oracle | WebSocket | n/a |
|
|
471
|
+
| 16 | admin | Admin | `/api/admin/` | mixed |
|
|
472
|
+
| 17 | sync | Sync Worker | `/api/sync/` | explicit |
|
|
473
|
+
| 18 | artifacts | Artifact Worker | `/api/artifact/` | explicit |
|
|
474
|
+
| 19 | jobs+processor | Job Worker + Processor | `/api/job/`, `/api/processor/` | explicit |
|
|
475
|
+
|
|
476
|
+
**"explicit"** = passes `useGateway: true` in request options.
|
|
477
|
+
**"default"** = uses `BASE_URL` (which defaults to gateway).
|
|
478
|
+
|
|
479
|
+
Total: **19 namespaces**, **200+ methods** covering data, auth, AI, infrastructure, and admin operations.
|
package/package.json
CHANGED
package/docs/development.md
DELETED
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
# Development
|
|
2
|
-
|
|
3
|
-
## Requirements
|
|
4
|
-
- Node.js 18+ (native fetch)
|
|
5
|
-
- TypeScript 5.6+
|
|
6
|
-
|
|
7
|
-
## Commands
|
|
8
|
-
```bash
|
|
9
|
-
npm install
|
|
10
|
-
npm run lint # type-check
|
|
11
|
-
npm run test # node --test
|
|
12
|
-
npm run build # tsc
|
|
13
|
-
```
|
|
14
|
-
|
|
15
|
-
## Publishing
|
|
16
|
-
Publishing is handled by GitHub Actions on branch push:
|
|
17
|
-
- `development` -> publishes as `dominus-sdk-nodejs-dev`
|
|
18
|
-
- `staging` -> publishes as `dominus-sdk-nodejs-staging`
|
|
19
|
-
- `production` -> publishes as `dominus-sdk-nodejs`
|
|
20
|
-
|
|
21
|
-
Before publishing:
|
|
22
|
-
1. Bump `package.json` version
|
|
23
|
-
2. Ensure `dist/` builds cleanly
|
|
24
|
-
3. Update docs under `docs/`
|
|
25
|
-
|
|
26
|
-
## Adding APIs
|
|
27
|
-
- Add methods in the relevant `src/namespaces/*.ts` file
|
|
28
|
-
- Export types and helpers from `src/index.ts`
|
|
29
|
-
- Use `client.request()` for JSON, `streamRequest()` for SSE, `binaryUpload/Download()` for bytes
|
|
30
|
-
- Always set `method: 'GET'` for GET endpoints
|
package/docs/namespaces.md
DELETED
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
# Namespaces
|
|
2
|
-
|
|
3
|
-
## Core Services
|
|
4
|
-
- `secrets` (Warden): secrets CRUD
|
|
5
|
-
- `db` (Scribe): database CRUD, filters, pagination
|
|
6
|
-
- `secure` (Scribe): secure-table access with audit `reason` + `actor`
|
|
7
|
-
- `redis` (Whisperer): cache, locks, counters, hashes (TTL required)
|
|
8
|
-
- `files` (Archivist): upload/download/list/move/update metadata
|
|
9
|
-
- `auth` (Guardian): users, roles, scopes, tenants, pages/navigation
|
|
10
|
-
- `ddl` (Smith): schema DDL, migrations, provisioning
|
|
11
|
-
- `logs` (Herald): structured logs + queries
|
|
12
|
-
- `portal` (Portal): user login, sessions, profile, navigation
|
|
13
|
-
- `courier` (Courier): email delivery
|
|
14
|
-
- `open` (Scribe Open): direct SQL execution / DSN
|
|
15
|
-
- `health`: service health/ping/warmup
|
|
16
|
-
|
|
17
|
-
## AI + Orchestration
|
|
18
|
-
- `ai.runAgent`, `ai.streamAgent`, `ai.runAgentAsync`
|
|
19
|
-
- `ai.complete`, `ai.completeStream` (multi-provider LLM completions)
|
|
20
|
-
- `ai.rag` (list/ensure/stats/upsert/search/ingest)
|
|
21
|
-
- `ai.artifacts` (create/fetch/list/delete)
|
|
22
|
-
- `ai.results` (async result polling)
|
|
23
|
-
- `ai.workflow` (workflow orchestration in agent-runtime)
|
|
24
|
-
- `ai.tools` (tool registry, default-deny)
|
|
25
|
-
- `ai.stt` / `ai.tts` (speech services)
|
|
26
|
-
- `ai.setup` (pre-flight session setup)
|
|
27
|
-
|
|
28
|
-
## Workflow Manager
|
|
29
|
-
- `workflow` namespace manages workflow CRUD, categories, templates, and execution
|
|
30
|
-
- List calls use canonical GET routes:
|
|
31
|
-
- `workflow.list()` -> `/api/workflow/workflows`
|
|
32
|
-
- `workflow.listCategories()` -> `/api/workflow/categories`
|
|
33
|
-
|
|
34
|
-
## Streaming STT
|
|
35
|
-
- `stt` (Oracle) creates streaming transcription sessions with VAD
|
|
36
|
-
|
|
37
|
-
## Admin
|
|
38
|
-
- `admin.reseedAdminCategory()` and `admin.resetAdminCategory()` (destructive)
|