@qaecy/cue-sdk 0.0.32 → 0.0.34

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/index.d.ts CHANGED
@@ -6,9 +6,10 @@ export type { GisBBox, GisCategoryDescriptor, GisFeature, GisFeaturesMap, Featur
6
6
  export { CueAuth } from './lib/auth';
7
7
  export { CueApi } from './lib/api';
8
8
  export { CueIndexApi } from './lib/index-api';
9
- export type { IndexSearchRequest, IndexItem, IndexSearchResponse } from './lib/models';
9
+ export type { IndexSearchRequest, IndexItem, IndexSearchResponse, IndexFilterOption, IndexAppliedFilters, AvailableFiltersResponse, SearchFilter, DocumentFilterOption, AvailableDocumentFilters, } from './lib/models';
10
10
  export { CueSyncApi, configureScanWasm } from './lib/sync';
11
11
  export { CueProjectSchema } from './lib/schema';
12
+ export { CueDocumentFilter } from './lib/document-filter';
12
13
  export { CueProjectEntities } from './lib/entities';
13
14
  export { CueProjectDocuments } from './lib/documents';
14
15
  export { CueProjectView } from './lib/project-view';
@@ -17,11 +18,11 @@ export { CueProjects } from './lib/project';
17
18
  export { CueProfile } from './lib/profile';
18
19
  export { CuePrivileges, REQUIRED_ROLES } from './lib/privileges';
19
20
  export type { UserProjectRole, Privileges } from './lib/privileges';
20
- export { CueSignal, cueComputed, staleWhileRevalidate } from './lib/signal';
21
+ export { CueSignal, cueComputed } from './lib/signal';
21
22
  export type { ReadonlySignal } from './lib/signal';
22
23
  export { CueCache } from './lib/cache';
23
24
  export type { QueryCacheEntry } from './lib/cache';
24
- export type { CueSdkConfig, SsoProvider, PasswordCredentials, SearchRequest, SearchResponse, SearchSource, SearchOptions, ProjectData, ProjectSettings, CreateProjectOptions, SyncOptions, SyncResult, SyncPreview, ScanOutputRecord, UnitsConsumedDto, OrganizationData, OrgMember, ProfileSSOAccount, APIKeyInfo, APIKeyDoc, ProjectDoc, OrganizationDoc, UserDoc, RDFWritingDoc, ViewDefinition, QueryCache, LangMap, CategoryDef, RelationshipDef, EntityCoreData, EntityRelationship, EntityRelationships, MapGeometry, EntityDetailedData, ProjectEntitiesData, DocumentInfo, DocumentSummary, ProjectDocumentsData, } from './lib/models';
25
+ export type { CueSdkConfig, SsoProvider, PasswordCredentials, SearchRequest, SearchResponse, SearchSource, SearchOptions, ProjectData, ProjectSettings, CreateProjectOptions, SyncOptions, SyncResult, SyncPreview, ScanOutputRecord, UnitsConsumedDto, OrgCreditsDto, OrganizationData, OrgMember, ProfileSSOAccount, APIKeyInfo, APIKeyDoc, ProjectDoc, OrganizationDoc, UserDoc, RDFWritingDoc, ViewDefinition, QueryCache, LangMap, CategoryDef, RelationshipDef, EntityCoreData, EntityRelationship, EntityRelationships, MapGeometry, EntityDetailedData, ProjectEntitiesData, DocumentInfo, DocumentSummary, ProjectDocumentsData, } from './lib/models';
25
26
  export type { AuthStateListener, Unsubscribe } from './lib/auth';
26
27
  export { CueTables } from './lib/tables';
27
28
  export type { ProjectTable } from './lib/tables';
@@ -29,3 +30,4 @@ export { CueExtraction } from './lib/extraction';
29
30
  export type { ExtractionRequest, ExtractionResponse } from './lib/extraction';
30
31
  export { CueContexts } from './lib/contexts';
31
32
  export type { ContextDoc, ContextItem } from './lib/models';
33
+ export { CueAppData } from './lib/app-data';
package/index.js CHANGED
@@ -1,26 +1,27 @@
1
- import { C as s, a as u, b as C, c as t, d as i, e as o, f as c, g as r, h as n, i as l, j as P, k as j, l as m, m as p, n as S, o as g, p as h, q as E, r as R, R as d, s as f, t as x, u as A } from "./cue-C7sbHLj4.js";
1
+ import { C as s, a as u, b as C, c as t, d as o, e as c, f as i, g as r, h as n, i as p, j as m, k as P, l as j, m as l, n as S, o as g, p as A, q as E, r as f, s as h, t as x, R as D, u as R, v as d } from "./document-filter-DAUY6HuA.js";
2
2
  export {
3
3
  s as Cue,
4
4
  u as CueApi,
5
- C as CueAuth,
6
- t as CueCache,
7
- i as CueContexts,
8
- o as CueExtraction,
9
- c as CueGis,
10
- r as CueIndexApi,
11
- n as CuePrivileges,
12
- l as CueProfile,
13
- P as CueProjectDocuments,
14
- j as CueProjectEntities,
15
- m as CueProjectSchema,
16
- p as CueProjectView,
17
- S as CueProjects,
18
- g as CueSignal,
19
- h as CueStorage,
20
- E as CueSyncApi,
21
- R as CueTables,
22
- d as REQUIRED_ROLES,
23
- f as configureScanWasm,
24
- x as cueComputed,
25
- A as staleWhileRevalidate
5
+ C as CueAppData,
6
+ t as CueAuth,
7
+ o as CueCache,
8
+ c as CueContexts,
9
+ i as CueDocumentFilter,
10
+ r as CueExtraction,
11
+ n as CueGis,
12
+ p as CueIndexApi,
13
+ m as CuePrivileges,
14
+ P as CueProfile,
15
+ j as CueProjectDocuments,
16
+ l as CueProjectEntities,
17
+ S as CueProjectSchema,
18
+ g as CueProjectView,
19
+ A as CueProjects,
20
+ E as CueSignal,
21
+ f as CueStorage,
22
+ h as CueSyncApi,
23
+ x as CueTables,
24
+ D as REQUIRED_ROLES,
25
+ R as configureScanWasm,
26
+ d as cueComputed
26
27
  };
package/node.js CHANGED
@@ -1,62 +1,34 @@
1
- import { C as S, B as _, v as l, w as E, x as m, y as P, q as d, z as w, a as U } from "./cue-C7sbHLj4.js";
2
- import { b as j, c as y, d as K, e as L, f as N, g as O, h as v, i as H, j as D, k as G, l as W, m as k, n as q, o as z, p as Q, r as V, R as F, s as J, t as M, u as X } from "./cue-C7sbHLj4.js";
3
- import { getStorage as s, connectStorageEmulator as b } from "firebase/storage";
4
- import "firebase/firestore";
5
- class f extends S {
1
+ import { C as s } from "./document-filter-DAUY6HuA.js";
2
+ import { a as r, b as c, c as i, d as n, e as p, f as m, g as l, h as P, i as j, j as x, k as S, l as d, m as f, n as g, o as A, p as E, q as h, r as D, s as R, t as b, R as v, u as I, v as k } from "./document-filter-DAUY6HuA.js";
3
+ class C extends s {
6
4
  constructor(e) {
7
5
  super(e);
8
6
  }
9
- _buildApi(e) {
10
- const r = s(this._app, _), i = s(this._app, l), n = this._storageRaw, u = s(this._app, E), c = this._storageProcessed, t = s(this._app, m);
11
- if (this._isEmulator) {
12
- const g = this._endpoints.storageEmulatorHost, h = this._endpoints.storageEmulatorPort;
13
- b(t, g, h);
14
- }
15
- const C = s(this._app, P), p = new w({
16
- storageChatSessions: r,
17
- storageLogs: i,
18
- storageRaw: n,
19
- storagePersistence: u,
20
- storageProcessed: c,
21
- storagePublic: t,
22
- storageSessions: C
23
- }), a = new d(
24
- this.auth,
25
- e,
26
- p,
27
- this._endpoints.gatewayUrl
28
- ), o = new U(
29
- this.auth,
30
- this._endpoints.gatewayUrl,
31
- e,
32
- a
33
- );
34
- return a._bindApi(o), o;
35
- }
36
7
  }
37
8
  export {
38
- S as Cue,
39
- U as CueApi,
40
- j as CueAuth,
41
- y as CueCache,
42
- K as CueContexts,
43
- L as CueExtraction,
44
- N as CueGis,
45
- O as CueIndexApi,
46
- f as CueNode,
47
- v as CuePrivileges,
48
- H as CueProfile,
49
- D as CueProjectDocuments,
50
- G as CueProjectEntities,
51
- W as CueProjectSchema,
52
- k as CueProjectView,
53
- q as CueProjects,
54
- z as CueSignal,
55
- Q as CueStorage,
56
- d as CueSyncApi,
57
- V as CueTables,
58
- F as REQUIRED_ROLES,
59
- J as configureScanWasm,
60
- M as cueComputed,
61
- X as staleWhileRevalidate
9
+ s as Cue,
10
+ r as CueApi,
11
+ c as CueAppData,
12
+ i as CueAuth,
13
+ n as CueCache,
14
+ p as CueContexts,
15
+ m as CueDocumentFilter,
16
+ l as CueExtraction,
17
+ P as CueGis,
18
+ j as CueIndexApi,
19
+ C as CueNode,
20
+ x as CuePrivileges,
21
+ S as CueProfile,
22
+ d as CueProjectDocuments,
23
+ f as CueProjectEntities,
24
+ g as CueProjectSchema,
25
+ A as CueProjectView,
26
+ E as CueProjects,
27
+ h as CueSignal,
28
+ D as CueStorage,
29
+ R as CueSyncApi,
30
+ b as CueTables,
31
+ v as REQUIRED_ROLES,
32
+ I as configureScanWasm,
33
+ k as cueComputed
62
34
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@qaecy/cue-sdk",
3
- "version": "0.0.32",
3
+ "version": "0.0.34",
4
4
  "type": "module",
5
5
  "main": "./index.js",
6
6
  "types": "./index.d.ts",
@@ -12,8 +12,18 @@
12
12
  "./node": {
13
13
  "import": "./node.js",
14
14
  "types": "./node.d.ts"
15
+ },
16
+ "./browser": {
17
+ "import": "./browser.js"
15
18
  }
16
19
  },
20
+ "files": [
21
+ "index.js",
22
+ "index.d.ts",
23
+ "node.js",
24
+ "node.d.ts",
25
+ "browser.js"
26
+ ],
17
27
  "peerDependencies": {
18
28
  "firebase": ">=10.0.0"
19
29
  }
@@ -1,346 +0,0 @@
1
- # Cue SDK — Portal Migration
2
-
3
- > **Goal:** All server communication in cue-portal flows through `js-cue-sdk`, replacing direct usage of `js-firebase` and `cue-repos`.
4
-
5
- ---
6
-
7
- ## Current State
8
-
9
- | Layer | Status |
10
- |-------|--------|
11
- | **js-cue-sdk** — `Cue`, `CueAuth`, `CueProjects`, `CueProfile`, `CuePrivileges`, `CueCache` | ✅ Active — all major modules built |
12
- | **js-databases** — `IDocStore`, `FirestoreDocStore`, `CueBlobStorage` | ✅ All repos delegating to these |
13
- | **cue-repos** (Angular) — now thin adapters over the SDK | ✅ Migrated |
14
- | **js-firebase** (`CueFirebase`) | Kept — CLI, widget, admin depend on it |
15
- | **cue-views** (Angular) — SPARQL + entity/doc signals | 🔄 In progress — core data classes built, facade + adapters pending |
16
-
17
- **Remaining `js-firebase` imports in the portal:**
18
- - `libs/ng/cue-repos/src/lib/firebase.service.ts` — intentional (this IS the `CueFirebase` wrapper)
19
- - `apps/frontend/cue-portal/src/main.ts` — app bootstrap; addressed in Final phase
20
-
21
- ---
22
-
23
- ## Remaining Work
24
-
25
- ### Phase 6 — Knowledge Graph View State (`CueProjectView`)
26
-
27
- Full investigation of `cue-views` services completed. The three heaviest SPARQL data classes are already built in `js-cue-sdk`. What remains is a thin facade, the Angular adapter wiring, and gateway API additions for the remaining services.
28
-
29
- #### Coverage summary — `cue-views` services vs SDK
30
-
31
- | `cue-views` service | SDK status | Owner after migration |
32
- |---|---|---|
33
- | `TriplestoreService` | ✅ Replaced by `CueApi.sparql()` | SDK |
34
- | `AvailableCategoriesService` | ✅ Replaced by `CueProjectSchema` | Angular bridge |
35
- | `ProjectDocumentsService` | ✅ Replaced by `CueProjectDocuments.fetchOverview()` | Angular bridge |
36
- | `DocumentInfoService` (SPARQL) | ✅ Replaced by `CueProjectDocuments.requestDocumentData()` | Angular bridge; callbacks stay Angular |
37
- | `EntityInfoService` (core) | ✅ Replaced by `CueProjectEntities` | Angular bridge |
38
- | `DocumentDuplicatesService` | ⚠️ Count covered; full path list not yet in SDK | Needs `CueProjectDocuments.fetchDuplicates()` |
39
- | `DocumentEntitiesService` | ❌ Not covered | Needs new SDK read queries + `CueApi` write methods |
40
- | `RelatedService` | ❌ Not covered | Needs `CueApi.relatedDocuments()` |
41
- | `ContentCategoryService` | ❌ Not covered | Needs `CueApi.changeContentCategory()` |
42
- | `AgentService` | ❌ Not covered | Needs `CueApi.streamPlan()` / `CueApi.streamAct()` |
43
- | `ResourceService` | ❌ Not covered | Per-document viewer; stays Angular or becomes `CueDocumentResource` |
44
- | `FileLocationsService` | ❌ Not covered | Low priority; stays Angular or becomes private helper |
45
- | `FileContentService` | ❌ Not covered | Depends on `FileRepo`; stays Angular-layer |
46
- | `CueViewsService` | N/A — config/context root | Angular adapter responsibility |
47
- | `CommandsService` | N/A — thin facade | Angular adapter responsibility |
48
-
49
- ---
50
-
51
- #### Phase 6a — `CueProjectView` facade _(next step)_
52
-
53
- Create `libs/js/cue-sdk/src/lib/project-view.ts` — a single class that composes `CueProjectSchema`, `CueProjectEntities`, and `CueProjectDocuments` and adds `search()`.
54
-
55
- ```ts
56
- const view = cue.createProjectView(projectId, { language: 'en', queryCache });
57
-
58
- // Proxied signals from sub-classes
59
- view.availableContentCategories // → schema.availableContentCategories
60
- view.availableEntityCategories // → schema.availableEntityCategories
61
- view.availableEntityRelationships // → schema.availableEntityRelationships
62
- view.entityInfoMap // → entities.entityInfoMap
63
- view.entityGraph // → entities.entityGraph
64
- view.documentInfoMap // → documents.documentInfoMap
65
- view.projectDocumentsData // → documents.projectDocumentsData
66
-
67
- // Proxied methods
68
- view.requestEntityData(ids, includeMentionCount?)
69
- view.requestEntityLocations(ids)
70
- view.fetchEntityRelationships(iri)
71
- view.fetchEntityDocuments(iri)
72
- view.requestDocumentData(ids)
73
-
74
- // New: search
75
- view.searchResults // ReadonlySignal<DocumentRef[]>
76
- view.search(term, options?) // Calls CueApi.search(), appends to searchResults
77
-
78
- // Lifecycle
79
- view.setLanguage(lang) // Calls schema.setLanguage(); docs.setLanguage()
80
- view.destroy() // Tears down subscriptions
81
- ```
82
-
83
- `Cue` gains a factory method:
84
- ```ts
85
- cue.createProjectView(projectId: string, opts: { language: string, queryCache?: QueryCache }): CueProjectView
86
- ```
87
-
88
- **Files to create/modify:**
89
- - `libs/js/cue-sdk/src/lib/project-view.ts` — new `CueProjectView` class
90
- - `libs/js/cue-sdk/src/lib/cue.ts` — add `createProjectView()` method
91
- - `libs/js/cue-sdk/src/index.ts` — export `CueProjectView` + related types
92
-
93
- ---
94
-
95
- #### Phase 6b — Angular adapters in `cue-views`
96
-
97
- Replace the heavy Angular services with thin bridges that subscribe to SDK signals and forward method calls. Each bridge service creates/receives a `CueProjectView` instance from the Angular DI tree.
98
-
99
- | Angular service | Migration action |
100
- |---|---|
101
- | `AvailableCategoriesService` | Replace with computed signals bridging `view.availableContentCategories` etc. via `toSignal(obs)` or `subscribe()` |
102
- | `ProjectDocumentsService` | Replace signal with bridge to `view.projectDocumentsData`; call `view.fetchOverview()` on project init |
103
- | `DocumentInfoService` | Delegate `requestDocumentData()` to `view`; keep `documentListHandlers` callbacks (download, navigate) Angular-side |
104
- | `EntityInfoService` | Delegate all 4 public methods to `view`; bridge `entityInfoMap` and `entityGraph` signals |
105
- | `TriplestoreService` | Remove — callers switch to `CueApi.sparql()` directly or via `view` |
106
-
107
- The Angular adapter pattern:
108
- ```ts
109
- // In cue-views Angular service
110
- readonly entityInfoMap = toSignal(
111
- new Observable(obs => this._view.entityInfoMap.subscribe(v => obs.next(v)))
112
- );
113
- ```
114
-
115
- ---
116
-
117
- #### Phase 6c — Gateway API additions (`CueApi`)
118
-
119
- These are needed before the remaining `cue-views` services can be bridged:
120
-
121
- | Method | Source service | HTTP call |
122
- |---|---|---|
123
- | `CueApi.relatedDocuments(contentUUID, k)` | `RelatedService` | `POST {gatewayURL}/endpoints.relatedDocuments` |
124
- | `CueApi.changeContentCategory(payload)` | `ContentCategoryService` | `PATCH {gatewayURL}/endpoints.contentCategoryChange` |
125
- | `CueApi.streamPlan(prompt, cb)` | `AgentService` | Streaming `POST {gatewayURL}/endpoints.agentPlan` via `fetchStream()` |
126
- | `CueApi.streamAct(plan, cb)` | `AgentService` | Streaming `POST {gatewayURL}/endpoints.agentAct` via `fetchStream()` |
127
- | `CueApi.saveEntityMentions(payload)` | `DocumentEntitiesService` | `POST/DELETE {gatewayURL}/endpoints.entityMentionBatch` |
128
- | `CueApi.saveSelectors(payload)` | `DocumentEntitiesService` | `POST {gatewayURL}/endpoints.selectorBatch` |
129
-
130
- The `gatewayURL` and project-scoped `Authorization`/`x-project-id` headers are already in `CueApi` — these are additive methods only.
131
-
132
- ---
133
-
134
- #### Phase 6d — SDK data additions
135
-
136
- Small additions to existing SDK classes:
137
-
138
- - **`CueProjectDocuments.fetchDuplicates()`** — returns `Record<uuid, string[]>` (all file paths per content UUID where count > 1). `DocumentDuplicatesService` currently holds an in-memory project-keyed cache of this.
139
- - **`CueProjectEntities` — document-entity reads** — fetch all `qcy:mentions` IRIs for a given `contentIRI`, with `qcy:value` and `qcy:hasEntityCategory`. Currently only in `DocumentEntitiesService`.
140
- - **`CueProjectEntities` or new `CueDocumentResource`** — type detection (`SELECT ?cl WHERE { <iri> a ?cl }`) + file metadata fetch for per-document-viewer panel. Currently in `ResourceService`.
141
-
142
- ---
143
-
144
- #### Phase 6e — `cue-views` cleanup
145
-
146
- After 6a–6d, the remaining Angular services that have no SDK equivalent are either:
147
- - **Kept as-is** (framework-specific): `FileContentService` (depends on `FileRepo`), `ResourceService` viewer composition, `DocumentListHandlers` callbacks
148
- - **Deleted** once bridge services are verified: `TriplestoreService`, `AvailableCategoriesService`, `ProjectDocumentsService`
149
-
150
- ---
151
-
152
- ### Final — Remove `js-firebase` from portal bootstrap
153
-
154
- Replace `main.ts` Firebase init + `FirebaseService` with pure SDK init. `cue-repos` services become either collapsed into the SDK or thin DI wrappers with no direct Firebase imports.
155
-
156
- ---
157
-
158
-
159
- ## Verification Plan
160
-
161
- After each phase, verify with the following checklist. Run `npx nx build cue-portal` as the baseline — all items below are functional smoke tests.
162
-
163
- ### ✅ Phase 2–5 (already done — verify these haven't regressed)
164
-
165
- | Area | How to verify |
166
- |------|--------------|
167
- | **Auth signals** | Sign in; confirm `cue.auth.user.get()` returns the user, `cue.auth.token.get()` returns a JWT, `cue.auth.isSuperAdmin.get()` reflects the claim |
168
- | **Privileges** | Select a project where the user is `admin`; confirm `cue.privileges.privileges.get().uploadDocuments === true`; `PrivilegesService.privileges()` should match |
169
- | **Cloud functions** | In Settings → Members: invite a user, change role, remove — all three `CueProjects` callables should fire without error |
170
- | **Cache (write)** | Run a SPARQL query with caching enabled; confirm a `.json.gz` file appears in the `db_persistence_eu_west6` bucket at `portal/projects/{pid}/queries/{id}.json.gz` |
171
- | **Cache (read)** | Run the same query again; confirm it loads from cache (no SPARQL call in the network tab) |
172
- | **Agent session cache** | Run an agent interaction; confirm `portal/projects/{pid}/agent/{id}.json.gz` is written |
173
- | **Doc types** | `ProjectDoc`, `UserDoc`, `OrganizationDoc`, `RDFWritingDoc`, `ViewDefinition` all importable from `js-cue-sdk` without errors |
174
- | **`nx graph`** | `cue-repos` should only have one edge to `js-firebase` (via `firebase.service.ts`) |
175
-
176
- ### 🔲 Phase 6a — `CueProjectView` facade
177
-
178
- | Area | How to verify |
179
- |------|--------------|
180
- | **Category signals** | Open a project; `view.availableContentCategories.get()` and `view.availableEntityCategories.get()` return non-empty arrays |
181
- | **Entity graph** | `view.entityGraph.get()` returns the full entity graph after project init |
182
- | **Entity detail** | Call `view.requestEntityData(['<uuid>'])` then read `view.entityInfoMap.get()['<uuid>']` — `value` and `categories` populated |
183
- | **Entity relationships** | Call `view.fetchEntityRelationships('<iri>')` and confirm incoming/outgoing edges |
184
- | **Entity documents** | Call `view.fetchEntityDocuments('<iri>')` and confirm document UUIDs |
185
- | **Document data** | Call `view.requestDocumentData(['<id>'])` then read `view.documentInfoMap.get()['<id>']` |
186
- | **Project documents overview** | `view.projectDocumentsData.get()` returns `documentsBySuffix` and `documentsByContentCategory` |
187
- | **Search** | Call `view.search('test')` and confirm `view.searchResults.get()` accumulates results |
188
- | **Language change** | Call `view.setLanguage('da')` and confirm category labels switch |
189
- | **Stale-while-revalidate** | With a warm `QueryCache`, confirm the signal fires twice — first with stale data, then fresh |
190
- | **Destroy** | Call `view.destroy()` and confirm no further signal updates |
191
-
192
- ### ✅ Phase 6b — Angular adapters
193
-
194
- **Completed.** All 4 `cue-views` services bridged to SDK signals. Build verified (`nx build ng-cue-views` passes). Also fixed a pre-existing ng-packagr `rootDir` issue in `cue-repos` and `cue-views` by overriding `js-cue-sdk` path to dist in `tsconfig.lib.prod.json`.
195
-
196
- | Area | Status |
197
- |------|--------|
198
- | `CueViewsService` — owns `CueProjectView` signal, effects for project/language change | ✅ |
199
- | `AvailableCategoriesService` — bridges `view.availableContentCategories/EntityCategories/EntityRelationships` | ✅ |
200
- | `ProjectDocumentsService` — bridges `view.projectDocumentsData` | ✅ |
201
- | `DocumentInfoService` — bridges `view.documentInfoMap`; keeps `documentListHandlers` Angular-side | ✅ |
202
- | `EntityInfoService` — bridges `view.entityInfoMap` + `entityGraph`; delegates all 4 methods to view | ✅ |
203
- | `cue-repos/tsconfig.lib.prod.json` — path override to dist to fix ng-packagr TS6059 | ✅ |
204
- | `cue-views/tsconfig.lib.prod.json` — same fix | ✅ |
205
-
206
- ### 🔲 Phase 6c — Gateway API additions
207
-
208
- | Area | How to verify |
209
- |------|--------------|
210
- | **Related documents** | Call `cue.api.relatedDocuments(uuid, 10)` from console; confirm response array with `relevance` scores |
211
- | **Content category change** | Change a document's content category; confirm PATCH fires and SPARQL reflects the update |
212
- | **Agent plan streaming** | Trigger agent plan build; confirm streaming chunks arrive and plan signal updates incrementally |
213
- | **Agent act streaming** | Execute a plan; confirm streaming result chunks arrive and final result is saved via `CueCache` |
214
-
215
- ### 🔲 Phase 6d — SDK data additions
216
-
217
- | Area | How to verify |
218
- |------|--------------|
219
- | **Duplicate list** | `view.documents.fetchDuplicates()` returns a map of content UUIDs → array of file paths |
220
- | **Document entity reads** | `view.entities.fetchDocumentMentions(contentIRI)` returns entity IRIs with labels and categories |
221
-
222
- ### 🔲 Final (portal bootstrap migration — pending)
223
-
224
- | Area | How to verify |
225
- |------|--------------|
226
- | **`nx graph`** | `cue-portal` has zero edges to `js-firebase` |
227
- | **Cold load** | Full page refresh — auth state restores, project loads, entities visible |
228
- | **Emulator** | `nx run cue-portal:serve` with emulator; all Firestore + Storage + Auth calls route correctly |
229
-
230
- ---
231
-
232
- ## Architecture Decisions
233
-
234
- **`js-firebase` stays** — CLI, widget, and admin depend on it directly and always will. The portal's dependency shrinks to the single `FirebaseService` wrapper.
235
-
236
- **`js-databases` as the abstraction boundary** — `IDocStore` and `CueBlobStorage` are Firebase-agnostic. Switching storage provider only requires changing the backing class in `CueFirebase._init()`.
237
-
238
- **Vanilla signals in the SDK** — `CueSignal<T>` + `cueComputed()` in `signal.ts`. No external signal library. Angular adapters bridge to Angular signals via `effect(onCleanup => ...)` + `subscribe()`.
239
-
240
- **`UploadTask` escape hatch** — `FileRepo.uploadRawFile` still returns a native Firebase `UploadTask` because `cue-views/handlers.service.ts` depends on `task.on('state_changed', ...)` for per-file upload progress. Resolved in Phase 6.
241
-
242
- **`CueCache` uses `firebase/storage` directly** — only needs the `persistence` bucket; no need to instantiate all 6 buckets via `CueBlobStorage`.
243
-
244
- ---
245
-
246
- ## SDK Module Reference
247
-
248
- | Module | Class | Exposed as | Key members |
249
- |--------|-------|-----------|-------------|
250
- | `auth.ts` | `CueAuth` | `cue.auth` | `user`, `token`, `isSuperAdmin`, `userIds` (all `ReadonlySignal`); `signIn()`, `signOut()`, `signInWithRedirect()`, `checkRedirectResult()`, `checkSuperAdmin()`, `getToken()`, `authenticatedFetch()` |
251
- | `privileges.ts` | `CuePrivileges` | `cue.privileges` | `privileges: ReadonlySignal<Privileges>`; `setProjectRoles(roles)` |
252
- | `project.ts` | `CueProjects` | `cue.projects` | `inviteUserToProject()`, `changeUserRoleOnProject()`, `removeUserFromProject()` |
253
- | `profile.ts` | `CueProfile` | `cue.profile` | `getUserInfo(uids)`, `acceptTerms()`, API key management |
254
- | `cache.ts` | `CueCache` | `cue.cache` | `getQueryCache`, `setQueryCache`, `getAgentSessionCache`, `setAgentSessionCache`, `getUserProjectCache`, `setUserProjectCache` |
255
- | `signal.ts` | `CueSignal<T>` | exported | Writable reactive state; `get()`, `set()`, `subscribe()` |
256
- | `signal.ts` | `cueComputed()` | exported | Derived read-only signal from deps |
257
- | `signal.ts` | `staleWhileRevalidate()` | exported | Serve stale cache data first, then revalidate; generic `QueryCache` interface |
258
- | `api.ts` | `CueApi` | `cue.api` | `search()`, `sparql()`, `sync` (Node only) |
259
- | `schema.ts` | `CueProjectSchema` | `view.schema` | `availableContentCategories`, `availableEntityCategories`, `availableEntityRelationships` (all `ReadonlySignal`); `setLanguage()`, `refresh()` |
260
- | `entities.ts` | `CueProjectEntities` | `view.entities` | `entityInfoMap`, `entityGraph` (all `ReadonlySignal`); `requestEntityData()`, `requestEntityLocations()`, `fetchEntityRelationships()`, `fetchEntityDocuments()`, `entityIri()`, `reset()` |
261
- | `documents.ts` | `CueProjectDocuments` | `view.documents` | `documentInfoMap`, `projectDocumentsData` (all `ReadonlySignal`); `requestDocumentData()`, `fetchOverview()`, `setLanguage()`, `reset()` |
262
- | `project-view.ts` _(pending)_ | `CueProjectView` | `cue.createProjectView()` | Facade over schema + entities + documents; adds `search()`, `searchResults`, `setLanguage()`, `destroy()` |
263
-
264
- ---
265
-
266
- ## Firestore Collections Reference
267
-
268
- | Collection | Document type | Owner |
269
- |-----------|--------------|-------|
270
- | `projects` | `ProjectDoc` | `ProjectRepo` → `docStore` |
271
- | `users` | `UserDoc` | `UserRepo` → `docStore` |
272
- | `organizations` | `OrganizationDoc` | `OrganizationRepo` → `docStore` |
273
- | `apiKeys` | `APIKeyDoc` | `APIKeysRepo` → `docStore` |
274
- | `rdfWriting` | `RDFWritingDoc` | `RDFWritingRepo` → `docStore` |
275
- | `tiers` | `TierDoc` | `FirebaseService` (raw, portal doesn't use) |
276
- | `userTermsAcceptance` | `{ uid, timestamp }` | `FirebaseService` (raw) |
277
- | `chatSessions` | `ChatSessionDoc` | `FirebaseService` (raw) |
278
-
279
- ## Storage Buckets Reference
280
-
281
- | Bucket name | Key | Owner |
282
- |-------------|-----|-------|
283
- | `cue_raw_eu_west6` | `raw` | `FileRepo` → `blobStore` |
284
- | `cue_processed_eu_west6` | `processed` | `FileRepo` → `blobStore` |
285
- | `cue_logs_eu_west6` | `logs` | `FileRepo` → `blobStore` |
286
- | `cue_public_eu_west6` | `public` | `FileRepo` → `blobStore` |
287
- | `db_persistence_eu_west6` | `persistence` | `CueCache` (via `firebase/storage` directly) |
288
- | `cue_chat_sessions_eu_west6` | `chatSessions` | `FileRepo` → `blobStore` |
289
-
290
- ---
291
-
292
- ## Completed Work (archive)
293
-
294
- ### Phase 6 (partial) — Knowledge Graph data classes
295
-
296
- | Class | File | Replaces |
297
- |---|---|---|
298
- | `CueProjectSchema` | `schema.ts` | `AvailableCategoriesService` |
299
- | `CueProjectEntities` | `entities.ts` | `EntityInfoService` |
300
- | `CueProjectDocuments` | `documents.ts` | `ProjectDocumentsService` + `DocumentInfoService` (SPARQL) |
301
-
302
- All three classes:
303
- - Accept `CueApi` + `projectId` — no Angular dependencies
304
- - Use `CueSignal<T>` / `cueComputed()` — framework-agnostic reactive signals
305
- - Accept optional `QueryCache` for stale-while-revalidate caching via `staleWhileRevalidate()`
306
- - Use `js/prefixes` (`qaecyPrefixes`, `prefixCC`) — no inline namespace constants
307
- - Exported from `libs/js/cue-sdk/src/index.ts`
308
-
309
- `staleWhileRevalidate<T>(query, fetchFresh, onData, cache?)` helper added to `signal.ts`:
310
- - Serves cached (stale) data immediately via `cache.get(key)` then fires `onData(stale, true)`
311
- - Fetches fresh data, fires `onData(fresh, false)`, writes to cache only if data changed
312
- - Cache key is `contextBasedGuid(query)` (deterministic UUID v5 hash)
313
-
314
- ---
315
-
316
- ### `js-databases` — Provider-agnostic storage layer
317
-
318
- - `IDocStore` interface + `FirestoreDocStore` implementation
319
- - `CueBlobStorage` covers all 6 named buckets and all file operations
320
- - `CueFirebase` constructs and exposes `docStore` + `blobStore`
321
-
322
- ### `js-cue-sdk` additions
323
-
324
- - **`Cue.fromApp(app, config?)`** — static factory that reuses an existing `FirebaseApp` (portal shares auth session with SDK without a second login)
325
- - **`CueSignal<T>` + `cueComputed()`** — vanilla framework-agnostic reactive primitives
326
- - **`CueAuth` signals** — `user`, `token`, `isSuperAdmin`, `userIds` all reactive via `onIdTokenChanged`
327
- - **`CuePrivileges`** — role expansion (`admin → [admin, syncer, member]`), `REQUIRED_ROLES`, `privileges` signal auto-recomputes when roles or superadmin status changes
328
- - **`CueProjects`** cloud function wrappers: `inviteUserToProject`, `changeUserRoleOnProject`, `removeUserFromProject`
329
- - **`CueProfile`** cloud function wrappers: `getUserInfo`, `acceptTerms`
330
- - **`CueCache`** — gzip cache over `db_persistence_eu_west6`; uses `CompressionStream`/`DecompressionStream` (web standard, no `fflate` in SDK)
331
- - **Doc types in SDK models** — `ProjectDoc`, `OrganizationDoc`, `UserDoc`, `RDFWritingDoc`, `ViewDefinition` (type aliases/interfaces; classes remain in `js-firebase` for CLI/admin)
332
-
333
- ### `cue-repos` — Angular adapters
334
-
335
- | Service / Repo | Before | After |
336
- |----------------|--------|-------|
337
- | All 5 doc repos | Raw `CollectionReference` + `onSnapshot` | `docStore.subscribeToCollection/Doc` |
338
- | `FileRepo` | Raw `firebase/storage` calls | `blobStore.*` |
339
- | `CacheRepo` | 200-line `fflate`-based gzip impl | 40-line delegate to `cue.cache` |
340
- | `PrivilegesService` | Owned all role logic | Thin adapter — syncs from `cue.privileges` signal |
341
- | `CueSdkService` | — | New: `sdk: Signal<Cue \| undefined>` via `Cue.fromApp()` |
342
- | `settings.component.ts` | Used `FirebaseService` | Uses `CueSdkService → sdk.projects.*` |
343
- | `UsersRepo` | Used `FirebaseService.functionGetUserInfo` | Uses `sdk.profile.getUserInfo()` |
344
-
345
- Doc type imports in `cue-repos` and portal services moved from `js-firebase` → `js-cue-sdk` (7 files, type-only).
346
-