@x12i/static-memorix-explorer-api 1.2.0 → 1.3.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/README.md +31 -0
- package/dist/config.d.ts +8 -0
- package/dist/config.js +18 -0
- package/dist/engine/inventory.js +4 -4
- package/dist/engine/lists.d.ts +1 -1
- package/dist/engine/lists.js +2 -6
- package/dist/engine/narratives.js +6 -16
- package/dist/engine/write.js +2 -6
- package/dist/routes/index.js +7 -1
- package/dist/storage/InMemoryStore.js +35 -16
- package/guides/managing-json-files.md +56 -0
- package/guides/running-the-service.md +13 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -207,6 +207,28 @@ These strings are derived from `MEMORIX_ORG_ID`, `MEMORIX_AGENT_ID`, and the
|
|
|
207
207
|
`MEMORIX_DEPLOYMENT_PROFILE` (which, when set to `ebook`, forces both IDs to
|
|
208
208
|
`ebooks`).
|
|
209
209
|
|
|
210
|
+
### File-backed routing
|
|
211
|
+
|
|
212
|
+
Those routed database names also select JSON files. The separator is `--`:
|
|
213
|
+
|
|
214
|
+
```text
|
|
215
|
+
mocks/data/product/neo-memorix-entities--snapshots.json
|
|
216
|
+
mocks/data/product/neo-memorix-events--events.json
|
|
217
|
+
mocks/data/memory/neo-agent-memorix-catalox--memory.json
|
|
218
|
+
mocks/metadata/lists/neo-agent-memorix-catalox--my-plate.json
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
For `MEMORIX_ORG_ID=neo` and `MEMORIX_AGENT_ID=neo-agent`, entity-like
|
|
222
|
+
collections use the first prefix, events use the second, and memory plus
|
|
223
|
+
metadata use the Catalox prefix. If a routed file does not exist, the server
|
|
224
|
+
loads its unprefixed counterpart as seed data, but all mutations are written
|
|
225
|
+
to the routed filename. This provides database-style isolation without a
|
|
226
|
+
database and preserves existing fixtures.
|
|
227
|
+
|
|
228
|
+
The health response exposes the resolved values under `fileRouting`.
|
|
229
|
+
See [guides/managing-json-files.md](./guides/managing-json-files.md) for the
|
|
230
|
+
complete precedence and migration rules.
|
|
231
|
+
|
|
210
232
|
## Feature Flag Enforcement
|
|
211
233
|
|
|
212
234
|
The mock server enforces the following feature-flag gates with error responses:
|
|
@@ -247,6 +269,15 @@ and `knowledgeId`.
|
|
|
247
269
|
|
|
248
270
|
## Release history
|
|
249
271
|
|
|
272
|
+
### v1.3.0
|
|
273
|
+
- Added database-routing parity through deterministic JSON filename prefixes.
|
|
274
|
+
- Added separate entity, event, and Catalox/metadata prefix resolution.
|
|
275
|
+
- Added migration-safe fallback from missing routed files to unprefixed seeds;
|
|
276
|
+
writes always persist to the selected routed file.
|
|
277
|
+
- Added resolved `fileRouting` prefixes to the health response.
|
|
278
|
+
- Updated metadata discovery to ignore other routed tenants.
|
|
279
|
+
- Added routed persistence and prefix regression coverage.
|
|
280
|
+
|
|
250
281
|
### v1.2.0
|
|
251
282
|
- Added native `--port` and `--host` CLI options.
|
|
252
283
|
- Added the canonical `static-memorix-explorer-api` executable while retaining
|
package/dist/config.d.ts
CHANGED
|
@@ -18,6 +18,14 @@ export declare function buildMemorixDbString(): string;
|
|
|
18
18
|
* e.g. "ebooks-memorix-catalox"
|
|
19
19
|
*/
|
|
20
20
|
export declare function buildCataloxDbString(): string;
|
|
21
|
+
/**
|
|
22
|
+
* Files emulate routed databases by using the resolved database name as a
|
|
23
|
+
* prefix. The `--` separator is reserved for routing and must not be used in
|
|
24
|
+
* an unprefixed fixture basename.
|
|
25
|
+
*/
|
|
26
|
+
export declare function buildDataFilePrefix(contentType: string): string;
|
|
27
|
+
export declare function buildMetadataFilePrefix(): string;
|
|
28
|
+
export declare function prefixedJsonFilename(prefix: string, basename: string): string;
|
|
21
29
|
export declare const FLAGS: {
|
|
22
30
|
METADATA_WRITES: boolean;
|
|
23
31
|
PIPELINE_WRITES: boolean;
|
package/dist/config.js
CHANGED
|
@@ -46,6 +46,24 @@ export function buildMemorixDbString() {
|
|
|
46
46
|
export function buildCataloxDbString() {
|
|
47
47
|
return `${MEMORIX_AGENT_ID}-memorix-catalox`;
|
|
48
48
|
}
|
|
49
|
+
/**
|
|
50
|
+
* Files emulate routed databases by using the resolved database name as a
|
|
51
|
+
* prefix. The `--` separator is reserved for routing and must not be used in
|
|
52
|
+
* an unprefixed fixture basename.
|
|
53
|
+
*/
|
|
54
|
+
export function buildDataFilePrefix(contentType) {
|
|
55
|
+
if (contentType === "events")
|
|
56
|
+
return `${MEMORIX_ORG_ID}-memorix-events`;
|
|
57
|
+
if (contentType === "memory")
|
|
58
|
+
return buildCataloxDbString();
|
|
59
|
+
return `${MEMORIX_ORG_ID}-memorix-entities`;
|
|
60
|
+
}
|
|
61
|
+
export function buildMetadataFilePrefix() {
|
|
62
|
+
return buildCataloxDbString();
|
|
63
|
+
}
|
|
64
|
+
export function prefixedJsonFilename(prefix, basename) {
|
|
65
|
+
return `${prefix}--${basename}.json`;
|
|
66
|
+
}
|
|
49
67
|
// ---------------------------------------------------------------------------
|
|
50
68
|
// Feature Flag Enforcement
|
|
51
69
|
// ---------------------------------------------------------------------------
|
package/dist/engine/inventory.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import path from "node:path";
|
|
2
2
|
import { store } from "../storage/InMemoryStore.js";
|
|
3
3
|
import { CONTENT_TYPES } from "../types.js";
|
|
4
|
-
import {
|
|
5
|
-
import { METADATA_DIR, DATA_DIR } from "../config.js";
|
|
4
|
+
import { DATA_DIR } from "../config.js";
|
|
6
5
|
import fs from "node:fs";
|
|
7
6
|
import { isDir } from "../storage/fs.js";
|
|
8
7
|
export function listObjectTypes() {
|
|
9
|
-
|
|
10
|
-
|
|
8
|
+
return store.getMetaKeys()
|
|
9
|
+
.filter((key) => key.startsWith("object-types/"))
|
|
10
|
+
.map((key) => key.slice("object-types/".length));
|
|
11
11
|
}
|
|
12
12
|
export function listDataObjectTypes() {
|
|
13
13
|
if (!isDir(DATA_DIR))
|
package/dist/engine/lists.d.ts
CHANGED
|
@@ -11,7 +11,7 @@ export declare function executeListDescriptor(desc: ListDescriptor, params?: Exp
|
|
|
11
11
|
export declare function suggestListExtensions(entityName: string): {
|
|
12
12
|
entityName: string;
|
|
13
13
|
suggestions: {
|
|
14
|
-
contentType: "
|
|
14
|
+
contentType: "events" | "memory" | "analysis" | "decisions";
|
|
15
15
|
collection: string;
|
|
16
16
|
suggestion: string;
|
|
17
17
|
}[];
|
package/dist/engine/lists.js
CHANGED
|
@@ -1,14 +1,10 @@
|
|
|
1
|
-
import path from "node:path";
|
|
2
1
|
import { store } from "../storage/InMemoryStore.js";
|
|
3
2
|
import { CONTENT_TYPES } from "../types.js";
|
|
4
|
-
import { listJsonFiles, basenameNoExt } from "../storage/fs.js";
|
|
5
|
-
import { METADATA_DIR } from "../config.js";
|
|
6
3
|
import { queryMockCollection } from "../engine/query.js";
|
|
7
4
|
export function listListDescriptors(entityName) {
|
|
8
|
-
const dir = path.join(METADATA_DIR, "lists");
|
|
9
5
|
const out = [];
|
|
10
|
-
for (const
|
|
11
|
-
const desc = store.getMeta(
|
|
6
|
+
for (const key of store.getMetaKeys().filter((item) => item.startsWith("lists/"))) {
|
|
7
|
+
const desc = store.getMeta(key);
|
|
12
8
|
if (desc && (!entityName || desc.entity === entityName || desc.entityName === entityName)) {
|
|
13
9
|
out.push(desc);
|
|
14
10
|
}
|
|
@@ -1,10 +1,5 @@
|
|
|
1
|
-
import path from "node:path";
|
|
2
1
|
import { store } from "../storage/InMemoryStore.js";
|
|
3
2
|
import { CONTENT_TYPES } from "../types.js";
|
|
4
|
-
import { listJsonFiles, basenameNoExt, readJson } from "../storage/fs.js";
|
|
5
|
-
import { METADATA_DIR } from "../config.js";
|
|
6
|
-
import { isDir } from "../storage/fs.js";
|
|
7
|
-
import fs from "node:fs";
|
|
8
3
|
/**
|
|
9
4
|
* Discover narrative keys tagged on records via doc.narratives.*.
|
|
10
5
|
*/
|
|
@@ -40,11 +35,10 @@ export function getMergedNarratives(entityName) {
|
|
|
40
35
|
return mergeCatalogWithSignals(authored, recordTags);
|
|
41
36
|
}
|
|
42
37
|
// global across all entities
|
|
43
|
-
const dir = path.join(METADATA_DIR, "narratives");
|
|
44
38
|
const out = {};
|
|
45
|
-
for (const
|
|
46
|
-
const name =
|
|
47
|
-
const authored =
|
|
39
|
+
for (const metaKey of store.getMetaKeys().filter((key) => key.startsWith("narratives/"))) {
|
|
40
|
+
const name = metaKey.slice("narratives/".length);
|
|
41
|
+
const authored = store.getMeta(metaKey) || {};
|
|
48
42
|
const recordTags = discoverRecordNarrativeTags(name);
|
|
49
43
|
out[name] = mergeCatalogWithSignals(authored, recordTags);
|
|
50
44
|
}
|
|
@@ -67,11 +61,7 @@ export function queryNarrativeRecords(entityName, key) {
|
|
|
67
61
|
return results;
|
|
68
62
|
}
|
|
69
63
|
export function listNarrativeEntities() {
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
return fs
|
|
74
|
-
.readdirSync(dir)
|
|
75
|
-
.filter((f) => f.endsWith(".json"))
|
|
76
|
-
.map((f) => basenameNoExt(f));
|
|
64
|
+
return store.getMetaKeys()
|
|
65
|
+
.filter((key) => key.startsWith("narratives/"))
|
|
66
|
+
.map((key) => key.slice("narratives/".length));
|
|
77
67
|
}
|
package/dist/engine/write.js
CHANGED
|
@@ -1,7 +1,4 @@
|
|
|
1
|
-
import path from "node:path";
|
|
2
1
|
import { store } from "../storage/InMemoryStore.js";
|
|
3
|
-
import { basenameNoExt, listJsonFiles } from "../storage/fs.js";
|
|
4
|
-
import { METADATA_DIR } from "../config.js";
|
|
5
2
|
export function loadWriteDescriptor(writeDescriptorId) {
|
|
6
3
|
const desc = store.getMeta(`write-descriptors/${writeDescriptorId}`);
|
|
7
4
|
if (!desc) {
|
|
@@ -156,10 +153,9 @@ function getNextId(collection, idField = "recordId") {
|
|
|
156
153
|
return () => String(counter++);
|
|
157
154
|
}
|
|
158
155
|
export function listWriteDescriptors() {
|
|
159
|
-
const dir = path.join(METADATA_DIR, "write-descriptors");
|
|
160
156
|
const out = [];
|
|
161
|
-
for (const
|
|
162
|
-
const desc = store.getMeta(
|
|
157
|
+
for (const key of store.getMetaKeys().filter((item) => item.startsWith("write-descriptors/"))) {
|
|
158
|
+
const desc = store.getMeta(key);
|
|
163
159
|
if (desc)
|
|
164
160
|
out.push(desc);
|
|
165
161
|
}
|
package/dist/routes/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { store } from "../storage/InMemoryStore.js";
|
|
2
|
-
import { buildMemorixDbString, buildCataloxDbString, metadataWritesEnabled, } from "../config.js";
|
|
2
|
+
import { buildMemorixDbString, buildCataloxDbString, buildDataFilePrefix, buildMetadataFilePrefix, metadataWritesEnabled, } from "../config.js";
|
|
3
3
|
import { listObjectTypes } from "../engine/inventory.js";
|
|
4
4
|
import { computeInventory, computeInventorySummary, computeInventoryIssues, computeGraph, } from "../engine/inventory.js";
|
|
5
5
|
import { qp, str } from "./helpers.js";
|
|
@@ -25,6 +25,12 @@ export async function registerRoutes(app) {
|
|
|
25
25
|
discoverySample: objectTypes,
|
|
26
26
|
memorixDb: buildMemorixDbString(),
|
|
27
27
|
cataloxDb: buildCataloxDbString(),
|
|
28
|
+
fileRouting: {
|
|
29
|
+
entitiesPrefix: buildDataFilePrefix("snapshots"),
|
|
30
|
+
eventsPrefix: buildDataFilePrefix("events"),
|
|
31
|
+
memoryPrefix: buildDataFilePrefix("memory"),
|
|
32
|
+
metadataPrefix: buildMetadataFilePrefix(),
|
|
33
|
+
},
|
|
28
34
|
};
|
|
29
35
|
if (includeInventory) {
|
|
30
36
|
const rows = computeInventory({ sourceLens: "catalox-first" });
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import fs from "node:fs";
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
import { CONTENT_TYPES } from "../types.js";
|
|
4
|
-
import { MOCKS_DIR, METADATA_DIR, DATA_DIR } from "../config.js";
|
|
4
|
+
import { MOCKS_DIR, METADATA_DIR, DATA_DIR, buildDataFilePrefix, buildMetadataFilePrefix, prefixedJsonFilename, } from "../config.js";
|
|
5
5
|
import { validateRecordArray } from "../engine/identity.js";
|
|
6
6
|
import { isDir, listJsonFiles, readJson, writeJson, basenameNoExt, } from "./fs.js";
|
|
7
7
|
import { DISK_FLUSH_DEBOUNCE_MS } from "../config.js";
|
|
@@ -28,18 +28,33 @@ export class InMemoryStore {
|
|
|
28
28
|
"write-descriptors": "write-descriptors",
|
|
29
29
|
narratives: "narratives",
|
|
30
30
|
};
|
|
31
|
+
const prefix = buildMetadataFilePrefix();
|
|
31
32
|
for (const [subdir] of Object.entries(sections)) {
|
|
32
33
|
const dir = path.join(METADATA_DIR, subdir);
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
34
|
+
const files = listJsonFiles(dir);
|
|
35
|
+
const logicalNames = new Set();
|
|
36
|
+
for (const file of files) {
|
|
37
|
+
const name = basenameNoExt(file);
|
|
38
|
+
if (!name.includes("--"))
|
|
39
|
+
logicalNames.add(name);
|
|
40
|
+
if (name.startsWith(`${prefix}--`))
|
|
41
|
+
logicalNames.add(name.slice(prefix.length + 2));
|
|
42
|
+
}
|
|
43
|
+
for (const name of logicalNames) {
|
|
44
|
+
const baseFile = path.join(dir, `${name}.json`);
|
|
45
|
+
const routedFile = path.join(dir, prefixedJsonFilename(prefix, name));
|
|
46
|
+
const source = fs.existsSync(routedFile) ? routedFile : baseFile;
|
|
47
|
+
const key = `${subdir}/${name}`;
|
|
48
|
+
this.metadata.set(key, { path: routedFile, data: readJson(source, {}) });
|
|
36
49
|
}
|
|
37
50
|
}
|
|
38
|
-
const
|
|
39
|
-
|
|
51
|
+
const baseAgentsFile = path.join(METADATA_DIR, "agents.json");
|
|
52
|
+
const routedAgentsFile = path.join(METADATA_DIR, prefixedJsonFilename(prefix, "agents"));
|
|
53
|
+
const agentsSource = fs.existsSync(routedAgentsFile) ? routedAgentsFile : baseAgentsFile;
|
|
54
|
+
if (fs.existsSync(agentsSource)) {
|
|
40
55
|
this.metadata.set("agents", {
|
|
41
|
-
path:
|
|
42
|
-
data: readJson(
|
|
56
|
+
path: routedAgentsFile,
|
|
57
|
+
data: readJson(agentsSource, { agents: [] }),
|
|
43
58
|
});
|
|
44
59
|
}
|
|
45
60
|
}
|
|
@@ -51,9 +66,11 @@ export class InMemoryStore {
|
|
|
51
66
|
if (!isDir(otDir))
|
|
52
67
|
continue;
|
|
53
68
|
for (const ct of CONTENT_TYPES) {
|
|
54
|
-
const
|
|
69
|
+
const baseFile = path.join(otDir, `${ct}.json`);
|
|
70
|
+
const file = path.join(otDir, prefixedJsonFilename(buildDataFilePrefix(ct), ct));
|
|
55
71
|
const key = `${objectType}/${ct}`;
|
|
56
|
-
const
|
|
72
|
+
const source = fs.existsSync(file) ? file : baseFile;
|
|
73
|
+
const data = readJson(source, []);
|
|
57
74
|
// Startup validation: ensure records carry exactly one identity key
|
|
58
75
|
// (MemorixRecordArraySchema mock). Memory collections use memoryId.
|
|
59
76
|
const result = validateRecordArray(objectType, ct, data);
|
|
@@ -68,11 +85,13 @@ export class InMemoryStore {
|
|
|
68
85
|
});
|
|
69
86
|
}
|
|
70
87
|
// system overrides
|
|
71
|
-
const
|
|
72
|
-
|
|
88
|
+
const baseInvFile = path.join(DATA_DIR, "system", "inventory.json");
|
|
89
|
+
const invFile = path.join(DATA_DIR, "system", prefixedJsonFilename(buildDataFilePrefix("snapshots"), "inventory"));
|
|
90
|
+
const invSource = fs.existsSync(invFile) ? invFile : baseInvFile;
|
|
91
|
+
if (objectType === "system" && fs.existsSync(invSource)) {
|
|
73
92
|
this.collections.set("system/inventory", {
|
|
74
93
|
path: invFile,
|
|
75
|
-
data: readJson(
|
|
94
|
+
data: readJson(invSource, []),
|
|
76
95
|
});
|
|
77
96
|
}
|
|
78
97
|
}
|
|
@@ -89,7 +108,7 @@ export class InMemoryStore {
|
|
|
89
108
|
}
|
|
90
109
|
else {
|
|
91
110
|
this.metadata.set(key, {
|
|
92
|
-
path: path.join(METADATA_DIR, `${key}.
|
|
111
|
+
path: path.join(METADATA_DIR, `${path.dirname(key)}/${prefixedJsonFilename(buildMetadataFilePrefix(), path.basename(key))}`),
|
|
93
112
|
data,
|
|
94
113
|
[DIRTY]: true,
|
|
95
114
|
});
|
|
@@ -106,7 +125,7 @@ export class InMemoryStore {
|
|
|
106
125
|
const c = this.collections.get(key);
|
|
107
126
|
if (!c) {
|
|
108
127
|
const newC = {
|
|
109
|
-
path: path.join(DATA_DIR, objectType,
|
|
128
|
+
path: path.join(DATA_DIR, objectType, prefixedJsonFilename(buildDataFilePrefix(ct), ct)),
|
|
110
129
|
data: [],
|
|
111
130
|
};
|
|
112
131
|
this.collections.set(key, newC);
|
|
@@ -123,7 +142,7 @@ export class InMemoryStore {
|
|
|
123
142
|
}
|
|
124
143
|
else {
|
|
125
144
|
this.collections.set(key, {
|
|
126
|
-
path: path.join(DATA_DIR, objectType,
|
|
145
|
+
path: path.join(DATA_DIR, objectType, prefixedJsonFilename(buildDataFilePrefix(ct), ct)),
|
|
127
146
|
data,
|
|
128
147
|
[DIRTY]: true,
|
|
129
148
|
});
|
|
@@ -1,5 +1,61 @@
|
|
|
1
1
|
# Managing JSON Files
|
|
2
2
|
|
|
3
|
+
## File-backed database routing
|
|
4
|
+
|
|
5
|
+
The static server has no database, so database routing is represented by a
|
|
6
|
+
reserved filename prefix followed by `--`.
|
|
7
|
+
|
|
8
|
+
With:
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
MEMORIX_ORG_ID=neo
|
|
12
|
+
MEMORIX_AGENT_ID=neo-agent
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
the routing matrix is:
|
|
16
|
+
|
|
17
|
+
| Data kind | Filename prefix | Example |
|
|
18
|
+
| --- | --- | --- |
|
|
19
|
+
| Snapshots, analysis, decisions | `neo-memorix-entities--` | `data/product/neo-memorix-entities--snapshots.json` |
|
|
20
|
+
| Events | `neo-memorix-events--` | `data/product/neo-memorix-events--events.json` |
|
|
21
|
+
| Memory | `neo-agent-memorix-catalox--` | `data/memory/neo-agent-memorix-catalox--memory.json` |
|
|
22
|
+
| Metadata | `neo-agent-memorix-catalox--` | `metadata/lists/neo-agent-memorix-catalox--my-plate.json` |
|
|
23
|
+
|
|
24
|
+
### Read and write precedence
|
|
25
|
+
|
|
26
|
+
1. The server first looks for the routed, prefixed file.
|
|
27
|
+
2. If it does not exist, it reads the matching unprefixed file as seed data.
|
|
28
|
+
3. Any mutation writes the complete resulting collection to the routed file.
|
|
29
|
+
4. Unprefixed seed files are never overwritten while routed mode is active.
|
|
30
|
+
5. Files belonging to a different prefix are ignored by the active process.
|
|
31
|
+
|
|
32
|
+
This makes onboarding migration-safe: existing files such as
|
|
33
|
+
`product/snapshots.json` continue to seed a new tenant, while the first write
|
|
34
|
+
creates `product/neo-memorix-entities--snapshots.json`. Starting with another
|
|
35
|
+
organization ID selects a different file and therefore different state.
|
|
36
|
+
|
|
37
|
+
The delimiter `--` is reserved. Do not use it inside ordinary, unprefixed
|
|
38
|
+
fixture basenames.
|
|
39
|
+
|
|
40
|
+
### Inspect the active route
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
curl http://localhost:5030/api/explorer/health
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
The response includes:
|
|
47
|
+
|
|
48
|
+
```json
|
|
49
|
+
{
|
|
50
|
+
"fileRouting": {
|
|
51
|
+
"entitiesPrefix": "neo-memorix-entities",
|
|
52
|
+
"eventsPrefix": "neo-memorix-events",
|
|
53
|
+
"memoryPrefix": "neo-agent-memorix-catalox",
|
|
54
|
+
"metadataPrefix": "neo-agent-memorix-catalox"
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
```
|
|
58
|
+
|
|
3
59
|
The mock server stores all state in JSON files under the `mocks/` directory. At
|
|
4
60
|
startup, every file is loaded into an in-memory store. Mutations happen in
|
|
5
61
|
memory and are debounced-flushed back to disk automatically.
|
|
@@ -121,6 +121,19 @@ correct tenant.
|
|
|
121
121
|
The health endpoint returns:
|
|
122
122
|
- `memorixDb`: `"<orgId>-memorix-entities + <orgId>-memorix-events"`
|
|
123
123
|
- `cataloxDb`: `"<agentId>-memorix-catalox"`
|
|
124
|
+
- `fileRouting`: the concrete entity, event, memory, and metadata filename
|
|
125
|
+
prefixes selected for this process
|
|
126
|
+
|
|
127
|
+
These are functional routes, not display-only labels. For example:
|
|
128
|
+
|
|
129
|
+
```bash
|
|
130
|
+
MEMORIX_ORG_ID=neo MEMORIX_AGENT_ID=neo-agent npm start
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
selects filenames beginning with `neo-memorix-entities--`,
|
|
134
|
+
`neo-memorix-events--`, and `neo-agent-memorix-catalox--`. See
|
|
135
|
+
[managing-json-files.md](./managing-json-files.md#file-backed-database-routing)
|
|
136
|
+
for exact examples and fallback behavior.
|
|
124
137
|
|
|
125
138
|
### Feature flags
|
|
126
139
|
|