nubase_cli 0.1.0 → 0.1.2

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.
@@ -5,14 +5,15 @@ Use this reference when designing or changing Nubase database tables, RLS polici
5
5
  ## Tools
6
6
 
7
7
  - `fetch_docs({ "topic": "database" })`
8
+ - `db_export_schema({ schema?, tables?, includeDrop? })` — export table DDL to inspect structure (read-only; `schema` defaults to `public`)
9
+ - `db_list_migrations({ limit? })` — read the audit trail of schema changes applied through `sql_execute` (read-only)
8
10
  - `rest_select(table, query?)`
9
11
  - `sql_dry_run(sql)`
10
12
  - `sql_execute(sql)`
11
- - schema inspection tools when available from the Nubase MCP server
12
13
 
13
14
  ## Database Workflow
14
15
 
15
- 1. Inspect existing schema before changing it.
16
+ 1. Inspect existing schema before changing it — call `db_export_schema` (default schema `public`, or pass `tables` to narrow). Treat its DDL as the source of truth for what already exists.
16
17
  2. Prefer additive changes.
17
18
  3. Add primary keys and timestamps where appropriate.
18
19
  4. Add indexes for common filters.
@@ -21,6 +22,87 @@ Use this reference when designing or changing Nubase database tables, RLS polici
21
22
  7. Execute only when the user requested implementation or gave approval.
22
23
  8. Store durable schema decisions with `memory_write`.
23
24
 
25
+ ## Schema Change Audit Trail
26
+
27
+ Every successful `sql_execute` that changes schema (risk `SCHEMA_WRITE` or `DANGEROUS`) is recorded to an append-only `nubase.migrations` table (timestamp, risk, statement count, the SQL text, and `agent_id`/`run_id`/`user_id` when set). Pure reads and data writes are not recorded.
28
+
29
+ - Review history with `db_list_migrations({ limit? })` — most recent first. Use it to see what changed, when, and by which agent, or to replay the SQL elsewhere.
30
+ - The successful `sql_execute` result includes `migrationRecorded: true`; if recording fails it returns `migrationRecorded: false` with `migrationError` but the DDL itself still succeeded.
31
+ - Disable the trail with `NUBASE_RECORD_MIGRATIONS=false`.
32
+
33
+ This is a lightweight audit/replay log, not a full migration engine — there is no diffing, versioning of files, or rollback.
34
+
35
+ ## Worked Example: a `todos` table end to end
36
+
37
+ This is the full path from empty schema to a working, user-scoped table.
38
+
39
+ **1. Inspect what exists** (don't guess):
40
+
41
+ ```text
42
+ nubase_overview() # tables, buckets, users, gateway keys, permissions in one call
43
+ # or, just the schema:
44
+ db_export_schema({ "schema": "public" })
45
+ ```
46
+
47
+ **2. Draft the DDL** — primary key, owner column, timestamps, an index, and RLS:
48
+
49
+ ```sql
50
+ create table public.todos (
51
+ id uuid primary key default gen_random_uuid(),
52
+ user_id uuid not null references auth.users (id) on delete cascade,
53
+ title text not null,
54
+ done boolean not null default false,
55
+ created_at timestamptz not null default now()
56
+ );
57
+ create index todos_user_id_idx on public.todos (user_id);
58
+
59
+ alter table public.todos enable row level security;
60
+
61
+ create policy "owner can read" on public.todos for select using (auth.uid() = user_id);
62
+ create policy "owner can insert" on public.todos for insert with check (auth.uid() = user_id);
63
+ create policy "owner can modify" on public.todos for update using (auth.uid() = user_id);
64
+ create policy "owner can delete" on public.todos for delete using (auth.uid() = user_id);
65
+ ```
66
+
67
+ **3. Classify before running:**
68
+
69
+ ```text
70
+ sql_dry_run({ "sql": "<the DDL above>" })
71
+ # -> { "success": true, "risk": "SCHEMA_WRITE", "statementCount": 6, "executable": true }
72
+ ```
73
+
74
+ **4. Execute** (only after the user asked you to implement; needs `NUBASE_ALLOW_SQL_EXECUTE=true`):
75
+
76
+ ```text
77
+ sql_execute({ "sql": "<the DDL above>" })
78
+ ```
79
+
80
+ **5. Read and write through `/rest/v1` from app code** — RLS scopes rows to the JWT's user automatically:
81
+
82
+ ```http
83
+ POST /rest/v1/todos
84
+ apikey: <anon or authenticated key>
85
+ Authorization: Bearer <user JWT>
86
+ Content-Type: application/json
87
+ Prefer: return=representation
88
+
89
+ { "title": "Buy milk" }
90
+ ```
91
+
92
+ Response:
93
+
94
+ ```json
95
+ [{ "id": "9b2...c1", "user_id": "f3a...07", "title": "Buy milk", "done": false, "created_at": "2026-06-03T10:00:00Z" }]
96
+ ```
97
+
98
+ ```http
99
+ GET /rest/v1/todos?select=*&done=eq.false&order=created_at.desc
100
+ PATCH /rest/v1/todos?id=eq.9b2...c1 Body: { "done": true }
101
+ DELETE /rest/v1/todos?id=eq.9b2...c1
102
+ ```
103
+
104
+ `user_id` is omitted on insert on purpose — set it server-side via a column default or a trigger, or let the app pass it; never trust a client-supplied owner id.
105
+
24
106
  ## REST API Patterns
25
107
 
26
108
  Use `/rest/v1` for generated app data access:
@@ -58,6 +140,4 @@ Destructive operations requiring confirmation:
58
140
  - deleting schemas
59
141
  - resetting Memory
60
142
 
61
- ## Supabase Compatibility
62
-
63
- Treat `/rest/v1` as PostgREST-style and Supabase-compatible for common workflows. Do not claim full `supabase-js` compatibility unless a test covers the exact SDK behavior.
143
+ > `/rest/v1` is PostgREST-style and Supabase-compatible for common workflows; don't assume full `supabase-js` compatibility without a test.
@@ -39,6 +39,16 @@ Dangerous SQL remains blocked unless:
39
39
  NUBASE_ALLOW_DANGEROUS_SQL=true
40
40
  ```
41
41
 
42
+ ## Admin Write Guardrails
43
+
44
+ Backend-ops write tools (create/delete bucket, create/delete user, issue/revoke gateway key) are disabled unless:
45
+
46
+ ```bash
47
+ NUBASE_ALLOW_ADMIN_WRITE=true
48
+ ```
49
+
50
+ When disabled they return `{ success: false, error }` without calling the backend. Read tools (`*_list_*`, `db_export_schema`, `gateway_usage`) are always available. A freshly issued gateway key is returned once — treat it as a secret and never write it to Memory or generated code.
51
+
42
52
  Ask for explicit confirmation before:
43
53
 
44
54
  - `drop`