@x12i/catalox 4.0.3 → 4.1.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 +932 -898
- package/dist/src/cli/index.js +435 -1
- package/dist/src/cli/index.js.map +1 -1
- package/dist/src/cli/item-json.d.ts +17 -0
- package/dist/src/cli/item-json.d.ts.map +1 -0
- package/dist/src/cli/item-json.js +97 -0
- package/dist/src/cli/item-json.js.map +1 -0
- package/dist/src/contracts/errors.d.ts.map +1 -1
- package/dist/src/contracts/errors.js +12 -1
- package/dist/src/contracts/errors.js.map +1 -1
- package/docs/cli-items.md +93 -0
- package/docs/cli-toolbox.md +166 -0
- package/package.json +3 -1
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
# `catalox toolbox` — access diagnostics and binding repairs
|
|
2
|
+
|
|
3
|
+
The **`toolbox`** CLI commands help operators answer: **“Can this `appId` read this `catalogId` in Firestore, and why not?”** They complement **`catalox report`** / **`export`**, which support **`--god`** to **bypass** binding checks for inventory — not for reproducing embedder/runtime auth.
|
|
4
|
+
|
|
5
|
+
## Prerequisites
|
|
6
|
+
|
|
7
|
+
Use the **same environment** as other Catalox CLI commands (see [`docs/environment.md`](environment.md)):
|
|
8
|
+
|
|
9
|
+
- **Firestore:** `FIREBASE_PROJECT_ID`, optional `FIRESTORE_DATABASE_ID`, and credentials (`GOOGLE_SERVICE_ACCOUNT_BASE64` recommended, or ADC).
|
|
10
|
+
- **Working directory:** `.env` loaded via `dotenv` from `src/cli/index.ts` (same pattern as `catalox firestore probe`).
|
|
11
|
+
|
|
12
|
+
Connectivity smoke test:
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
catalox firestore probe
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Firestore layout (what is checked)
|
|
19
|
+
|
|
20
|
+
| Piece | Collection / id | Meaning |
|
|
21
|
+
|-------|------------------|--------|
|
|
22
|
+
| Catalog row | `catalogs/{catalogId}` | Catalog exists in this project. |
|
|
23
|
+
| App↔catalog binding | `catalogBindings/{appId}:{catalogId}` | Document id is **`{appId}:{catalogId}`** (see [`src/firebase/binding-store.ts`](../src/firebase/binding-store.ts), [`src/catalox/catalox.ts`](../src/catalox/catalox.ts) `bindCatalogToApp`). |
|
|
24
|
+
|
|
25
|
+
Runtime reads require an **active** binding with sufficient **`access`** flags (`canRead` for list/get, etc.). See [`docs/authorization.md`](authorization.md) and [`docs/spec.md`](spec.md) §13 (app↔catalog binding model).
|
|
26
|
+
|
|
27
|
+
## `toolbox check-access`
|
|
28
|
+
|
|
29
|
+
**Purpose:** In one shot, report:
|
|
30
|
+
|
|
31
|
+
1. Whether the **`catalogBindings/{appId}:{catalogId}`** document exists and its fields (as stored).
|
|
32
|
+
2. Whether **`catalogs/{catalogId}`** exists (via Catalox `getCatalog`, no binding required for that read).
|
|
33
|
+
3. **`listCatalogItemsWithOutcome`** for `{ appId }` + `catalogId` with `limit: 1` — the same authorization path as normal embedder usage (unless you use `superAdmin` / god mode elsewhere).
|
|
34
|
+
|
|
35
|
+
### Usage
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
catalox toolbox check-access --app <appId> --catalog <catalogId>
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Optional:
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
catalox toolbox check-access --app <appId> --catalog <catalogId> --show-all-bindings
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
**`--show-all-bindings`** runs a Firestore query on `catalogBindings` where `catalogId == <catalogId>` and prints every matching row (useful to see which apps are bound to a shared catalog).
|
|
48
|
+
|
|
49
|
+
### Interpreting the JSON
|
|
50
|
+
|
|
51
|
+
| Field | Typical meaning |
|
|
52
|
+
|-------|------------------|
|
|
53
|
+
| `bindingDocId` | Always **`{appId}:{catalogId}`**. |
|
|
54
|
+
| `bindingDocExists` / `binding` | If `false` / `null`, there is **no** (or unreadable) binding doc at that id — lists will be **denied** for that app. |
|
|
55
|
+
| `catalogExists` | If `false`, there is **no** `catalogs/{catalogId}` document in **this** project (wrong project/database, typo, or catalog never created). **Fix:** create the catalog (seed, `createCatalog`, or your platform’s provisioning) — **`toolbox` does not create catalog rows.** |
|
|
56
|
+
| `catalogMetadataStatus` | When the catalog exists, optional `metadata.status` from the catalog record. |
|
|
57
|
+
| `simulatedListOutcome` | Result of `listCatalogItemsWithOutcome`: **`ok`**, **`empty`**, **`denied`**, **`misconfigured`**, **`mapping_blocked`**. See [`docs/outcomes.md`](outcomes.md). |
|
|
58
|
+
| `deniedMessage` | Present when `simulatedListOutcome === "denied"`. |
|
|
59
|
+
| `recommendations` | Short suggested next steps (heuristic). |
|
|
60
|
+
|
|
61
|
+
### Exit code
|
|
62
|
+
|
|
63
|
+
- **0** when `simulatedListOutcome` is **`ok`** or **`empty`** (authorized; empty means no items returned with `limit: 1`).
|
|
64
|
+
- **1** for **`denied`**, **`misconfigured`**, **`mapping_blocked`**, or unexpected errors — suitable for scripts.
|
|
65
|
+
|
|
66
|
+
### Example: studio app and `entities`
|
|
67
|
+
|
|
68
|
+
If your host uses `appId` **`graphs-studio`** and catalog id **`entities`**:
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
catalox toolbox check-access --app graphs-studio --catalog entities
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
If you see **`catalogExists: false`** and **`bindingDocExists: false`**, you must:
|
|
75
|
+
|
|
76
|
+
1. **Create the catalog** in this Firestore project (so `catalogs/entities` exists), then
|
|
77
|
+
2. **Create the binding** (next section).
|
|
78
|
+
|
|
79
|
+
If the catalog exists but **`bindingDocExists` is false**, only step (2) is required.
|
|
80
|
+
|
|
81
|
+
## `toolbox ensure-binding`
|
|
82
|
+
|
|
83
|
+
**Purpose:** Call Catalox **`ensureBinding`** — **insert** `catalogBindings/{appId}:{catalogId}` **only when no binding row already exists** for that app+catalog pair.
|
|
84
|
+
|
|
85
|
+
It does **not**:
|
|
86
|
+
|
|
87
|
+
- Create **`catalogs/{catalogId}`**.
|
|
88
|
+
- Upgrade or reactivate an existing row (if a doc exists, **`ensureBinding` is a no-op**).
|
|
89
|
+
|
|
90
|
+
### Usage
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
catalox toolbox ensure-binding --app <appId> --catalog <catalogId>
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
Optional flags:
|
|
97
|
+
|
|
98
|
+
- **`--write`** — set `canWrite: true` on the **new** binding (default `false`).
|
|
99
|
+
- **`--admin`** — set `canAdmin: true`.
|
|
100
|
+
- **`--god`** — set `superAdmin` on the Catalox context. Needed only when your **context `appId`** differs from the **`--app`** binding target (see **`ensureBinding`** in [`src/catalox/catalox.ts`](../src/catalox/catalox.ts)). The toolbox sets context **`appId`** from **`--app`**, so **`--god` is usually not required** for normal “bind this app to this catalog” use.
|
|
101
|
+
|
|
102
|
+
### After `ensure-binding`
|
|
103
|
+
|
|
104
|
+
Re-run:
|
|
105
|
+
|
|
106
|
+
```bash
|
|
107
|
+
catalox toolbox check-access --app <appId> --catalog <catalogId>
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
If the binding doc existed but was **disabled** or had **wrong `access`**, `ensure-binding` will not change it — use **`repair-binding`** below.
|
|
111
|
+
|
|
112
|
+
## `toolbox repair-binding`
|
|
113
|
+
|
|
114
|
+
**Purpose:** **Merge-write** the `catalogBindings/{appId}:{catalogId}` document to **`status: "active"`** and the given **`access`** flags. Use when:
|
|
115
|
+
|
|
116
|
+
- A binding exists but **`status`** is not **`active`**, or
|
|
117
|
+
- **`canRead`** / **`canWrite`** need to be corrected, or
|
|
118
|
+
- **`ensure-binding`** no-ops because a row already exists.
|
|
119
|
+
|
|
120
|
+
### Usage
|
|
121
|
+
|
|
122
|
+
**`--god` is required** (operator confirmation; the write uses Firebase Admin and bypasses client security rules like other admin tooling).
|
|
123
|
+
|
|
124
|
+
```bash
|
|
125
|
+
catalox toolbox repair-binding --god --app <appId> --catalog <catalogId>
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
Optional:
|
|
129
|
+
|
|
130
|
+
- **`--write`** — set `canWrite: true`.
|
|
131
|
+
- **`--admin`** — set `canAdmin: true`.
|
|
132
|
+
|
|
133
|
+
Then verify with **`check-access`** again.
|
|
134
|
+
|
|
135
|
+
## `toolbox unbind-catalog`
|
|
136
|
+
|
|
137
|
+
**Purpose:** Call Catalox **`unbindCatalogFromApp`**, which **disables** the binding at `catalogBindings/{appId:catalogId}` (`status: "disabled"`) rather than deleting the document. The app stops receiving read/write access until the row is repaired or re-bound.
|
|
138
|
+
|
|
139
|
+
### Usage
|
|
140
|
+
|
|
141
|
+
```bash
|
|
142
|
+
catalox toolbox unbind-catalog --app <appId> --catalog <catalogId>
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
Use **`--god`** when your CLI context (typically `CATALOX_APP_ID`) is not the same as **`--app`** and the library requires super-admin for cross-app operations (same mental model as `ensure-binding`).
|
|
146
|
+
|
|
147
|
+
### After `unbind-catalog`
|
|
148
|
+
|
|
149
|
+
- Re-run **`toolbox check-access`** — expect `bindingDocExists: true` with `status: "disabled"` or list outcome **denied**, depending on how your host reads bindings.
|
|
150
|
+
- To restore access without re-seeding: **`toolbox repair-binding --god`** (sets `active` and access flags).
|
|
151
|
+
|
|
152
|
+
## How this differs from `report` / `export --god`
|
|
153
|
+
|
|
154
|
+
| Tool | Binding checks |
|
|
155
|
+
|------|------------------|
|
|
156
|
+
| **`catalox report`**, **`export`** with **`--god`** | Super-admin context can **skip** binding requirements for broad inventory. |
|
|
157
|
+
| **`toolbox check-access`** | Uses **normal** app context (no `--god` on check-access) so **`listCatalogItemsWithOutcome`** reflects **real** embedder access. |
|
|
158
|
+
| **`ensure-binding`** / **`repair-binding`** | **Writes** binding documents (admin SDK); **`repair-binding`** requires **`--god`**. |
|
|
159
|
+
|
|
160
|
+
## Related documentation
|
|
161
|
+
|
|
162
|
+
- [`docs/authorization.md`](authorization.md) — app axis, super admin, empty vs denied.
|
|
163
|
+
- [`docs/outcomes.md`](outcomes.md) — `listCatalogItemsWithOutcome` outcomes.
|
|
164
|
+
- [`docs/onboarding-happy-path.md`](onboarding-happy-path.md) — seed presets that include catalogs and bindings.
|
|
165
|
+
- [`docs/spec.md`](spec.md) §13 — app↔catalog binding model.
|
|
166
|
+
- [`docs/cli-items.md`](cli-items.md) — per-item CRUD, batch upsert, `seed validate`, and relation subcommands.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@x12i/catalox",
|
|
3
|
-
"version": "4.0
|
|
3
|
+
"version": "4.1.0",
|
|
4
4
|
"description": "Platform infrastructure for reusable, interoperable catalogs across apps and data sources.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"private": false,
|
|
@@ -50,6 +50,8 @@
|
|
|
50
50
|
"files": [
|
|
51
51
|
"dist",
|
|
52
52
|
"docs/catalox-ui-contract.md",
|
|
53
|
+
"docs/cli-items.md",
|
|
54
|
+
"docs/cli-toolbox.md",
|
|
53
55
|
"presets",
|
|
54
56
|
"README.md",
|
|
55
57
|
"LICENSE",
|