datanotes 3.3.1 → 3.4.0
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/SECURITY.md +5 -3
- package/dist/api/extensions.cjs +141 -5
- package/dist/api/extensions.js +141 -5
- package/dist/api/index.cjs +141 -5
- package/dist/api/index.js +141 -5
- package/dist/api/mcp.cjs +141 -5
- package/dist/api/mcp.js +141 -5
- package/dist/datanotes.cjs +1672 -600
- package/dist/docs/administration/extensions.md +2 -2
- package/dist/docs/api/operations/add_column.md +1 -0
- package/dist/docs/api/operations/check_table.md +1 -0
- package/dist/docs/api/operations/create_table.md +1 -0
- package/dist/docs/api/operations/describe_database.md +2 -0
- package/dist/docs/api/operations/describe_history.md +1 -0
- package/dist/docs/api/operations/describe_semantic_index.md +1 -0
- package/dist/docs/api/operations/describe_table.md +1 -0
- package/dist/docs/api/operations/graph_neighbors.md +1 -0
- package/dist/docs/api/operations/graph_path.md +1 -0
- package/dist/docs/api/operations/graph_traverse.md +1 -0
- package/dist/docs/api/operations/infer_table.md +1 -0
- package/dist/docs/api/operations/list_changes.md +1 -0
- package/dist/docs/api/operations/list_folder.md +1 -0
- package/dist/docs/api/operations/list_link_targets.md +1 -0
- package/dist/docs/api/operations/list_migrations.md +1 -0
- package/dist/docs/api/operations/list_tables.md +2 -0
- package/dist/docs/api/operations/list_webhooks.md +1 -0
- package/dist/docs/api/operations/read_note.md +1 -0
- package/dist/docs/api/operations/search.md +39 -0
- package/dist/docs/api/operations/search_notes.md +1 -0
- package/dist/docs/api/operations/select_rows.md +1 -0
- package/dist/docs/api/operations/semantic_search.md +1 -0
- package/dist/docs/api/operations/table_changes.md +1 -0
- package/dist/docs/api/operations/tags/queries.md +1 -0
- package/dist/docs/api/operations/tags/tokens.md +1 -1
- package/dist/docs/api/operations/tokens_create.md +1 -0
- package/dist/docs/api/operations/tokens_update.md +2 -1
- package/dist/docs/api.md +5 -4
- package/dist/docs/develop/build-an-app.md +2 -1
- package/dist/docs/develop/change-feed-and-webhooks.md +1 -1
- package/dist/docs/develop/http-api.md +1 -1
- package/dist/docs/guides/data-quality/check-constraints.md +10 -10
- package/dist/docs/guides/data-quality/hand-edits.md +8 -8
- package/dist/docs/guides/database-objects/bases.md +11 -11
- package/dist/docs/guides/database-objects/catalogs-and-schemas.md +10 -10
- package/dist/docs/guides/database-objects/columns.md +241 -38
- package/dist/docs/guides/database-objects/relations.md +28 -28
- package/dist/docs/guides/database-objects/tables.md +26 -26
- package/dist/docs/guides/database-objects/views.md +19 -19
- package/dist/docs/guides/history/change-data-feed.md +34 -34
- package/dist/docs/guides/history/journal-and-undo.md +12 -12
- package/dist/docs/guides/history/restore.md +20 -20
- package/dist/docs/guides/history/table-history.md +31 -31
- package/dist/docs/guides/read-and-write/automatic-links.md +15 -15
- package/dist/docs/guides/read-and-write/import-notes.md +20 -20
- package/dist/docs/guides/read-and-write/write-rows.md +10 -10
- package/dist/docs/guides/search/hybrid.md +162 -0
- package/dist/docs/guides/search/text.md +1 -1
- package/dist/docs/guides/security/security-model.md +5 -3
- package/dist/docs/guides/security/tokens.md +121 -8
- package/dist/docs/reference/cli.md +1 -1
- package/dist/docs/reference/glossary.md +1 -1
- package/dist/docs/reference/operations/auxiliary.md +2 -2
- package/dist/docs/reference/operations/queries.md +16 -0
- package/dist/docs/reference/operations/schema.md +2 -2
- package/dist/docs/reference/operations.md +2 -1
- package/dist/docs/release-notes.md +43 -0
- package/dist/docs/start/connect-agents.md +10 -3
- package/package.json +1 -1
|
@@ -111,7 +111,7 @@ Each extension gets a named token, `ext-<name>`. The token has three limits:
|
|
|
111
111
|
|
|
112
112
|
* It writes only the tables of the roles in the manifest’s `permissions.write`.
|
|
113
113
|
* It never changes the schema and never undoes. The installer changes the schema with the owner’s token.
|
|
114
|
-
* It reads every table,
|
|
114
|
+
* It reads every table: the installer gives it no `read` patterns. You may limit it, as [Limit what a token can read](https://datanotes.dev/guides/security/tokens/#change-what-a-token-reads) shows.
|
|
115
115
|
|
|
116
116
|
The tools of an extension run when an agent calls them. Before a tool that writes runs, the MCP server checks the agent’s own token. If that token may not write the tool’s tables, the call fails. A read-only client cannot write through an extension. To allow the call, add the table to the `write` patterns of the client’s token. Or call the tool with a token that may write.
|
|
117
117
|
|
|
@@ -127,7 +127,7 @@ The code runs inside the MCP server’s process. It is trusted code, not a sandb
|
|
|
127
127
|
Known limits in this version:
|
|
128
128
|
|
|
129
129
|
* **No isolation.** Extension code has the privileges of the MCP server’s process.
|
|
130
|
-
* **No read
|
|
130
|
+
* **No read patterns from the installer.** The token of an extension reads every table. If you limit its `read`, cover the tables it writes. An install or update that writes a table outside `read` is refused with 400: widen `read` first.
|
|
131
131
|
* **No data-converting migrations.** A migration lists operations. It cannot run code to convert rows.
|
|
132
132
|
|
|
133
133
|
## Update an extension
|
|
@@ -12,6 +12,7 @@ a column whose meaning an existing column (name/label/aliases/description) alrea
|
|
|
12
12
|
Column names are permanent identifiers; only `rename_column` changes them.
|
|
13
13
|
Enum columns: `values` and, for each, its meaning in `value_descriptions` (`{"stated": "the user said it", …}`): describe_table shows them and a refused value lists them.
|
|
14
14
|
Generated link columns: `generated: "link({occurred_at:YYYY-MM-DD})"` with `ref` = the days table links each row to the row of `ref` named by the template (its folder read from the schema; the target may not exist yet).
|
|
15
|
+
Generated aggregates of a json column holding a list of objects (integer or number columns; avg: number): `count(feeds)`, `count(feeds.min)` (the items with a min), `sum(feeds.min)`, `avg(…)`, `min(…)`, `max(…)`, with an optional filter on one field: `count(feeds, side = "left")`, `sum(feeds.min, min > 0)` (=, !=, <, <=, >, >=; "text", a number, true or false). Recomputed on every write; no list: count and sum 0, avg/min/max empty; a field that is not a number: empty.
|
|
15
16
|
Filtered link targets (link columns): `ref_where` (a `where` every target must match) and `ref_by` (a column of the row picks the target level: `{"column": "kind", "levels": ["area", "project", "workstream"]}` or `{"column": "kind", "map": {"area": null, "project": ["area"]}}`; null = top level, no link; `target_column` when the target names it differently: an enum target column must have every value the map allows, a string one takes any value). A link to no row of the table, or to the row itself, is refused too. Existing rows that break them refuse the change; `list_link_targets` lists the valid targets of a row.
|
|
16
17
|
Acyclic links: `acyclic: true` on a link (or list of links) to the table itself refuses every write that closes a cycle, on either side of an `inverse`; refused while existing rows form one (they are listed).
|
|
17
18
|
|
|
@@ -22,6 +22,7 @@ columns, CHECK constraints, those that follow links included, filtered link targ
|
|
|
22
22
|
| 200 | Done. | `object` (application/json) |
|
|
23
23
|
| 400 | Bad input: the body is not a JSON object, or an argument is unknown, missing or of the wrong type. | `Error` (application/json) |
|
|
24
24
|
| 401 | Missing or wrong bearer token. | `Error` (application/json) |
|
|
25
|
+
| 403 | A named token whose `read` patterns do not cover the table, view or note the request names (such as `token cook may not read personal.health.weight`). Sets it did not name (listings, bases, search, the graph, the change feed) are filtered instead. | `Error` (application/json) |
|
|
25
26
|
| 404 | Unknown table, view, migration, note or folder. | `Error` (application/json) |
|
|
26
27
|
| 409 | Ambiguous table name: it matches several tables (`paths` or `tables` lists them). | `AmbiguousName` (application/json) |
|
|
27
28
|
| 500 | Unexpected error. | `Error` (application/json) |
|
|
@@ -30,6 +30,7 @@ digits, `_` (no dots: pass the catalog and the schema as their own arguments).
|
|
|
30
30
|
describe_table return them, alter_table changes them.
|
|
31
31
|
Enum columns: `values` and, for each, its meaning in `value_descriptions` (`{"stated": "the user said it", …}`): describe_table shows them and a refused value lists them.
|
|
32
32
|
Generated link columns: `generated: "link({occurred_at:YYYY-MM-DD})"` with `ref` = the days table links each row to the row of `ref` named by the template (its folder read from the schema; the target may not exist yet).
|
|
33
|
+
Generated aggregates of a json column holding a list of objects (integer or number columns; avg: number): `count(feeds)`, `count(feeds.min)` (the items with a min), `sum(feeds.min)`, `avg(…)`, `min(…)`, `max(…)`, with an optional filter on one field: `count(feeds, side = "left")`, `sum(feeds.min, min > 0)` (=, !=, <, <=, >, >=; "text", a number, true or false). Recomputed on every write; no list: count and sum 0, avg/min/max empty; a field that is not a number: empty.
|
|
33
34
|
Filtered link targets (link columns): `ref_where` (a `where` every target must match) and `ref_by` (a column of the row picks the target level: `{"column": "kind", "levels": ["area", "project", "workstream"]}` or `{"column": "kind", "map": {"area": null, "project": ["area"]}}`; null = top level, no link; `target_column` when the target names it differently: an enum target column must have every value the map allows, a string one takes any value). A link to no row of the table, or to the row itself, is refused too. Existing rows that break them refuse the change; `list_link_targets` lists the valid targets of a row.
|
|
34
35
|
|
|
35
36
|
The schema changes only through operations like this one: never edit metastore.yaml by hand (no validation, no undo).
|
|
@@ -10,6 +10,7 @@ journal folder, `bases` (shared column sets and the tables using them), `catalog
|
|
|
10
10
|
catalogs and schemas show their `comment` (set with `comment_on`). A table or base defined before
|
|
11
11
|
descriptions were required has `missing_descriptions`: what lacks one, for alter_table / alter_column
|
|
12
12
|
(define_base for a base) to fill, so every table and column says what it holds.
|
|
13
|
+
A token with `read` patterns sees only the tables, views and bases it may read.
|
|
13
14
|
|
|
14
15
|
## Request body
|
|
15
16
|
|
|
@@ -25,6 +26,7 @@ descriptions were required has `missing_descriptions`: what lacks one, for alter
|
|
|
25
26
|
| 200 | Done. | `DatabaseDescription` (application/json) |
|
|
26
27
|
| 400 | Bad input: the body is not a JSON object, or an argument is unknown, missing or of the wrong type. | `Error` (application/json) |
|
|
27
28
|
| 401 | Missing or wrong bearer token. | `Error` (application/json) |
|
|
29
|
+
| 403 | A named token whose `read` patterns do not cover the table, view or note the request names (such as `token cook may not read personal.health.weight`). Sets it did not name (listings, bases, search, the graph, the change feed) are filtered instead. | `Error` (application/json) |
|
|
28
30
|
| 500 | Unexpected error. | `Error` (application/json) |
|
|
29
31
|
|
|
30
32
|
The schemas named here are in [openapi.json](https://datanotes.dev/openapi.json) (`components.schemas`).
|
|
@@ -33,6 +33,7 @@ from it (`timestamp`, or `before_migration` with a `migration_id` or a `batch`).
|
|
|
33
33
|
| 200 | Done. | `object` (application/json) |
|
|
34
34
|
| 400 | Bad input: the body is not a JSON object, or an argument is unknown, missing or of the wrong type. | `Error` (application/json) |
|
|
35
35
|
| 401 | Missing or wrong bearer token. | `Error` (application/json) |
|
|
36
|
+
| 403 | A named token whose `read` patterns do not cover the table, view or note the request names (such as `token cook may not read personal.health.weight`). Sets it did not name (listings, bases, search, the graph, the change feed) are filtered instead. | `Error` (application/json) |
|
|
36
37
|
| 404 | Unknown table, view, migration, note or folder. | `Error` (application/json) |
|
|
37
38
|
| 409 | Ambiguous table name: it matches several tables (`paths` or `tables` lists them). | `AmbiguousName` (application/json) |
|
|
38
39
|
| 500 | Unexpected error. | `Error` (application/json) |
|
|
@@ -19,6 +19,7 @@ The semantic search index: `enabled`, `provider`, `model`, `files`, `passages`,
|
|
|
19
19
|
| 200 | Done. | `SemanticStatus` (application/json) |
|
|
20
20
|
| 400 | Bad input: the body is not a JSON object, or an argument is unknown, missing or of the wrong type. | `Error` (application/json) |
|
|
21
21
|
| 401 | Missing or wrong bearer token. | `Error` (application/json) |
|
|
22
|
+
| 403 | A named token whose `read` patterns do not cover the table, view or note the request names (such as `token cook may not read personal.health.weight`). Sets it did not name (listings, bases, search, the graph, the change feed) are filtered instead. | `Error` (application/json) |
|
|
22
23
|
| 500 | Unexpected error. | `Error` (application/json) |
|
|
23
24
|
|
|
24
25
|
The schemas named here are in [openapi.json](https://datanotes.dev/openapi.json) (`components.schemas`).
|
|
@@ -31,6 +31,7 @@ defined before descriptions were required), names what lacks one: write them wit
|
|
|
31
31
|
| 200 | Done. | `object` (application/json) |
|
|
32
32
|
| 400 | Bad input: the body is not a JSON object, or an argument is unknown, missing or of the wrong type. | `Error` (application/json) |
|
|
33
33
|
| 401 | Missing or wrong bearer token. | `Error` (application/json) |
|
|
34
|
+
| 403 | A named token whose `read` patterns do not cover the table, view or note the request names (such as `token cook may not read personal.health.weight`). Sets it did not name (listings, bases, search, the graph, the change feed) are filtered instead. | `Error` (application/json) |
|
|
34
35
|
| 404 | Unknown table, view, migration, note or folder. | `Error` (application/json) |
|
|
35
36
|
| 409 | Ambiguous table name: it matches several tables (`paths` or `tables` lists them). | `AmbiguousName` (application/json) |
|
|
36
37
|
| 500 | Unexpected error. | `Error` (application/json) |
|
|
@@ -27,6 +27,7 @@ start notes). Edges are labelled with their link column (`people`, `event`, …)
|
|
|
27
27
|
| 200 | Done. | `object` (application/json) |
|
|
28
28
|
| 400 | Bad input: the body is not a JSON object, or an argument is unknown, missing or of the wrong type. | `Error` (application/json) |
|
|
29
29
|
| 401 | Missing or wrong bearer token. | `Error` (application/json) |
|
|
30
|
+
| 403 | A named token whose `read` patterns do not cover the table, view or note the request names (such as `token cook may not read personal.health.weight`). Sets it did not name (listings, bases, search, the graph, the change feed) are filtered instead. | `Error` (application/json) |
|
|
30
31
|
| 404 | Unknown table, view, migration, note or folder. | `Error` (application/json) |
|
|
31
32
|
| 409 | Ambiguous table name: it matches several tables (`paths` or `tables` lists them). | `AmbiguousName` (application/json) |
|
|
32
33
|
| 500 | Unexpected error. | `Error` (application/json) |
|
|
@@ -25,6 +25,7 @@ and/or `{"tables": [...]}`): `found`, `length` and `path`: the steps (`from`, `l
|
|
|
25
25
|
| 200 | Done. | `object` (application/json) |
|
|
26
26
|
| 400 | Bad input: the body is not a JSON object, or an argument is unknown, missing or of the wrong type. | `Error` (application/json) |
|
|
27
27
|
| 401 | Missing or wrong bearer token. | `Error` (application/json) |
|
|
28
|
+
| 403 | A named token whose `read` patterns do not cover the table, view or note the request names (such as `token cook may not read personal.health.weight`). Sets it did not name (listings, bases, search, the graph, the change feed) are filtered instead. | `Error` (application/json) |
|
|
28
29
|
| 404 | Unknown table, view, migration, note or folder. | `Error` (application/json) |
|
|
29
30
|
| 409 | Ambiguous table name: it matches several tables (`paths` or `tables` lists them). | `AmbiguousName` (application/json) |
|
|
30
31
|
| 500 | Unexpected error. | `Error` (application/json) |
|
|
@@ -36,6 +36,7 @@ with Alice: from `{"table": "person", "where": {"name": "Alice"}}`, direction `i
|
|
|
36
36
|
| 200 | Done. | `object` (application/json) |
|
|
37
37
|
| 400 | Bad input: the body is not a JSON object, or an argument is unknown, missing or of the wrong type. | `Error` (application/json) |
|
|
38
38
|
| 401 | Missing or wrong bearer token. | `Error` (application/json) |
|
|
39
|
+
| 403 | A named token whose `read` patterns do not cover the table, view or note the request names (such as `token cook may not read personal.health.weight`). Sets it did not name (listings, bases, search, the graph, the change feed) are filtered instead. | `Error` (application/json) |
|
|
39
40
|
| 404 | Unknown table, view, migration, note or folder. | `Error` (application/json) |
|
|
40
41
|
| 409 | Ambiguous table name: it matches several tables (`paths` or `tables` lists them). | `AmbiguousName` (application/json) |
|
|
41
42
|
| 500 | Unexpected error. | `Error` (application/json) |
|
|
@@ -36,6 +36,7 @@ distinct values (default 12), each used twice on average, short texts.
|
|
|
36
36
|
| 200 | Done. | `object` (application/json) |
|
|
37
37
|
| 400 | Bad input: the body is not a JSON object, or an argument is unknown, missing or of the wrong type. | `Error` (application/json) |
|
|
38
38
|
| 401 | Missing or wrong bearer token. | `Error` (application/json) |
|
|
39
|
+
| 403 | A named token whose `read` patterns do not cover the table, view or note the request names (such as `token cook may not read personal.health.weight`). Sets it did not name (listings, bases, search, the graph, the change feed) are filtered instead. | `Error` (application/json) |
|
|
39
40
|
| 404 | Unknown table, view, migration, note or folder. | `Error` (application/json) |
|
|
40
41
|
| 409 | Ambiguous table name: it matches several tables (`paths` or `tables` lists them). | `AmbiguousName` (application/json) |
|
|
41
42
|
| 500 | Unexpected error. | `Error` (application/json) |
|
|
@@ -30,6 +30,7 @@ older changes were dropped: re-read the tables. `where` filters rows as in selec
|
|
|
30
30
|
| 200 | Done. | `object` (application/json) |
|
|
31
31
|
| 400 | Bad input: the body is not a JSON object, or an argument is unknown, missing or of the wrong type. | `Error` (application/json) |
|
|
32
32
|
| 401 | Missing or wrong bearer token. | `Error` (application/json) |
|
|
33
|
+
| 403 | A named token whose `read` patterns do not cover the table, view or note the request names (such as `token cook may not read personal.health.weight`). Sets it did not name (listings, bases, search, the graph, the change feed) are filtered instead. | `Error` (application/json) |
|
|
33
34
|
| 500 | Unexpected error. | `Error` (application/json) |
|
|
34
35
|
|
|
35
36
|
The schemas named here are in [openapi.json](https://datanotes.dev/openapi.json) (`components.schemas`).
|
|
@@ -21,6 +21,7 @@ error.
|
|
|
21
21
|
| 200 | Done. | `object` (application/json) |
|
|
22
22
|
| 400 | Bad input: the body is not a JSON object, or an argument is unknown, missing or of the wrong type. | `Error` (application/json) |
|
|
23
23
|
| 401 | Missing or wrong bearer token. | `Error` (application/json) |
|
|
24
|
+
| 403 | A named token whose `read` patterns do not cover the table, view or note the request names (such as `token cook may not read personal.health.weight`). Sets it did not name (listings, bases, search, the graph, the change feed) are filtered instead. | `Error` (application/json) |
|
|
24
25
|
| 404 | Unknown table, view, migration, note or folder. | `Error` (application/json) |
|
|
25
26
|
| 409 | Ambiguous table name: it matches several tables (`paths` or `tables` lists them). | `AmbiguousName` (application/json) |
|
|
26
27
|
| 500 | Unexpected error. | `Error` (application/json) |
|
|
@@ -37,6 +37,7 @@ reason, for a level the map lacks); write a row's `link` as the value.
|
|
|
37
37
|
| 200 | Done. | `object` (application/json) |
|
|
38
38
|
| 400 | Bad input: the body is not a JSON object, or an argument is unknown, missing or of the wrong type. | `Error` (application/json) |
|
|
39
39
|
| 401 | Missing or wrong bearer token. | `Error` (application/json) |
|
|
40
|
+
| 403 | A named token whose `read` patterns do not cover the table, view or note the request names (such as `token cook may not read personal.health.weight`). Sets it did not name (listings, bases, search, the graph, the change feed) are filtered instead. | `Error` (application/json) |
|
|
40
41
|
| 404 | Unknown table, view, migration, note or folder. | `Error` (application/json) |
|
|
41
42
|
| 409 | Ambiguous table name: it matches several tables (`paths` or `tables` lists them). | `AmbiguousName` (application/json) |
|
|
42
43
|
| 500 | Unexpected error. | `Error` (application/json) |
|
|
@@ -28,6 +28,7 @@ engine's store, outside the vault (`store:journal/`); entries older than 90 days
|
|
|
28
28
|
| 200 | Done. | `object` (application/json) |
|
|
29
29
|
| 400 | Bad input: the body is not a JSON object, or an argument is unknown, missing or of the wrong type. | `Error` (application/json) |
|
|
30
30
|
| 401 | Missing or wrong bearer token. | `Error` (application/json) |
|
|
31
|
+
| 403 | A named token whose `read` patterns do not cover the table, view or note the request names (such as `token cook may not read personal.health.weight`). Sets it did not name (listings, bases, search, the graph, the change feed) are filtered instead. | `Error` (application/json) |
|
|
31
32
|
| 404 | Unknown table, view, migration, note or folder. | `Error` (application/json) |
|
|
32
33
|
| 409 | Ambiguous table name: it matches several tables (`paths` or `tables` lists them). | `AmbiguousName` (application/json) |
|
|
33
34
|
| 500 | Unexpected error. | `Error` (application/json) |
|
|
@@ -8,6 +8,7 @@ when declared, `description`, `aliases` (other words for what it records) and `t
|
|
|
8
8
|
defined in `metastore.yaml` (catalog → schema → table): read it freely, but it is read-only for
|
|
9
9
|
agents and changes only through the schema operations (create_table, add_column, …). Returns `{tables, views}`: `views` lists the stored views (same fields, no
|
|
10
10
|
path): select them like tables. `system.information_schema` is read with `select_rows`.
|
|
11
|
+
A token with `read` patterns sees only the tables and views it may read.
|
|
11
12
|
|
|
12
13
|
Call this first to find the table for what the user reports (match their words against
|
|
13
14
|
name, description and aliases), and before creating tables or columns so you reuse existing
|
|
@@ -27,6 +28,7 @@ ones instead of creating duplicates.
|
|
|
27
28
|
| 200 | Done. | `object` (application/json) |
|
|
28
29
|
| 400 | Bad input: the body is not a JSON object, or an argument is unknown, missing or of the wrong type. | `Error` (application/json) |
|
|
29
30
|
| 401 | Missing or wrong bearer token. | `Error` (application/json) |
|
|
31
|
+
| 403 | A named token whose `read` patterns do not cover the table, view or note the request names (such as `token cook may not read personal.health.weight`). Sets it did not name (listings, bases, search, the graph, the change feed) are filtered instead. | `Error` (application/json) |
|
|
30
32
|
| 500 | Unexpected error. | `Error` (application/json) |
|
|
31
33
|
|
|
32
34
|
The schemas named here are in [openapi.json](https://datanotes.dev/openapi.json) (`components.schemas`).
|
|
@@ -18,6 +18,7 @@ Webhooks of the change feed: id, url, filter (tables, ops, columns, exclude_acto
|
|
|
18
18
|
| 200 | Done. | `object` (application/json) |
|
|
19
19
|
| 400 | Bad input: the body is not a JSON object, or an argument is unknown, missing or of the wrong type. | `Error` (application/json) |
|
|
20
20
|
| 401 | Missing or wrong bearer token. | `Error` (application/json) |
|
|
21
|
+
| 403 | A named token whose `read` patterns do not cover the table, view or note the request names (such as `token cook may not read personal.health.weight`). Sets it did not name (listings, bases, search, the graph, the change feed) are filtered instead. | `Error` (application/json) |
|
|
21
22
|
| 500 | Unexpected error. | `Error` (application/json) |
|
|
22
23
|
|
|
23
24
|
The schemas named here are in [openapi.json](https://datanotes.dev/openapi.json) (`components.schemas`).
|
|
@@ -22,6 +22,7 @@ an error. `path`: vault-relative, forward slashes.
|
|
|
22
22
|
| 200 | Done. | `object` (application/json) |
|
|
23
23
|
| 400 | Bad input: the body is not a JSON object, or an argument is unknown, missing or of the wrong type. | `Error` (application/json) |
|
|
24
24
|
| 401 | Missing or wrong bearer token. | `Error` (application/json) |
|
|
25
|
+
| 403 | A named token whose `read` patterns do not cover the table, view or note the request names (such as `token cook may not read personal.health.weight`). Sets it did not name (listings, bases, search, the graph, the change feed) are filtered instead. | `Error` (application/json) |
|
|
25
26
|
| 404 | Unknown table, view, migration, note or folder. | `Error` (application/json) |
|
|
26
27
|
| 409 | Ambiguous table name: it matches several tables (`paths` or `tables` lists them). | `AmbiguousName` (application/json) |
|
|
27
28
|
| 500 | Unexpected error. | `Error` (application/json) |
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# Search the notes by their words and, when semantic search is on, by their meaning:
|
|
2
|
+
|
|
3
|
+
`POST /datanotes/operations/search/` (operation `search`)
|
|
4
|
+
|
|
5
|
+
Search the notes by their words and, when semantic search is on, by their meaning:
|
|
6
|
+
`{query, results: [{path, table?, score, heading, snippet, matched_by}], meaning}`, one result per
|
|
7
|
+
note, best first. It always works: with semantic search off it ranks by words alone (BM25:
|
|
8
|
+
rare words count more; a word in the note's name or properties counts more), with it on it fuses
|
|
9
|
+
both rankings (Reciprocal Rank Fusion), so a note found only by its words or only by its meaning
|
|
10
|
+
is still there. `matched_by` says which (`words`, `meaning`); `meaning` is `on`, `off` or `failed`
|
|
11
|
+
(the embedding provider failed: words only, `meaning_error` says why). Query syntax as search_docs:
|
|
12
|
+
`"a phrase"` and `+word` must appear, `-word` must not (both rankings); words in any language,
|
|
13
|
+
case and accents ignored, no stemming. Filters: `tables` (qualified or short names), `folder`,
|
|
14
|
+
`min_score` (the meaning ranking's cosine floor). `limit`: default 10, max 100. Then read_note /
|
|
15
|
+
select_rows for the details.
|
|
16
|
+
|
|
17
|
+
## Request body
|
|
18
|
+
|
|
19
|
+
`application/json`, required
|
|
20
|
+
|
|
21
|
+
| Property | Type | Required | Default | Description |
|
|
22
|
+
| --- | --- | --- | --- | --- |
|
|
23
|
+
| `query` | `string` | yes | | |
|
|
24
|
+
| `limit` | `integer` | no | `10` | |
|
|
25
|
+
| `tables` | `string[] \| null` | no | `null` | |
|
|
26
|
+
| `folder` | `string \| null` | no | `null` | |
|
|
27
|
+
| `min_score` | `number \| null` | no | `null` | |
|
|
28
|
+
|
|
29
|
+
## Responses
|
|
30
|
+
|
|
31
|
+
| Status | Description | Body |
|
|
32
|
+
| --- | --- | --- |
|
|
33
|
+
| 200 | Done. | `object` (application/json) |
|
|
34
|
+
| 400 | Bad input: the body is not a JSON object, or an argument is unknown, missing or of the wrong type. | `Error` (application/json) |
|
|
35
|
+
| 401 | Missing or wrong bearer token. | `Error` (application/json) |
|
|
36
|
+
| 403 | A named token whose `read` patterns do not cover the table, view or note the request names (such as `token cook may not read personal.health.weight`). Sets it did not name (listings, bases, search, the graph, the change feed) are filtered instead. | `Error` (application/json) |
|
|
37
|
+
| 500 | Unexpected error. | `Error` (application/json) |
|
|
38
|
+
|
|
39
|
+
The schemas named here are in [openapi.json](https://datanotes.dev/openapi.json) (`components.schemas`).
|
|
@@ -23,6 +23,7 @@ matches per note. `context_length`: characters of context on each side (default
|
|
|
23
23
|
| 200 | Done. | `object` (application/json) |
|
|
24
24
|
| 400 | Bad input: the body is not a JSON object, or an argument is unknown, missing or of the wrong type. | `Error` (application/json) |
|
|
25
25
|
| 401 | Missing or wrong bearer token. | `Error` (application/json) |
|
|
26
|
+
| 403 | A named token whose `read` patterns do not cover the table, view or note the request names (such as `token cook may not read personal.health.weight`). Sets it did not name (listings, bases, search, the graph, the change feed) are filtered instead. | `Error` (application/json) |
|
|
26
27
|
| 500 | Unexpected error. | `Error` (application/json) |
|
|
27
28
|
|
|
28
29
|
The schemas named here are in [openapi.json](https://datanotes.dev/openapi.json) (`components.schemas`).
|
|
@@ -54,6 +54,7 @@ on the base's columns, each row tagged `_source` with its table.
|
|
|
54
54
|
| 200 | Done. | `object` (application/json) |
|
|
55
55
|
| 400 | Bad input: the body is not a JSON object, or an argument is unknown, missing or of the wrong type. | `Error` (application/json) |
|
|
56
56
|
| 401 | Missing or wrong bearer token. | `Error` (application/json) |
|
|
57
|
+
| 403 | A named token whose `read` patterns do not cover the table, view or note the request names (such as `token cook may not read personal.health.weight`). Sets it did not name (listings, bases, search, the graph, the change feed) are filtered instead. | `Error` (application/json) |
|
|
57
58
|
| 404 | Unknown table, view, migration, note or folder. | `Error` (application/json) |
|
|
58
59
|
| 409 | Ambiguous table name: it matches several tables (`paths` or `tables` lists them). | `AmbiguousName` (application/json) |
|
|
59
60
|
| 500 | Unexpected error. | `Error` (application/json) |
|
|
@@ -29,6 +29,7 @@ the engine settings.
|
|
|
29
29
|
| 200 | Done. | `object` (application/json) |
|
|
30
30
|
| 400 | Bad input: the body is not a JSON object, or an argument is unknown, missing or of the wrong type. | `Error` (application/json) |
|
|
31
31
|
| 401 | Missing or wrong bearer token. | `Error` (application/json) |
|
|
32
|
+
| 403 | A named token whose `read` patterns do not cover the table, view or note the request names (such as `token cook may not read personal.health.weight`). Sets it did not name (listings, bases, search, the graph, the change feed) are filtered instead. | `Error` (application/json) |
|
|
32
33
|
| 500 | Unexpected error. | `Error` (application/json) |
|
|
33
34
|
|
|
34
35
|
The schemas named here are in [openapi.json](https://datanotes.dev/openapi.json) (`components.schemas`).
|
|
@@ -24,6 +24,7 @@ Use it to answer "what changed since …" without diffing full tables.
|
|
|
24
24
|
| 200 | Done. | `object` (application/json) |
|
|
25
25
|
| 400 | Bad input: the body is not a JSON object, or an argument is unknown, missing or of the wrong type. | `Error` (application/json) |
|
|
26
26
|
| 401 | Missing or wrong bearer token. | `Error` (application/json) |
|
|
27
|
+
| 403 | A named token whose `read` patterns do not cover the table, view or note the request names (such as `token cook may not read personal.health.weight`). Sets it did not name (listings, bases, search, the graph, the change feed) are filtered instead. | `Error` (application/json) |
|
|
27
28
|
| 404 | Unknown table, view, migration, note or folder. | `Error` (application/json) |
|
|
28
29
|
| 409 | Ambiguous table name: it matches several tables (`paths` or `tables` lists them). | `AmbiguousName` (application/json) |
|
|
29
30
|
| 500 | Unexpected error. | `Error` (application/json) |
|
|
@@ -10,6 +10,7 @@ Operations that read rows and notes: select_rows, link targets, text and semanti
|
|
|
10
10
|
- [Query rows: `{table, total, rows: [{path, ...}]}`. `table` may be a view,](https://datanotes.dev/api/operations/select_rows/): `POST /datanotes/operations/select_rows/`
|
|
11
11
|
- [The rows a link column may point to, for one row: what an agent or a picker offers before writing](https://datanotes.dev/api/operations/list_link_targets/): `POST /datanotes/operations/list_link_targets/`
|
|
12
12
|
- [Find notes by meaning, not exact words: `{query, results: [{path, score, heading, snippet,](https://datanotes.dev/api/operations/semantic_search/): `POST /datanotes/operations/semantic_search/`
|
|
13
|
+
- [Search the notes by their words and, when semantic search is on, by their meaning:](https://datanotes.dev/api/operations/search/): `POST /datanotes/operations/search/`
|
|
13
14
|
- [Direct neighbours of notes: what they link to (`out`) and what links to them (`in`,](https://datanotes.dev/api/operations/graph_neighbors/): `POST /datanotes/operations/graph_neighbors/`
|
|
14
15
|
- [Breadth-first walk over links from `from_nodes` (`{"paths": [...]}`, `{"table", "where"}` and/or `{"tables": [...]}`).](https://datanotes.dev/api/operations/graph_traverse/): `POST /datanotes/operations/graph_traverse/`
|
|
15
16
|
- [Shortest chain of links between two sets of notes (each `{"paths": [...]}`, `{"table", "where"}`](https://datanotes.dev/api/operations/graph_path/): `POST /datanotes/operations/graph_path/`
|
|
@@ -8,6 +8,6 @@ Named tokens and their permissions; what MCP servers report about their agents'
|
|
|
8
8
|
- [List the named tokens (owner only).](https://datanotes.dev/api/operations/tokens_list/): `POST /datanotes/tokens/`
|
|
9
9
|
- [The calling token's own entry (a named token; 400 for the owner).](https://datanotes.dev/api/operations/tokens_me/): `POST /datanotes/tokens/me/`
|
|
10
10
|
- [Create a named token (owner only). Returns the token once.](https://datanotes.dev/api/operations/tokens_create/): `POST /datanotes/tokens/create/`
|
|
11
|
-
- [Change a named token. A token may change its own description and autolink default; permissions are the owner's.](https://datanotes.dev/api/operations/tokens_update/): `POST /datanotes/tokens/update/`
|
|
11
|
+
- [Change a named token. A token may change its own description and autolink default; permissions (`read`, `write`, `ddl`, `maintain`) are the owner's.](https://datanotes.dev/api/operations/tokens_update/): `POST /datanotes/tokens/update/`
|
|
12
12
|
- [Revoke a named token (owner only): it stops working at once.](https://datanotes.dev/api/operations/tokens_delete/): `POST /datanotes/tokens/delete/`
|
|
13
13
|
- [Give a named token a new value (owner only): the old one stops working.](https://datanotes.dev/api/operations/tokens_rotate/): `POST /datanotes/tokens/rotate/`
|
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
| --- | --- | --- | --- | --- |
|
|
17
17
|
| `name` | `string` | yes | | Kebab-case; the journal records it as `auth`. `owner` is reserved. |
|
|
18
18
|
| `description` | `string` | no | | |
|
|
19
|
+
| `read` | `string[]` | no | | Tables the token may read, as patterns like `write`'s. Absent (or with `*`): every table. It must cover every `write` pattern, and stay absent with `ddl` or `maintain` (400 otherwise). |
|
|
19
20
|
| `write` | `string[]` | no | | Tables the token may write: catalog.schema.table, catalog.schema.*, catalog.* or *. |
|
|
20
21
|
| `ddl` | `boolean` | no | | May the token change the schema? |
|
|
21
22
|
| `maintain` | `boolean` | no | | May the token also undo, restore, vacuum, configure and rebuild the semantic index? (For an agent's own token.) |
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Change a named token. A token may change its own description and autolink default; permissions are the owner's.
|
|
1
|
+
# Change a named token. A token may change its own description and autolink default; permissions (`read`, `write`, `ddl`, `maintain`) are the owner's.
|
|
2
2
|
|
|
3
3
|
`POST /datanotes/tokens/update/` (operation `tokens_update`)
|
|
4
4
|
|
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
| --- | --- | --- | --- | --- |
|
|
17
17
|
| `name` | `string` | no | | Owner only (a named token updates itself). |
|
|
18
18
|
| `description` | `string` | no | | An empty string removes it. |
|
|
19
|
+
| `read` | `array \| null` | no | | The tables the token may read; null reads every table again. Checked against `write`, `ddl` and `maintain` as on create. |
|
|
19
20
|
| `write` | `string[]` | no | | |
|
|
20
21
|
| `ddl` | `boolean` | no | | |
|
|
21
22
|
| `maintain` | `boolean` | no | | |
|
package/dist/docs/api.md
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
# Datanotes HTTP API
|
|
2
2
|
|
|
3
|
-
> OpenAPI 3.1.0 description of the Datanotes 3.
|
|
3
|
+
> OpenAPI 3.1.0 description of the Datanotes 3.4.0 HTTP API: https://datanotes.dev/openapi.json
|
|
4
4
|
|
|
5
5
|
Database of Markdown notes: tables of notes, rows, queries, history, a change feed and the vault's notes.
|
|
6
6
|
|
|
7
7
|
**Operations**: every operation is `POST /datanotes/operations/<name>/`, its body the operation's arguments (the same names as the MCP tool of the same name). An unknown argument is refused (400) with the closest real one.
|
|
8
8
|
|
|
9
|
-
**Authentication**: every route but `GET /`, this document and `/datanotes/docs` needs `Authorization: Bearer <token>`: the owner's token (`httpServerToken` in the settings: everything) or a named token (`/datanotes/tokens/create/`: reads
|
|
9
|
+
**Authentication**: every route but `GET /`, this document and `/datanotes/docs` needs `Authorization: Bearer <token>`: the owner's token (`httpServerToken` in the settings: everything) or a named token (`/datanotes/tokens/create/`: reads the tables in its `read` patterns, every table without them; writes the tables in its `write` patterns, changes the schema with `ddl`; the engine's administration stays the owner's: 403 otherwise).
|
|
10
10
|
|
|
11
11
|
**Actor**: send `X-Datanotes-Actor: {"harness": …, "model": …, "session": …}` (JSON) to record on whose behalf a write is made; the journal adds the credential (`auth`: `owner`, or the named token's name), which the client cannot claim.
|
|
12
12
|
|
|
13
|
-
**Errors**: `{error}` with 400 (bad input), 401 (missing or wrong token), 403 (a named token beyond its permissions), 404 (unknown table, view, migration or note), 409 (ambiguous table name), 500. A refused write answers 422 (409 for undo) with the operation's result, `ok: false`: nothing was written.
|
|
13
|
+
**Errors**: `{error}` with 400 (bad input), 401 (missing or wrong token), 403 (a named token beyond its permissions, or a read of a table outside its `read` patterns), 404 (unknown table, view, migration or note), 409 (ambiguous table name), 500. A refused write answers 422 (409 for undo) with the operation's result, `ok: false`: nothing was written.
|
|
14
14
|
|
|
15
15
|
## Servers
|
|
16
16
|
|
|
@@ -68,6 +68,7 @@ Operations that read rows and notes: select_rows, link targets, text and semanti
|
|
|
68
68
|
- [Query rows: `{table, total, rows: [{path, ...}]}`. `table` may be a view,](https://datanotes.dev/api/operations/select_rows/): `POST /datanotes/operations/select_rows/`
|
|
69
69
|
- [The rows a link column may point to, for one row: what an agent or a picker offers before writing](https://datanotes.dev/api/operations/list_link_targets/): `POST /datanotes/operations/list_link_targets/`
|
|
70
70
|
- [Find notes by meaning, not exact words: `{query, results: [{path, score, heading, snippet,](https://datanotes.dev/api/operations/semantic_search/): `POST /datanotes/operations/semantic_search/`
|
|
71
|
+
- [Search the notes by their words and, when semantic search is on, by their meaning:](https://datanotes.dev/api/operations/search/): `POST /datanotes/operations/search/`
|
|
71
72
|
- [Direct neighbours of notes: what they link to (`out`) and what links to them (`in`,](https://datanotes.dev/api/operations/graph_neighbors/): `POST /datanotes/operations/graph_neighbors/`
|
|
72
73
|
- [Breadth-first walk over links from `from_nodes` (`{"paths": [...]}`, `{"table", "where"}` and/or `{"tables": [...]}`).](https://datanotes.dev/api/operations/graph_traverse/): `POST /datanotes/operations/graph_traverse/`
|
|
73
74
|
- [Shortest chain of links between two sets of notes (each `{"paths": [...]}`, `{"table", "where"}`](https://datanotes.dev/api/operations/graph_path/): `POST /datanotes/operations/graph_path/`
|
|
@@ -116,7 +117,7 @@ Named tokens and their permissions; what MCP servers report about their agents'
|
|
|
116
117
|
- [List the named tokens (owner only).](https://datanotes.dev/api/operations/tokens_list/): `POST /datanotes/tokens/`
|
|
117
118
|
- [The calling token's own entry (a named token; 400 for the owner).](https://datanotes.dev/api/operations/tokens_me/): `POST /datanotes/tokens/me/`
|
|
118
119
|
- [Create a named token (owner only). Returns the token once.](https://datanotes.dev/api/operations/tokens_create/): `POST /datanotes/tokens/create/`
|
|
119
|
-
- [Change a named token. A token may change its own description and autolink default; permissions are the owner's.](https://datanotes.dev/api/operations/tokens_update/): `POST /datanotes/tokens/update/`
|
|
120
|
+
- [Change a named token. A token may change its own description and autolink default; permissions (`read`, `write`, `ddl`, `maintain`) are the owner's.](https://datanotes.dev/api/operations/tokens_update/): `POST /datanotes/tokens/update/`
|
|
120
121
|
- [Revoke a named token (owner only): it stops working at once.](https://datanotes.dev/api/operations/tokens_delete/): `POST /datanotes/tokens/delete/`
|
|
121
122
|
- [Give a named token a new value (owner only): the old one stops working.](https://datanotes.dev/api/operations/tokens_rotate/): `POST /datanotes/tokens/rotate/`
|
|
122
123
|
|
|
@@ -64,13 +64,14 @@ The app has four small files in `src/`: the client, the films, the change feed a
|
|
|
64
64
|
console.log(r.token);
|
|
65
65
|
```
|
|
66
66
|
|
|
67
|
-
The token can read every table
|
|
67
|
+
The request passes no `read`, so the token can read every table. It writes rows of `watch` and `film` only. It can’t change the schema, undo, or touch `actor`. The engine lists it like this:
|
|
68
68
|
|
|
69
69
|
```json
|
|
70
70
|
{
|
|
71
71
|
"name": "film-night",
|
|
72
72
|
"description": "Logs film nights and picks the next film",
|
|
73
73
|
"write": ["main.public.watch", "main.public.film"],
|
|
74
|
+
"read": ["*"],
|
|
74
75
|
"ddl": false
|
|
75
76
|
}
|
|
76
77
|
```
|
|
@@ -67,4 +67,4 @@ A 2xx answer moves the webhook on. Any other answer is retried with backoff, fro
|
|
|
67
67
|
|
|
68
68
|
## Choose the feed or a webhook
|
|
69
69
|
|
|
70
|
-
A named token can read the feed, while only the owner creates webhooks. So a program with its own token long-polls or streams the feed, as [Build an app on Datanotes](https://datanotes.dev/develop/build-an-app/) does, and a service the owner sets up receives a webhook.
|
|
70
|
+
A named token can read the feed, while only the owner creates webhooks. So a program with its own token long-polls or streams the feed, as [Build an app on Datanotes](https://datanotes.dev/develop/build-an-app/) does, and a service the owner sets up receives a webhook. A token with `read` patterns sees only the events of its readable tables, and only its own tool calls.
|
|
@@ -58,7 +58,7 @@ Errors come back as JSON `{"error": "…", "hint": "…", "docs": "…"}`: what
|
|
|
58
58
|
|
|
59
59
|
* **400**: bad input
|
|
60
60
|
* **401**: missing or wrong token
|
|
61
|
-
* **403**: a named token beyond its permissions
|
|
61
|
+
* **403**: a named token beyond its permissions, such as a table outside its `read` or `write` patterns
|
|
62
62
|
* **404**: unknown table, view, migration or note
|
|
63
63
|
* **409**: ambiguous table name
|
|
64
64
|
* **500**: an unexpected error, or a write that failed partway and couldn’t be [rolled back](https://datanotes.dev/guides/history/journal-and-undo/#the-engine-rolls-back-a-write-it-cannot-finish)
|
|
@@ -29,7 +29,7 @@ Answer:
|
|
|
29
29
|
"commits": [
|
|
30
30
|
{ "table": "diary.classics.film", "version": 8, "operation": "ADD CONSTRAINT" }
|
|
31
31
|
],
|
|
32
|
-
"migration_id": "
|
|
32
|
+
"migration_id": "20261024T063921-add_constraint-add-constraint-rated_when_watc"
|
|
33
33
|
}
|
|
34
34
|
```
|
|
35
35
|
|
|
@@ -86,7 +86,7 @@ Answer:
|
|
|
86
86
|
"files_created": 1,
|
|
87
87
|
"planned_creates": ["datanotes/diary/classics/film/His Girl Friday.md"],
|
|
88
88
|
"commits": [{ "table": "diary.classics.film", "version": 10, "operation": "WRITE" }],
|
|
89
|
-
"migration_id": "
|
|
89
|
+
"migration_id": "20261024T063921-insert_row-insert-into-film"
|
|
90
90
|
}
|
|
91
91
|
```
|
|
92
92
|
|
|
@@ -108,7 +108,7 @@ Answer:
|
|
|
108
108
|
"commits": [
|
|
109
109
|
{ "table": "diary.classics.film", "version": 11, "operation": "DROP CONSTRAINT" }
|
|
110
110
|
],
|
|
111
|
-
"migration_id": "
|
|
111
|
+
"migration_id": "20261024T063921-drop_constraint-drop-constraint-at_most_three_"
|
|
112
112
|
}
|
|
113
113
|
```
|
|
114
114
|
|
|
@@ -149,7 +149,7 @@ Answer:
|
|
|
149
149
|
"commits": [
|
|
150
150
|
{ "table": "main.public.genre", "version": 4, "operation": "ADD CONSTRAINT" }
|
|
151
151
|
],
|
|
152
|
-
"migration_id": "
|
|
152
|
+
"migration_id": "20261024T063906-add_constraint-add-constraint-parent_by_level"
|
|
153
153
|
}
|
|
154
154
|
```
|
|
155
155
|
|
|
@@ -228,34 +228,34 @@ Answer:
|
|
|
228
228
|
"ok": true,
|
|
229
229
|
"op": "batch",
|
|
230
230
|
"dry_run": false,
|
|
231
|
-
"migration_id": "
|
|
231
|
+
"migration_id": "20261024T063906-batch-add-the-silent-era-and-slapsti",
|
|
232
232
|
"steps": [
|
|
233
233
|
{
|
|
234
234
|
"index": 0,
|
|
235
235
|
"op": "insert_row",
|
|
236
236
|
"ok": true,
|
|
237
|
-
"migration_id": "
|
|
237
|
+
"migration_id": "20261024T063906-insert_row-insert-into-genre",
|
|
238
238
|
"result": {
|
|
239
239
|
"ok": true,
|
|
240
240
|
"op": "insert_row",
|
|
241
241
|
"files_created": 1,
|
|
242
242
|
"planned_creates": ["datanotes/main/public/genre/Silent cinema.md"],
|
|
243
243
|
"commits": [{ "table": "main.public.genre", "version": 5, "operation": "WRITE" }],
|
|
244
|
-
"migration_id": "
|
|
244
|
+
"migration_id": "20261024T063906-insert_row-insert-into-genre"
|
|
245
245
|
}
|
|
246
246
|
},
|
|
247
247
|
{
|
|
248
248
|
"index": 1,
|
|
249
249
|
"op": "insert_row",
|
|
250
250
|
"ok": true,
|
|
251
|
-
"migration_id": "
|
|
251
|
+
"migration_id": "20261024T063906-insert_row-insert-into-genre-2",
|
|
252
252
|
"result": {
|
|
253
253
|
"ok": true,
|
|
254
254
|
"op": "insert_row",
|
|
255
255
|
"files_created": 1,
|
|
256
256
|
"planned_creates": ["datanotes/main/public/genre/Slapstick comedy.md"],
|
|
257
257
|
"commits": [{ "table": "main.public.genre", "version": 6, "operation": "WRITE" }],
|
|
258
|
-
"migration_id": "
|
|
258
|
+
"migration_id": "20261024T063906-insert_row-insert-into-genre-2"
|
|
259
259
|
}
|
|
260
260
|
}
|
|
261
261
|
]
|
|
@@ -343,7 +343,7 @@ Answer:
|
|
|
343
343
|
}
|
|
344
344
|
],
|
|
345
345
|
"commits": [{ "table": "main.public.genre", "version": 7, "operation": "UPDATE" }],
|
|
346
|
-
"migration_id": "
|
|
346
|
+
"migration_id": "20261024T063906-update_row-update-genre"
|
|
347
347
|
}
|
|
348
348
|
```
|
|
349
349
|
|
|
@@ -35,7 +35,7 @@ You edit `datanotes/main/public/genre/Silent film.md` by hand, outside the engin
|
|
|
35
35
|
```markdown
|
|
36
36
|
---
|
|
37
37
|
table: main.public.genre
|
|
38
|
-
id:
|
|
38
|
+
id: 01a16ca2-6b55-78e6-a355-a9890248c59d
|
|
39
39
|
name: Silent film
|
|
40
40
|
kind: cinema
|
|
41
41
|
parent: "[[Cinema]]"
|
|
@@ -152,7 +152,7 @@ Answer:
|
|
|
152
152
|
}
|
|
153
153
|
],
|
|
154
154
|
"commits": [{ "table": "main.public.genre", "version": 9, "operation": "UPDATE" }],
|
|
155
|
-
"migration_id": "
|
|
155
|
+
"migration_id": "20261024T063907-update_row-update-genre"
|
|
156
156
|
}
|
|
157
157
|
```
|
|
158
158
|
|
|
@@ -167,7 +167,7 @@ You edit `datanotes/main/public/watch/2026-10-03T2130.md` by hand, outside the e
|
|
|
167
167
|
```markdown
|
|
168
168
|
---
|
|
169
169
|
table: main.public.watch
|
|
170
|
-
id:
|
|
170
|
+
id: 01a16ca2-6327-778b-85f9-d586c0c733a8
|
|
171
171
|
film: His Girl Friday
|
|
172
172
|
occurred_at: 2026-10-03T21:30
|
|
173
173
|
where: cinema
|
|
@@ -226,7 +226,7 @@ Answer:
|
|
|
226
226
|
}
|
|
227
227
|
],
|
|
228
228
|
"commits": [{ "table": "main.public.watch", "version": 3, "operation": "RECOMPUTE" }],
|
|
229
|
-
"migration_id": "
|
|
229
|
+
"migration_id": "20261024T063905-recompute_columns-recompute-id-day-label-of-watc"
|
|
230
230
|
}
|
|
231
231
|
```
|
|
232
232
|
|
|
@@ -292,7 +292,7 @@ Answer:
|
|
|
292
292
|
```markdown
|
|
293
293
|
---
|
|
294
294
|
table: main.public.watch
|
|
295
|
-
id:
|
|
295
|
+
id: 01a16ca2-ca05-74ee-97ba-2dcfcbb41703
|
|
296
296
|
occurred_at: 2026-09-25T21:00
|
|
297
297
|
film: "[[Charade]]"
|
|
298
298
|
where: home
|
|
@@ -311,7 +311,7 @@ You edit `datanotes/main/public/film/Metropolis.md` by hand, outside the engine.
|
|
|
311
311
|
```markdown
|
|
312
312
|
---
|
|
313
313
|
table: main.public.film
|
|
314
|
-
id:
|
|
314
|
+
id: 01a16ca2-8b18-71f0-92e4-4e2492953fa5
|
|
315
315
|
year: 1927
|
|
316
316
|
minutes: 153
|
|
317
317
|
status: to watch
|
|
@@ -384,7 +384,7 @@ You edit `datanotes/main/public/film/Sherlock Jr..md` by hand, outside the engin
|
|
|
384
384
|
```markdown
|
|
385
385
|
---
|
|
386
386
|
table: main.public.film
|
|
387
|
-
id:
|
|
387
|
+
id: 01a16ca2-719a-7e26-8d8b-e4471d2b154f
|
|
388
388
|
title: Sherlock Jr.: the projectionist
|
|
389
389
|
year: 1924
|
|
390
390
|
status: watched
|
|
@@ -471,7 +471,7 @@ You edit `datanotes/main/public/film/Sherlock Jr..md` by hand, outside the engin
|
|
|
471
471
|
```markdown
|
|
472
472
|
---
|
|
473
473
|
table: main.public.film
|
|
474
|
-
id:
|
|
474
|
+
id: 01a16ca2-719a-7e26-8d8b-e4471d2b154f
|
|
475
475
|
title: "Sherlock Jr.: the projectionist"
|
|
476
476
|
year: 1924
|
|
477
477
|
status: watched
|