@owlmeans/server-planning 0.1.18-rc.15 → 0.1.18-rc.17

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 CHANGED
@@ -10,7 +10,7 @@ the `@owlmeans/server-planning/store` subpath.
10
10
  ## Installation
11
11
 
12
12
  ```sh
13
- bun add @owlmeans/server-planning@^0.1.18-rc.15 @owlmeans/planning@^0.1.18-rc.13 ajv
13
+ bun add @owlmeans/server-planning@^0.1.18-rc.17 @owlmeans/planning@^0.1.18-rc.14 ajv
14
14
  ```
15
15
 
16
16
  ## Concepts
@@ -169,7 +169,7 @@ This package ships embedded agent skills under `agent-meta/`. After installing y
169
169
  your project's skill store (`.agents/skills/`):
170
170
 
171
171
  ```sh
172
- npx @owlmeans/agent-skills@^0.1.18-rc.44
172
+ npx @owlmeans/agent-skills@^0.1.18-rc.45
173
173
  ```
174
174
 
175
175
  The embedded files are version-matched to this package release. Do not edit them
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "schemaVersion": 2,
3
3
  "package": "@owlmeans/server-planning",
4
- "version": "0.1.18-rc.15",
5
- "generatedAt": "2026-09-30T09:41:02.821Z",
4
+ "version": "0.1.18-rc.17",
5
+ "generatedAt": "2026-10-02T19:07:09.538Z",
6
6
  "canonicalRepo": "https://github.com/owlmeans/common",
7
7
  "entries": [
8
8
  {
@@ -8,7 +8,7 @@ user-invocable: false
8
8
  # @owlmeans/server-planning
9
9
 
10
10
  **Layer:** Server
11
- **Install:** `"@owlmeans/server-planning": "^0.1.18-rc.15"` in `dependencies` (`ajv` is a peer)
11
+ **Install:** `"@owlmeans/server-planning": "^0.1.18-rc.17"` in `dependencies` (`ajv` is a peer)
12
12
 
13
13
  The general implementation of `@owlmeans/planning`: the planning service (a plugin host), the
14
14
  scoped facade, the executor every write goes through, the in-memory reference store, the commit
@@ -31,7 +31,7 @@ reuses the `./store` subpath (`foldPending`, `makeCommitHub`) without pulling fa
31
31
  | `PlanningAccessResolver`, `PlanningAccess`, `PlanningAccessGrants`, `PlanningGrant` | The optional access decision a hosting app supplies |
32
32
  | `listCards` … `executePlanning`, `getCommit`, `watchCommits`, `listSchemas`, `defineSchemas`, `applySchemaRequest` | The handlers, to bind one by hand |
33
33
  | `scopeOf(req, extra?)`, `accessScopeOf(req, access, extra?)`, `handlerScopeOf`, `assertGranted`, `actorOf(req)`, `concealed(run)`, `clampSeconds` | Scope and security helpers |
34
- | `makeDefinitions(runtime, facade)`, `makeSchemaViews(opts)`, `projectCriteriaOf(projects)` | Data-defined schemas and the project narrowing |
34
+ | `makeDefinitions(runtime, facade)`, `makeSchemaViews(opts)`, `projectCriteriaOf(projects, through?)` | Data-defined schemas and the project narrowing |
35
35
  | `makeProjectionProcessor(ctx, opts?)`, `planningQueueHooks(ctx, opts?)` | A generic projection job body and its `onJobDead` |
36
36
  | `./store`: `makeMemoryPlanningStore`, `foldPending`, `failPending`, `revisionsFromLog`, `commitEventOf`, `makeCommitHub`, `makeCompositeStore`, `wantsSpecifications` | What stores are built from |
37
37
  | `./conformance`: `planningConformance`, `conformanceCasesFor`, `planningConformancePlugin`, `conformanceClock`, `ConformanceFailure` | The store conformance suite, runner-agnostic |
@@ -291,6 +291,13 @@ mapping external records (`mappers`) belongs to that plugin's own store adapter.
291
291
  from the request, never the body (`wireExecution` drops a draft's claim; the executor's
292
292
  `withCreator` stamps the subject, and `assertCreatorFixed` refuses a body whose `changes` or
293
293
  `unset` names `createdBy` — an update can never re-own a card).
294
+ - The organization of a scope is the one the request ACTS IN. Behind the integrated IAM
295
+ (`@owlmeans/server-iam`) that is the session's acting organization, attached to the request by the
296
+ OIDC guard and keyed by its frozen `entityKey` (stable across renames), so `requireEntityKey(req)`
297
+ is the right tenant key for a product whose people belong
298
+ to several organizations — and, for a product with one shared organization (every person acts in
299
+ the application's own), the same key for everybody. Take it from the request in the handler and
300
+ pass it down; never read it from the context or from a body.
294
301
  - Another entity's card, specification or transition answers `WorkcardNotFound` — the same as an
295
302
  absent id — on reads and writes alike (`concealed`).
296
303
  - Queries arrive in their wire form and are decoded with `decode*Query` before `criteriaOf`, which
@@ -303,12 +310,21 @@ decision per request; a throw is the request's answer (an `AuthForbidden` answer
303
310
 
304
311
  - `entityId` is the resolver's — never the token's, never `opts.scope`'s.
305
312
  - `projects` becomes `PlanningScope.projects`, which the server facade enforces everywhere: the
306
- projects themselves and every card whose `parents` name one are visible (a specification
307
- through its parent card); anything else reads as absent (`WorkcardNotFound`, `null`, an empty
308
- list), a create under an invisible parent is `ParentNotFound` (the executor's own parent load),
309
- lists, counts and summaries are AND'd with `projectCriteriaOf`, links and transitions are
310
- filtered by `project` (and post-filtered, for a store that ignores the field), commit
311
- subscriptions drop events outside the set and a status or wait refuses them.
313
+ projects themselves and every card whose `parents` name one are visible, and so is a
314
+ specification whose parent card is (its `parents` hold only that card); anything else reads as
315
+ absent (`WorkcardNotFound`, `null`, an empty list), a create under an invisible parent is
316
+ `ParentNotFound` (the executor's own parent load), lists, counts and summaries are AND'd with
317
+ `projectCriteriaOf(projects, through)`, links and transitions are filtered by `project` (and
318
+ post-filtered, for a store that ignores the field), commit subscriptions drop events outside the
319
+ set and a status or wait refuses them.
320
+ - A narrowed list or count admits exactly the cards a single read admits. When its criteria ask
321
+ for specifications (`wantsSpecifications`) the facade resolves `through` — the parent cards a
322
+ specification is seen through — with ONE read per call: the query's `parent` loaded, or else the
323
+ ids of the projects' own cards. A summary counts no specification and pays nothing extra.
324
+ - A person who may see only SOME projects of their organization (a lending library's member given
325
+ one branch) is expressed here: the resolver answers the project ids the person's grants list as
326
+ `projects`, and omits the key when a grant covers every project — never a hand-written filter in
327
+ each handler.
312
328
  - `grants` gates the stock handlers' writes: `createProjects` (a project create — `true` for the
313
329
  root, a list names the parent projects), `deleteProjects` (the delete of a project card — a list
314
330
  names the projects), `defineSchemas` (`schema.define` — `true` for the organization's layer, a
package/build/facade.d.ts CHANGED
@@ -2,10 +2,12 @@ import type { PlanningFacade, PlanningScope, Workcard } from '@owlmeans/planning
2
2
  import type { Criteria } from '@owlmeans/resource';
3
3
  import type { PlanningRuntime } from './service.js';
4
4
  /**
5
- * The criteria a scope narrowed to `projects` adds to every card read: the projects themselves and
6
- * every card whose `parents` name one of them.
5
+ * The criteria a scope narrowed to `projects` adds to every card list, count and summary: the
6
+ * projects themselves, every card whose `parents` name one of them, and the specifications whose
7
+ * parent card is one of `through` — the cards of those projects a specification is seen through,
8
+ * exactly as a single read sees it (a specification's `parents` hold only its own card).
7
9
  */
8
- export declare const projectCriteriaOf: (projects: readonly string[]) => Criteria<Workcard>;
10
+ export declare const projectCriteriaOf: (projects: readonly string[], through?: readonly string[]) => Criteria<Workcard>;
9
11
  /**
10
12
  * The scoped facade over the service's stores.
11
13
  *
@@ -14,9 +16,12 @@ export declare const projectCriteriaOf: (projects: readonly string[]) => Criteri
14
16
  * `WorkcardNotFound`, exactly as for an id that never existed. Reads go through the composite
15
17
  * store (the default store plus the stores plugins own); writes go through the executor.
16
18
  *
17
- * A scope naming `projects` sees those projects and the cards whose `parents` name one of them (a
18
- * card's specification through its card); everything else reads as absent, lists are narrowed by
19
- * an AND'd criteria, and commit events and transitions outside the set are dropped or refused.
19
+ * A scope naming `projects` sees those projects, the cards whose `parents` name one of them, and a
20
+ * specification whose parent card is one of those (a card's specification through its card);
21
+ * everything else reads as absent. Lists, counts and summaries are narrowed by an AND'd criteria
22
+ * that admits the same cards a single read does — the parent cards a specification is seen through
23
+ * are resolved once per call ({@link projectCriteriaOf}) — and commit events and transitions
24
+ * outside the set are dropped or refused.
20
25
  *
21
26
  * `definitions` is present when the default store holds data-defined schemas; a model is then
22
27
  * built over the registry of the card's own project.
@@ -1 +1 @@
1
- {"version":3,"file":"facade.d.ts","sourceRoot":"","sources":["../src/facade.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACiB,cAAc,EAAE,aAAa,EACxD,QAAQ,EACT,MAAM,oBAAoB,CAAA;AAC3B,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAA;AAGlD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,cAAc,CAAA;AAGnD;;;GAGG;AACH,eAAO,MAAM,iBAAiB,aAAc,SAAS,MAAM,EAAE,KAAG,QAAQ,CAAC,QAAQ,CAEzD,CAAA;AAExB;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,eAAe,YAAa,eAAe,SAAS,aAAa,KAAG,cAmNhF,CAAA"}
1
+ {"version":3,"file":"facade.d.ts","sourceRoot":"","sources":["../src/facade.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACiB,cAAc,EAAE,aAAa,EACxD,QAAQ,EACT,MAAM,oBAAoB,CAAA;AAC3B,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAA;AAGlD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,cAAc,CAAA;AAInD;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB,aAAc,SAAS,MAAM,EAAE,YAAW,SAAS,MAAM,EAAE,KAAQ,QAAQ,CAAC,QAAQ,CAM1F,CAAA;AAExB;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,eAAe,YAAa,eAAe,SAAS,aAAa,KAAG,cA+OhF,CAAA"}
package/build/facade.js CHANGED
@@ -1,12 +1,19 @@
1
1
  import { criteriaOf, currentSpecification, isProject, isSpecification, linkWhereOf, listOptionsOf, modelOf, projectOf, PlanningUnsupported, specCriteriaOf, transitionWhereOf, WorkcardKind, WorkcardNotFound, } from '@owlmeans/planning';
2
2
  import { makeDefinitions } from './definitions.js';
3
3
  import { executeTransition } from './executor.js';
4
+ import { wantsSpecifications } from './store/memory.js';
4
5
  /**
5
- * The criteria a scope narrowed to `projects` adds to every card read: the projects themselves and
6
- * every card whose `parents` name one of them.
6
+ * The criteria a scope narrowed to `projects` adds to every card list, count and summary: the
7
+ * projects themselves, every card whose `parents` name one of them, and the specifications whose
8
+ * parent card is one of `through` — the cards of those projects a specification is seen through,
9
+ * exactly as a single read sees it (a specification's `parents` hold only its own card).
7
10
  */
8
- export const projectCriteriaOf = (projects) => ({
9
- $or: [{ id: { $in: [...projects] } }, { parents: { $overlaps: [...projects] } }],
11
+ export const projectCriteriaOf = (projects, through = []) => ({
12
+ $or: [
13
+ { id: { $in: [...projects] } },
14
+ { parents: { $overlaps: [...projects] } },
15
+ ...(through.length > 0 ? [{ kind: WorkcardKind.Specification, parent: { $in: [...through] } }] : []),
16
+ ],
10
17
  });
11
18
  /**
12
19
  * The scoped facade over the service's stores.
@@ -16,9 +23,12 @@ export const projectCriteriaOf = (projects) => ({
16
23
  * `WorkcardNotFound`, exactly as for an id that never existed. Reads go through the composite
17
24
  * store (the default store plus the stores plugins own); writes go through the executor.
18
25
  *
19
- * A scope naming `projects` sees those projects and the cards whose `parents` name one of them (a
20
- * card's specification through its card); everything else reads as absent, lists are narrowed by
21
- * an AND'd criteria, and commit events and transitions outside the set are dropped or refused.
26
+ * A scope naming `projects` sees those projects, the cards whose `parents` name one of them, and a
27
+ * specification whose parent card is one of those (a card's specification through its card);
28
+ * everything else reads as absent. Lists, counts and summaries are narrowed by an AND'd criteria
29
+ * that admits the same cards a single read does — the parent cards a specification is seen through
30
+ * are resolved once per call ({@link projectCriteriaOf}) — and commit events and transitions
31
+ * outside the set are dropped or refused.
22
32
  *
23
33
  * `definitions` is present when the default store holds data-defined schemas; a model is then
24
34
  * built over the registry of the card's own project.
@@ -42,9 +52,35 @@ export const makeStoreFacade = (runtime, scope) => {
42
52
  }
43
53
  return null;
44
54
  };
45
- const narrow = (where) => projects == null
55
+ /**
56
+ * The cards a narrowed list or count may see specifications THROUGH — what {@link visible} admits
57
+ * one by: its parent card in the scope's projects. One read per call, and only for criteria that
58
+ * ask for specifications at all (`wantsSpecifications`, the rule every store routes a list by): the
59
+ * parent the query names, or else the projects' own cards. A summary counts no specification.
60
+ */
61
+ const throughOf = async (where, parent) => {
62
+ if (projects == null || projects.length === 0 || !wantsSpecifications(where)) {
63
+ return [];
64
+ }
65
+ if (parent != null) {
66
+ const card = mine(await reader().cards.get(parent, entityId));
67
+ return card != null && inProjects(card) ? [parent] : [];
68
+ }
69
+ const listed = await reader().cards.list({ entityId, parents: { $overlaps: projects } }, { size: 0 });
70
+ // A project's own specifications are matched by their `parents` already.
71
+ return listed.items.filter(card => card.id != null && !projects.includes(card.id) && inProjects(card)).map(card => card.id);
72
+ };
73
+ /** A narrowed list's or count's criteria — `through` as {@link throughOf} resolved it. */
74
+ const narrowed = async (query) => {
75
+ const where = criteriaOf(query, scope);
76
+ return narrow(where, await throughOf(where, query?.parent));
77
+ };
78
+ const narrow = (where, through = []) => projects == null
46
79
  ? where
47
- : { ...where, $and: [...(where.$and ?? []), projectCriteriaOf(projects)] };
80
+ : {
81
+ ...where,
82
+ $and: [...(where.$and ?? []), projectCriteriaOf(projects, through)],
83
+ };
48
84
  const projectVisible = (project) => projects == null || (project != null && projects.includes(project));
49
85
  const commitSource = () => {
50
86
  const commits = reader().commits;
@@ -87,8 +123,8 @@ export const makeStoreFacade = (runtime, scope) => {
87
123
  }
88
124
  return card;
89
125
  },
90
- list: async (query) => await reader().cards.list(narrow(criteriaOf(query, scope)), listOptionsOf(query)),
91
- count: async (query) => await reader().cards.count(narrow(criteriaOf(query, scope))),
126
+ list: async (query) => await reader().cards.list(await narrowed(query), listOptionsOf(query)),
127
+ count: async (query) => await reader().cards.count(await narrowed(query)),
92
128
  summary: async (parents, query) => parents.length === 0
93
129
  ? {}
94
130
  : await reader().cards.summary(parents, narrow(criteriaOf({ kind: query?.kind, type: query?.type }, scope))),
@@ -1 +1 @@
1
- {"version":3,"file":"facade.js","sourceRoot":"","sources":["../src/facade.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"facade.js","sourceRoot":"","sources":["../src/facade.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@owlmeans/server-planning",
3
- "version": "0.1.18-rc.15",
3
+ "version": "0.1.18-rc.17",
4
4
  "license": "MIT",
5
5
  "description": "The general planning implementation — the planning service and its plugin/middleware registry, the transition executor, the in-memory store, the protocol handlers and the commit feed.",
6
6
  "type": "module",
@@ -44,21 +44,21 @@
44
44
  }
45
45
  },
46
46
  "dependencies": {
47
- "@owlmeans/auth": "^0.1.18-rc.36",
48
- "@owlmeans/auth-common": "^0.1.18-rc.42",
47
+ "@owlmeans/auth": "^0.1.18-rc.37",
48
+ "@owlmeans/auth-common": "^0.1.18-rc.43",
49
49
  "@owlmeans/basic-ids": "^0.1.18-rc.34",
50
50
  "@owlmeans/context": "^0.1.18-rc.32",
51
- "@owlmeans/entrypoint": "^0.1.18-rc.37",
51
+ "@owlmeans/entrypoint": "^0.1.18-rc.38",
52
52
  "@owlmeans/error": "^0.1.18-rc.36",
53
- "@owlmeans/planning": "^0.1.18-rc.13",
54
- "@owlmeans/queue": "^0.1.18-rc.36",
53
+ "@owlmeans/planning": "^0.1.18-rc.14",
54
+ "@owlmeans/queue": "^0.1.18-rc.37",
55
55
  "@owlmeans/resource": "^0.1.18-rc.37",
56
56
  "@owlmeans/route": "^0.1.18-rc.33",
57
- "@owlmeans/server-api": "^0.1.18-rc.46",
58
- "@owlmeans/server-context": "^0.1.18-rc.38",
59
- "@owlmeans/server-entrypoint": "^0.1.18-rc.36",
60
- "@owlmeans/server-socket": "^0.1.18-rc.49",
61
- "@owlmeans/socket": "^0.1.18-rc.35"
57
+ "@owlmeans/server-api": "^0.1.18-rc.47",
58
+ "@owlmeans/server-context": "^0.1.18-rc.39",
59
+ "@owlmeans/server-entrypoint": "^0.1.18-rc.37",
60
+ "@owlmeans/server-socket": "^0.1.18-rc.50",
61
+ "@owlmeans/socket": "^0.1.18-rc.36"
62
62
  },
63
63
  "peerDependencies": {
64
64
  "ajv": "*",
package/src/facade.ts CHANGED
@@ -4,20 +4,27 @@ import {
4
4
  } from '@owlmeans/planning'
5
5
  import type {
6
6
  CommitEvent, CommitSource, PlanningFacade, PlanningScope, Relationship, Specification, Transition,
7
- Workcard, WorkcardModel,
7
+ Workcard, WorkcardModel, WorkcardQuery,
8
8
  } from '@owlmeans/planning'
9
9
  import type { Criteria } from '@owlmeans/resource'
10
10
  import { makeDefinitions } from './definitions.js'
11
11
  import { executeTransition } from './executor.js'
12
12
  import type { PlanningRuntime } from './service.js'
13
+ import { wantsSpecifications } from './store/memory.js'
13
14
  import type { CommitHub } from './store/types.js'
14
15
 
15
16
  /**
16
- * The criteria a scope narrowed to `projects` adds to every card read: the projects themselves and
17
- * every card whose `parents` name one of them.
17
+ * The criteria a scope narrowed to `projects` adds to every card list, count and summary: the
18
+ * projects themselves, every card whose `parents` name one of them, and the specifications whose
19
+ * parent card is one of `through` — the cards of those projects a specification is seen through,
20
+ * exactly as a single read sees it (a specification's `parents` hold only its own card).
18
21
  */
19
- export const projectCriteriaOf = (projects: readonly string[]): Criteria<Workcard> => ({
20
- $or: [{ id: { $in: [...projects] } }, { parents: { $overlaps: [...projects] } }],
22
+ export const projectCriteriaOf = (projects: readonly string[], through: readonly string[] = []): Criteria<Workcard> => ({
23
+ $or: [
24
+ { id: { $in: [...projects] } },
25
+ { parents: { $overlaps: [...projects] } },
26
+ ...(through.length > 0 ? [{ kind: WorkcardKind.Specification, parent: { $in: [...through] } }] : []),
27
+ ],
21
28
  }) as Criteria<Workcard>
22
29
 
23
30
  /**
@@ -28,9 +35,12 @@ export const projectCriteriaOf = (projects: readonly string[]): Criteria<Workcar
28
35
  * `WorkcardNotFound`, exactly as for an id that never existed. Reads go through the composite
29
36
  * store (the default store plus the stores plugins own); writes go through the executor.
30
37
  *
31
- * A scope naming `projects` sees those projects and the cards whose `parents` name one of them (a
32
- * card's specification through its card); everything else reads as absent, lists are narrowed by
33
- * an AND'd criteria, and commit events and transitions outside the set are dropped or refused.
38
+ * A scope naming `projects` sees those projects, the cards whose `parents` name one of them, and a
39
+ * specification whose parent card is one of those (a card's specification through its card);
40
+ * everything else reads as absent. Lists, counts and summaries are narrowed by an AND'd criteria
41
+ * that admits the same cards a single read does — the parent cards a specification is seen through
42
+ * are resolved once per call ({@link projectCriteriaOf}) — and commit events and transitions
43
+ * outside the set are dropped or refused.
34
44
  *
35
45
  * `definitions` is present when the default store holds data-defined schemas; a model is then
36
46
  * built over the registry of the card's own project.
@@ -58,9 +68,37 @@ export const makeStoreFacade = (runtime: PlanningRuntime, scope: PlanningScope):
58
68
  return null
59
69
  }
60
70
 
61
- const narrow = (where: Criteria<Workcard>): Criteria<Workcard> => projects == null
71
+ /**
72
+ * The cards a narrowed list or count may see specifications THROUGH — what {@link visible} admits
73
+ * one by: its parent card in the scope's projects. One read per call, and only for criteria that
74
+ * ask for specifications at all (`wantsSpecifications`, the rule every store routes a list by): the
75
+ * parent the query names, or else the projects' own cards. A summary counts no specification.
76
+ */
77
+ const throughOf = async (where: Criteria<Workcard>, parent?: string): Promise<string[]> => {
78
+ if (projects == null || projects.length === 0 || !wantsSpecifications(where)) {
79
+ return []
80
+ }
81
+ if (parent != null) {
82
+ const card = mine(await reader().cards.get(parent, entityId))
83
+ return card != null && inProjects(card) ? [parent] : []
84
+ }
85
+ const listed = await reader().cards.list({ entityId, parents: { $overlaps: projects } } as unknown as Criteria<Workcard>, { size: 0 })
86
+ // A project's own specifications are matched by their `parents` already.
87
+ return listed.items.filter(card => card.id != null && !projects.includes(card.id) && inProjects(card)).map(card => card.id!)
88
+ }
89
+
90
+ /** A narrowed list's or count's criteria — `through` as {@link throughOf} resolved it. */
91
+ const narrowed = async (query?: WorkcardQuery | null): Promise<Criteria<Workcard>> => {
92
+ const where = criteriaOf(query, scope)
93
+ return narrow(where, await throughOf(where, query?.parent))
94
+ }
95
+
96
+ const narrow = (where: Criteria<Workcard>, through: readonly string[] = []): Criteria<Workcard> => projects == null
62
97
  ? where
63
- : { ...where, $and: [...((where as { $and?: Criteria<Workcard>[] }).$and ?? []), projectCriteriaOf(projects)] } as Criteria<Workcard>
98
+ : {
99
+ ...where,
100
+ $and: [...((where as { $and?: Criteria<Workcard>[] }).$and ?? []), projectCriteriaOf(projects, through)],
101
+ } as Criteria<Workcard>
64
102
 
65
103
  const projectVisible = (project?: string | null): boolean =>
66
104
  projects == null || (project != null && projects.includes(project))
@@ -113,9 +151,9 @@ export const makeStoreFacade = (runtime: PlanningRuntime, scope: PlanningScope):
113
151
  return card
114
152
  },
115
153
 
116
- list: async query => await reader().cards.list(narrow(criteriaOf(query, scope)), listOptionsOf(query)),
154
+ list: async query => await reader().cards.list(await narrowed(query), listOptionsOf(query)),
117
155
 
118
- count: async query => await reader().cards.count(narrow(criteriaOf(query, scope))),
156
+ count: async query => await reader().cards.count(await narrowed(query)),
119
157
 
120
158
  summary: async (parents, query) => parents.length === 0
121
159
  ? {}
@@ -0,0 +1,94 @@
1
+ import { describe, expect, test } from 'bun:test'
2
+ import { WorkcardKind, WorkcardNotFound } from '@owlmeans/planning'
3
+ import type { PlanningFacade, Workcard } from '@owlmeans/planning'
4
+ import { createProject, createTask, ENTITY, makeTestPlanning, PROFILE } from './context.js'
5
+
6
+ /**
7
+ * Two projects with a task each, a design document on each task and a plan on the first project —
8
+ * a specification's `parents` hold only its own card, so a scope narrowed to one project sees the
9
+ * task's document through the task.
10
+ */
11
+ const fixture = async () => {
12
+ const planning = await makeTestPlanning()
13
+ const owner = planning.facade()
14
+ const granted = await createProject(owner, 'Granted')
15
+ const hidden = await createProject(owner, 'Hidden')
16
+ const seen = (await createTask(owner, granted.id!, 'Seen')).card!
17
+ const unseen = (await createTask(owner, hidden.id!, 'Unseen')).card!
18
+ const write = async (card: Workcard, category: string, body: string): Promise<Workcard> =>
19
+ (await (await owner.model(card)).write(category, body, { wait: true })).card!
20
+ const design = await write(seen, 'design', '{"steps":[1]}')
21
+ const hiddenDesign = await write(unseen, 'design', '{"steps":[2]}')
22
+ const plan = await write(granted, 'plan', '{"steps":[3]}')
23
+ const scoped = (projects: string[]): PlanningFacade =>
24
+ planning.service.for({ entityId: ENTITY, profileId: PROFILE, channel: 'test', projects })
25
+
26
+ return { ...planning, owner, granted, hidden, seen, unseen, design, hiddenDesign, plan, scoped }
27
+ }
28
+
29
+ const ids = (items: Workcard[]): string[] => items.map(card => card.id!).sort()
30
+
31
+ describe('@owlmeans/server-planning — a narrowed scope lists what it reads', () => {
32
+ test('a granted card\'s specification is listed and counted as it is read', async () => {
33
+ const { seen, unseen, design, hiddenDesign, plan, granted, scoped } = await fixture()
34
+ const member = scoped([granted.id!])
35
+
36
+ expect((await member.cards.get(design.id!)).id).toBe(design.id!)
37
+ await expect(member.cards.get(hiddenDesign.id!)).rejects.toBeInstanceOf(WorkcardNotFound)
38
+
39
+ const underCard = await member.cards.list({ parent: seen.id!, kind: WorkcardKind.Specification })
40
+ expect(ids(underCard.items)).toEqual([design.id!])
41
+ expect(underCard.total).toBe(1)
42
+ expect(await member.cards.count({ parent: seen.id!, kind: WorkcardKind.Specification })).toBe(1)
43
+ expect((await member.cards.list({ parent: unseen.id!, kind: WorkcardKind.Specification })).items).toEqual([])
44
+ expect(await member.cards.count({ parent: unseen.id! })).toBe(0)
45
+
46
+ const everyDocument = await member.cards.list({ kind: WorkcardKind.Specification })
47
+ expect(ids(everyDocument.items)).toEqual([design.id!, plan.id!].sort())
48
+ expect(await member.cards.count({ kind: WorkcardKind.Specification })).toBe(2)
49
+ expect(ids((await member.cards.list({ kind: WorkcardKind.Card })).items)).toEqual([seen.id!])
50
+
51
+ expect(ids((await member.cards.list({ parent: seen.id!, category: 'design' })).items)).toEqual([design.id!])
52
+ expect((await member.specifications.list(seen.id!)).total).toBe(1)
53
+ // A summary counts a parent's cards, never its documents.
54
+ expect(Object.keys(await member.cards.summary([granted.id!, seen.id!, unseen.id!]))).toEqual([granted.id!])
55
+ })
56
+
57
+ test('every card the narrowed scope reads is the one it lists, and no other', async () => {
58
+ const { owner, granted, scoped } = await fixture()
59
+ const member = scoped([granted.id!])
60
+ const every = { size: 0, kind: [WorkcardKind.Project, WorkcardKind.Card, WorkcardKind.Specification] }
61
+ const everything = (await owner.cards.list(every)).items
62
+ const listed = new Set(ids((await member.cards.list(every)).items))
63
+
64
+ expect(everything.length).toBe(7)
65
+ for (const card of everything) {
66
+ expect([card.id, (await member.cards.load(card.id!)) != null]).toEqual([card.id, listed.has(card.id!)])
67
+ }
68
+ expect(listed.size).toBe(4)
69
+ expect(await member.cards.count(every)).toBe(listed.size)
70
+ })
71
+
72
+ test('a scope with no project, or another one, sees none of the granted project\'s documents', async () => {
73
+ const { seen, design, plan, hidden, scoped } = await fixture()
74
+
75
+ for (const outsider of [scoped([]), scoped([hidden.id!])]) {
76
+ await expect(outsider.cards.get(design.id!)).rejects.toBeInstanceOf(WorkcardNotFound)
77
+ expect((await outsider.cards.list({ parent: seen.id!, kind: WorkcardKind.Specification })).items).toEqual([])
78
+ expect(await outsider.cards.count({ parent: seen.id! })).toBe(0)
79
+ const documents = ids((await outsider.cards.list({ kind: WorkcardKind.Specification })).items)
80
+ expect(documents).not.toContain(design.id!)
81
+ expect(documents).not.toContain(plan.id!)
82
+ }
83
+ expect((await scoped([]).cards.list({ size: 0, kind: [WorkcardKind.Card, WorkcardKind.Specification] })).total).toBe(0)
84
+ })
85
+
86
+ test('an unnarrowed scope sees every document of the organization', async () => {
87
+ const { owner, unseen, design, hiddenDesign, plan } = await fixture()
88
+
89
+ expect(ids((await owner.cards.list({ kind: WorkcardKind.Specification })).items))
90
+ .toEqual([design.id!, hiddenDesign.id!, plan.id!].sort())
91
+ expect(await owner.cards.count({ kind: WorkcardKind.Specification })).toBe(3)
92
+ expect(ids((await owner.cards.list({ parent: unseen.id!, kind: WorkcardKind.Specification })).items)).toEqual([hiddenDesign.id!])
93
+ })
94
+ })