@fuzdev/fuz_app 0.141.0 → 0.142.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.
Files changed (147) hide show
  1. package/dist/actions/CLAUDE.md +10 -5
  2. package/dist/actions/connection_closer.d.ts +19 -2
  3. package/dist/actions/connection_closer.d.ts.map +1 -1
  4. package/dist/actions/connection_closer.js +25 -2
  5. package/dist/actions/perform_action.d.ts +10 -0
  6. package/dist/actions/perform_action.d.ts.map +1 -1
  7. package/dist/actions/perform_action.js +23 -9
  8. package/dist/actions/register_ws_endpoint.d.ts.map +1 -1
  9. package/dist/actions/register_ws_endpoint.js +5 -2
  10. package/dist/auth/CLAUDE.md +33 -13
  11. package/dist/auth/account_actions.d.ts.map +1 -1
  12. package/dist/auth/account_actions.js +12 -1
  13. package/dist/auth/account_route_schema.d.ts.map +1 -1
  14. package/dist/auth/account_route_schema.js +8 -0
  15. package/dist/auth/account_routes.d.ts +7 -2
  16. package/dist/auth/account_routes.d.ts.map +1 -1
  17. package/dist/auth/account_routes.js +240 -187
  18. package/dist/auth/admin_action_specs.d.ts +6 -1
  19. package/dist/auth/admin_action_specs.d.ts.map +1 -1
  20. package/dist/auth/admin_action_specs.js +6 -1
  21. package/dist/auth/admin_actions.d.ts.map +1 -1
  22. package/dist/auth/admin_actions.js +14 -2
  23. package/dist/auth/bootstrap_routes.d.ts.map +1 -1
  24. package/dist/auth/bootstrap_routes.js +85 -76
  25. package/dist/auth/cell_action_specs.d.ts +7 -3
  26. package/dist/auth/cell_action_specs.d.ts.map +1 -1
  27. package/dist/auth/cell_action_specs.js +9 -5
  28. package/dist/auth/cell_actions.d.ts +3 -3
  29. package/dist/auth/cell_actions.d.ts.map +1 -1
  30. package/dist/auth/cell_actions.js +67 -38
  31. package/dist/auth/cell_authorize.d.ts +69 -8
  32. package/dist/auth/cell_authorize.d.ts.map +1 -1
  33. package/dist/auth/cell_authorize.js +89 -9
  34. package/dist/auth/cell_field_action_specs.d.ts +5 -4
  35. package/dist/auth/cell_field_action_specs.d.ts.map +1 -1
  36. package/dist/auth/cell_field_action_specs.js +7 -7
  37. package/dist/auth/cell_field_actions.d.ts +7 -5
  38. package/dist/auth/cell_field_actions.d.ts.map +1 -1
  39. package/dist/auth/cell_field_actions.js +24 -22
  40. package/dist/auth/cell_grant_action_specs.d.ts +6 -0
  41. package/dist/auth/cell_grant_action_specs.d.ts.map +1 -1
  42. package/dist/auth/cell_grant_action_specs.js +6 -0
  43. package/dist/auth/cell_grant_actions.d.ts +3 -1
  44. package/dist/auth/cell_grant_actions.d.ts.map +1 -1
  45. package/dist/auth/cell_grant_actions.js +16 -2
  46. package/dist/auth/cell_item_action_specs.d.ts +5 -4
  47. package/dist/auth/cell_item_action_specs.d.ts.map +1 -1
  48. package/dist/auth/cell_item_action_specs.js +7 -7
  49. package/dist/auth/cell_item_actions.d.ts +6 -5
  50. package/dist/auth/cell_item_actions.d.ts.map +1 -1
  51. package/dist/auth/cell_item_actions.js +23 -22
  52. package/dist/auth/cell_relation_list_limit.d.ts +20 -0
  53. package/dist/auth/cell_relation_list_limit.d.ts.map +1 -0
  54. package/dist/auth/cell_relation_list_limit.js +27 -0
  55. package/dist/auth/cell_relation_visibility.d.ts +4 -3
  56. package/dist/auth/cell_relation_visibility.d.ts.map +1 -1
  57. package/dist/auth/cell_relation_visibility.js +6 -5
  58. package/dist/auth/cell_steward.d.ts +45 -0
  59. package/dist/auth/cell_steward.d.ts.map +1 -0
  60. package/dist/auth/cell_steward.js +53 -0
  61. package/dist/auth/request_context.d.ts +4 -0
  62. package/dist/auth/request_context.d.ts.map +1 -1
  63. package/dist/auth/request_context.js +6 -1
  64. package/dist/auth/role_grant_offer_action_specs.d.ts +5 -0
  65. package/dist/auth/role_grant_offer_action_specs.d.ts.map +1 -1
  66. package/dist/auth/role_grant_offer_action_specs.js +6 -1
  67. package/dist/auth/role_grant_offer_actions.d.ts.map +1 -1
  68. package/dist/auth/role_grant_offer_actions.js +23 -16
  69. package/dist/auth/role_grant_offer_queries.d.ts +8 -6
  70. package/dist/auth/role_grant_offer_queries.d.ts.map +1 -1
  71. package/dist/auth/role_grant_offer_queries.js +16 -8
  72. package/dist/auth/signup_routes.d.ts +4 -3
  73. package/dist/auth/signup_routes.d.ts.map +1 -1
  74. package/dist/auth/signup_routes.js +157 -134
  75. package/dist/auth/token_scope.d.ts +7 -1
  76. package/dist/auth/token_scope.d.ts.map +1 -1
  77. package/dist/auth/token_scope.js +8 -2
  78. package/dist/db/CLAUDE.md +32 -19
  79. package/dist/db/cell_ddl.d.ts +1 -2
  80. package/dist/db/cell_ddl.d.ts.map +1 -1
  81. package/dist/db/cell_ddl.js +1 -2
  82. package/dist/db/cell_field_queries.d.ts +20 -18
  83. package/dist/db/cell_field_queries.d.ts.map +1 -1
  84. package/dist/db/cell_field_queries.js +28 -22
  85. package/dist/db/cell_item_queries.d.ts +20 -14
  86. package/dist/db/cell_item_queries.d.ts.map +1 -1
  87. package/dist/db/cell_item_queries.js +28 -18
  88. package/dist/db/cell_moderation.d.ts +67 -0
  89. package/dist/db/cell_moderation.d.ts.map +1 -0
  90. package/dist/db/cell_moderation.js +66 -0
  91. package/dist/db/cell_queries.d.ts +44 -14
  92. package/dist/db/cell_queries.d.ts.map +1 -1
  93. package/dist/db/cell_queries.js +68 -45
  94. package/dist/db/cell_view_sql.d.ts +102 -0
  95. package/dist/db/cell_view_sql.d.ts.map +1 -0
  96. package/dist/db/cell_view_sql.js +112 -0
  97. package/dist/db/db_pg.d.ts +1 -1
  98. package/dist/db/db_pg.js +1 -1
  99. package/dist/http/auth_shape.d.ts +5 -2
  100. package/dist/http/auth_shape.d.ts.map +1 -1
  101. package/dist/http/auth_shape.js +5 -2
  102. package/dist/http/ip_canonical.d.ts +30 -3
  103. package/dist/http/ip_canonical.d.ts.map +1 -1
  104. package/dist/http/ip_canonical.js +50 -3
  105. package/dist/primitive_schemas.d.ts +10 -1
  106. package/dist/primitive_schemas.d.ts.map +1 -1
  107. package/dist/primitive_schemas.js +11 -2
  108. package/dist/rate_limiter.d.ts +179 -12
  109. package/dist/rate_limiter.d.ts.map +1 -1
  110. package/dist/rate_limiter.js +352 -42
  111. package/dist/server/serve_fact_route.d.ts +8 -4
  112. package/dist/server/serve_fact_route.d.ts.map +1 -1
  113. package/dist/server/serve_fact_route.js +15 -6
  114. package/dist/testing/CLAUDE.md +10 -3
  115. package/dist/testing/cross_backend/account_lifecycle.d.ts.map +1 -1
  116. package/dist/testing/cross_backend/account_lifecycle.js +37 -2
  117. package/dist/testing/cross_backend/cell_gated_create.d.ts +38 -0
  118. package/dist/testing/cross_backend/cell_gated_create.d.ts.map +1 -1
  119. package/dist/testing/cross_backend/cell_gated_create.js +401 -5
  120. package/dist/testing/cross_backend/cell_relations.d.ts.map +1 -1
  121. package/dist/testing/cross_backend/cell_relations.js +145 -2
  122. package/dist/testing/cross_backend/expected_schema.json +0 -1
  123. package/dist/testing/cross_backend/login_security.d.ts +16 -0
  124. package/dist/testing/cross_backend/login_security.d.ts.map +1 -1
  125. package/dist/testing/cross_backend/login_security.js +154 -0
  126. package/dist/testing/cross_backend/query_shape.d.ts.map +1 -1
  127. package/dist/testing/cross_backend/query_shape.js +24 -2
  128. package/dist/testing/cross_backend/role_grant_participation.d.ts.map +1 -1
  129. package/dist/testing/cross_backend/role_grant_participation.js +64 -0
  130. package/dist/testing/cross_backend/spine_surface_constants.d.ts +1 -1
  131. package/dist/testing/cross_backend/spine_surface_constants.js +1 -1
  132. package/dist/testing/cross_backend/ws_action_rate_limit.d.ts.map +1 -1
  133. package/dist/testing/cross_backend/ws_action_rate_limit.js +21 -1
  134. package/dist/testing/schema_introspect.js +1 -1
  135. package/dist/testing/schema_parity.d.ts +4 -3
  136. package/dist/testing/schema_parity.d.ts.map +1 -1
  137. package/dist/testing/schema_parity.js +4 -3
  138. package/dist/testing/schema_ready_fixture.d.ts +2 -4
  139. package/dist/testing/schema_ready_fixture.d.ts.map +1 -1
  140. package/dist/testing/schema_ready_fixture.js +2 -4
  141. package/dist/ui/auth_state.svelte.d.ts +10 -0
  142. package/dist/ui/auth_state.svelte.d.ts.map +1 -1
  143. package/dist/ui/auth_state.svelte.js +22 -4
  144. package/package.json +1 -1
  145. package/dist/db/cell_history_ddl.d.ts +0 -38
  146. package/dist/db/cell_history_ddl.d.ts.map +0 -1
  147. package/dist/db/cell_history_ddl.js +0 -61
@@ -8,7 +8,10 @@
8
8
  * not by allowing duplicate field rows.
9
9
  *
10
10
  * Reads filter both endpoints by `cell.deleted_at IS NULL` so relations
11
- * dangling off a soft-deleted cell don't surface to the live graph.
11
+ * dangling off a soft-deleted cell don't surface to the live graph, and the
12
+ * list reads apply the view predicate (`db/cell_view_sql.ts`) to the far end
13
+ * before `LIMIT` — a page is up to `limit` edges whose far end the caller can
14
+ * view.
12
15
  *
13
16
  * `query_cell_field_set` upserts on the `(source_id, name)` PK so
14
17
  * re-pointing a name updates `target_id` in place — JSON-object semantics
@@ -18,6 +21,7 @@
18
21
  */
19
22
  import type { QueryDeps } from './query_deps.js';
20
23
  import type { Uuid } from '../primitive_schemas.js';
24
+ import { type CellViewer } from './cell_view_sql.js';
21
25
  /** Row shape returned by `cell_field` SELECTs. */
22
26
  export interface CellFieldRow {
23
27
  source_id: Uuid;
@@ -77,38 +81,36 @@ export declare const query_cell_field_delete: (deps: QueryDeps, source_id: Uuid,
77
81
  /**
78
82
  * Forward fields list (`source.fields[]`).
79
83
  *
80
- * Filters target by `deleted_at IS NULL` so relations to tombstoned cells
81
- * don't surface; the source filter is the caller's responsibility (gated
82
- * upstream by `can_view_cell(source)`).
84
+ * Up to `limit` fields whose target is live and one `viewer` may view
85
+ * (`can_view_cell_sql`, applied before the limit); `name_after` pages on.
86
+ * The source-view gate is the caller's responsibility.
83
87
  *
84
88
  * @param deps - query deps
89
+ * @param viewer - who is reading; `CELL_VIEWER_UNRESTRICTED` filters nothing
85
90
  * @param source_id - source cell id
86
- * @param options - `limit` caps the row count; `name_after` resumes after a
87
- * name (keyset pagination)
91
+ * @param options - `limit` caps the row count (omitted = unbounded); `name_after`
92
+ * resumes after a name (keyset pagination)
88
93
  * @returns matching rows in lex `name` order
89
94
  */
90
- export declare const query_cell_field_list_for_source: (deps: QueryDeps, source_id: Uuid, options?: {
95
+ export declare const query_cell_field_list_for_source: (deps: QueryDeps, viewer: CellViewer, source_id: Uuid, options?: {
91
96
  limit?: number;
92
97
  name_after?: string;
93
98
  }) => Promise<Array<CellFieldRow>>;
94
99
  /**
95
100
  * Reverse fields list (`target.upfields[]`).
96
101
  *
97
- * Returns rows whose `target_id = $1`, joined to `cell` on `source_id` so
98
- * relations from tombstoned sources don't surface. The caller-side
99
- * authz filter (per-source `can_view_cell`) runs after the SQL fetch
100
- * — see the 2-layer authz contract on `cell_field_list({target_id})`.
101
- *
102
- * Bounded by `limit` (the wire `cell_field_list` cap) so a heavily
103
- * inbound-linked target can't force an unbounded fetch + per-source authz
104
- * pass on the public, IP-rate-limited reverse endpoint.
102
+ * Up to `limit` fields whose source is live and one `viewer` may view —
103
+ * filtered before the limit (`can_view_cell_sql`), so sources the caller
104
+ * can't see never crowd out ones it can. The target-view gate is the
105
+ * caller's responsibility.
105
106
  *
106
107
  * @param deps - query deps
108
+ * @param viewer - who is reading; `CELL_VIEWER_UNRESTRICTED` filters nothing
107
109
  * @param target_id - target cell id
108
- * @param options - `limit` caps the row count
109
- * @returns matching rows, oldest field first (by the field row's `created_at`)
110
+ * @param options - `limit` caps the row count (omitted = unbounded)
111
+ * @returns matching rows, oldest field first (by the field row's `created_at`, then its key)
110
112
  */
111
- export declare const query_cell_field_list_for_target: (deps: QueryDeps, target_id: Uuid, options?: {
113
+ export declare const query_cell_field_list_for_target: (deps: QueryDeps, viewer: CellViewer, target_id: Uuid, options?: {
112
114
  limit?: number;
113
115
  }) => Promise<Array<CellFieldRow>>;
114
116
  //# sourceMappingURL=cell_field_queries.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"cell_field_queries.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/db/cell_field_queries.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,yBAAyB,CAAC;AAIpD,kDAAkD;AAClD,MAAM,WAAW,YAAY;IAC5B,SAAS,EAAE,IAAI,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,IAAI,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;CACnB;AAED;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB,2DAKuB,CAAC;AAKvD,wCAAwC;AACxC,MAAM,WAAW,sBAAsB;IACtC,SAAS,EAAE,IAAI,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,IAAI,CAAC;CAChB;AAED;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,oBAAoB,GAChC,MAAM,SAAS,EACf,OAAO,sBAAsB,KAC3B,OAAO,CAAC,YAAY,CAUtB,CAAC;AAEF;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,oBAAoB,GAChC,MAAM,SAAS,EACf,WAAW,IAAI,EACf,MAAM,MAAM,KACV,OAAO,CAAC,YAAY,GAAG,IAAI,CAM7B,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,uBAAuB,GACnC,MAAM,SAAS,EACf,WAAW,IAAI,EACf,MAAM,MAAM,KACV,OAAO,CAAC,YAAY,GAAG,IAAI,CAO7B,CAAC;AAEF;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,gCAAgC,GAC5C,MAAM,SAAS,EACf,WAAW,IAAI,EACf,UAAU;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE,KAC/C,OAAO,CAAC,KAAK,CAAC,YAAY,CAAC,CAa7B,CAAC;AAEF;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,gCAAgC,GAC5C,MAAM,SAAS,EACf,WAAW,IAAI,EACf,UAAU;IAAE,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,KAC1B,OAAO,CAAC,KAAK,CAAC,YAAY,CAAC,CAS5B,CAAC"}
1
+ {"version":3,"file":"cell_field_queries.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/db/cell_field_queries.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,yBAAyB,CAAC;AAGpD,OAAO,EAIN,KAAK,UAAU,EACf,MAAM,oBAAoB,CAAC;AAE5B,kDAAkD;AAClD,MAAM,WAAW,YAAY;IAC5B,SAAS,EAAE,IAAI,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,IAAI,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;CACnB;AAED;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB,2DAKuB,CAAC;AAKvD,wCAAwC;AACxC,MAAM,WAAW,sBAAsB;IACtC,SAAS,EAAE,IAAI,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,IAAI,CAAC;CAChB;AAED;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,oBAAoB,GAChC,MAAM,SAAS,EACf,OAAO,sBAAsB,KAC3B,OAAO,CAAC,YAAY,CAUtB,CAAC;AAEF;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,oBAAoB,GAChC,MAAM,SAAS,EACf,WAAW,IAAI,EACf,MAAM,MAAM,KACV,OAAO,CAAC,YAAY,GAAG,IAAI,CAM7B,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,uBAAuB,GACnC,MAAM,SAAS,EACf,WAAW,IAAI,EACf,MAAM,MAAM,KACV,OAAO,CAAC,YAAY,GAAG,IAAI,CAO7B,CAAC;AAEF;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,gCAAgC,GAC5C,MAAM,SAAS,EACf,QAAQ,UAAU,EAClB,WAAW,IAAI,EACf,UAAU;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE,KAC/C,OAAO,CAAC,KAAK,CAAC,YAAY,CAAC,CAe7B,CAAC;AAEF;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,gCAAgC,GAC5C,MAAM,SAAS,EACf,QAAQ,UAAU,EAClB,WAAW,IAAI,EACf,UAAU;IAAE,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,KAC1B,OAAO,CAAC,KAAK,CAAC,YAAY,CAAC,CAW5B,CAAC"}
@@ -8,7 +8,10 @@
8
8
  * not by allowing duplicate field rows.
9
9
  *
10
10
  * Reads filter both endpoints by `cell.deleted_at IS NULL` so relations
11
- * dangling off a soft-deleted cell don't surface to the live graph.
11
+ * dangling off a soft-deleted cell don't surface to the live graph, and the
12
+ * list reads apply the view predicate (`db/cell_view_sql.ts`) to the far end
13
+ * before `LIMIT` — a page is up to `limit` edges whose far end the caller can
14
+ * view.
12
15
  *
13
16
  * `query_cell_field_set` upserts on the `(source_id, name)` PK so
14
17
  * re-pointing a name updates `target_id` in place — JSON-object semantics
@@ -18,6 +21,7 @@
18
21
  */
19
22
  import { assert_row } from './assert_row.js';
20
23
  import { columns_sql, iso8601_timestamp_expr, qualify_columns } from './sql_columns.js';
24
+ import { can_view_cell_sql, caller_role_grants_cte, cell_viewer_params } from './cell_view_sql.js';
21
25
  /**
22
26
  * The full `cell_field` column set, named explicitly so a row read fails
23
27
  * loud on schema drift (see `CELL_COLUMNS` in `db/cell_queries.ts`). Column
@@ -85,47 +89,49 @@ export const query_cell_field_delete = async (deps, source_id, name) => {
85
89
  /**
86
90
  * Forward fields list (`source.fields[]`).
87
91
  *
88
- * Filters target by `deleted_at IS NULL` so relations to tombstoned cells
89
- * don't surface; the source filter is the caller's responsibility (gated
90
- * upstream by `can_view_cell(source)`).
92
+ * Up to `limit` fields whose target is live and one `viewer` may view
93
+ * (`can_view_cell_sql`, applied before the limit); `name_after` pages on.
94
+ * The source-view gate is the caller's responsibility.
91
95
  *
92
96
  * @param deps - query deps
97
+ * @param viewer - who is reading; `CELL_VIEWER_UNRESTRICTED` filters nothing
93
98
  * @param source_id - source cell id
94
- * @param options - `limit` caps the row count; `name_after` resumes after a
95
- * name (keyset pagination)
99
+ * @param options - `limit` caps the row count (omitted = unbounded); `name_after`
100
+ * resumes after a name (keyset pagination)
96
101
  * @returns matching rows in lex `name` order
97
102
  */
98
- export const query_cell_field_list_for_source = async (deps, source_id, options) => {
103
+ export const query_cell_field_list_for_source = async (deps, viewer, source_id, options) => {
99
104
  const limit = options?.limit ?? null;
100
105
  const name_after = options?.name_after ?? null;
101
- return deps.db.query(`SELECT ${qualify_columns(CELL_FIELD_COLUMNS, 'f', cell_field_expr('f'))} FROM cell_field f
106
+ return deps.db.query(`WITH ${caller_role_grants_cte('$6', '$7')}
107
+ SELECT ${qualify_columns(CELL_FIELD_COLUMNS, 'f', cell_field_expr('f'))} FROM cell_field f
102
108
  JOIN cell t ON t.id = f.target_id
103
109
  WHERE f.source_id = $1
104
110
  AND t.deleted_at IS NULL
111
+ AND ${can_view_cell_sql('t', { is_admin: '$4', actor_id: '$5' })}
105
112
  AND ($3::text IS NULL OR f.name > $3)
106
113
  ORDER BY f.name ASC
107
- LIMIT $2`, [source_id, limit, name_after]);
114
+ LIMIT $2`, [source_id, limit, name_after, ...cell_viewer_params(viewer)]);
108
115
  };
109
116
  /**
110
117
  * Reverse fields list (`target.upfields[]`).
111
118
  *
112
- * Returns rows whose `target_id = $1`, joined to `cell` on `source_id` so
113
- * relations from tombstoned sources don't surface. The caller-side
114
- * authz filter (per-source `can_view_cell`) runs after the SQL fetch
115
- * — see the 2-layer authz contract on `cell_field_list({target_id})`.
116
- *
117
- * Bounded by `limit` (the wire `cell_field_list` cap) so a heavily
118
- * inbound-linked target can't force an unbounded fetch + per-source authz
119
- * pass on the public, IP-rate-limited reverse endpoint.
119
+ * Up to `limit` fields whose source is live and one `viewer` may view —
120
+ * filtered before the limit (`can_view_cell_sql`), so sources the caller
121
+ * can't see never crowd out ones it can. The target-view gate is the
122
+ * caller's responsibility.
120
123
  *
121
124
  * @param deps - query deps
125
+ * @param viewer - who is reading; `CELL_VIEWER_UNRESTRICTED` filters nothing
122
126
  * @param target_id - target cell id
123
- * @param options - `limit` caps the row count
124
- * @returns matching rows, oldest field first (by the field row's `created_at`)
127
+ * @param options - `limit` caps the row count (omitted = unbounded)
128
+ * @returns matching rows, oldest field first (by the field row's `created_at`, then its key)
125
129
  */
126
- export const query_cell_field_list_for_target = async (deps, target_id, options) => deps.db.query(`SELECT ${qualify_columns(CELL_FIELD_COLUMNS, 'f', cell_field_expr('f'))} FROM cell_field f
130
+ export const query_cell_field_list_for_target = async (deps, viewer, target_id, options) => deps.db.query(`WITH ${caller_role_grants_cte('$5', '$6')}
131
+ SELECT ${qualify_columns(CELL_FIELD_COLUMNS, 'f', cell_field_expr('f'))} FROM cell_field f
127
132
  JOIN cell s ON s.id = f.source_id
128
133
  WHERE f.target_id = $1
129
134
  AND s.deleted_at IS NULL
130
- ORDER BY f.created_at ASC
131
- LIMIT $2`, [target_id, options?.limit ?? null]);
135
+ AND ${can_view_cell_sql('s', { is_admin: '$3', actor_id: '$4' })}
136
+ ORDER BY f.created_at ASC, f.source_id ASC, f.name ASC
137
+ LIMIT $2`, [target_id, options?.limit ?? null, ...cell_viewer_params(viewer)]);
@@ -9,7 +9,9 @@
9
9
  * domain dedup rules ride on top).
10
10
  *
11
11
  * Reads filter both endpoints by `cell.deleted_at IS NULL` so items
12
- * dangling off a soft-deleted cell don't surface.
12
+ * dangling off a soft-deleted cell don't surface, and the list reads apply
13
+ * the view predicate (`db/cell_view_sql.ts`) to the far end before `LIMIT` —
14
+ * a page is up to `limit` edges whose far end the caller can view.
13
15
  *
14
16
  * `query_cell_item_insert` returns the inserted row OR throws the
15
17
  * underlying `23505` (Postgres unique violation) on a `(parent_id,
@@ -21,6 +23,7 @@
21
23
  */
22
24
  import type { QueryDeps } from './query_deps.js';
23
25
  import type { Uuid } from '../primitive_schemas.js';
26
+ import { type CellViewer } from './cell_view_sql.js';
24
27
  /** Row shape returned by `cell_item` SELECTs. */
25
28
  export interface CellItemRow {
26
29
  parent_id: Uuid;
@@ -86,33 +89,36 @@ export declare const query_cell_item_delete: (deps: QueryDeps, parent_id: Uuid,
86
89
  /**
87
90
  * Forward items list (`parent.items[]`), ordered by lex `position`.
88
91
  *
89
- * Filters child by `deleted_at IS NULL` so items pointing at tombstoned
90
- * cells don't surface; the parent filter is the caller's responsibility
91
- * (gated upstream by `can_view_cell(parent)`).
92
+ * Up to `limit` items whose child is live and one `viewer` may view
93
+ * (`can_view_cell_sql`, applied before the limit); `position_after` pages on.
94
+ * The parent-view gate is the caller's responsibility.
92
95
  *
93
96
  * @param deps - query deps
97
+ * @param viewer - who is reading; `CELL_VIEWER_UNRESTRICTED` filters nothing
94
98
  * @param parent_id - parent cell id
95
- * @param options - `limit` caps the row count (passes through to SQL `LIMIT`);
99
+ * @param options - `limit` caps the row count (omitted = unbounded);
96
100
  * `position_after` resumes after a position (keyset pagination)
97
101
  * @returns matching rows in lex `position` order
98
102
  */
99
- export declare const query_cell_item_list_for_parent: (deps: QueryDeps, parent_id: Uuid, options?: {
103
+ export declare const query_cell_item_list_for_parent: (deps: QueryDeps, viewer: CellViewer, parent_id: Uuid, options?: {
100
104
  limit?: number;
101
105
  position_after?: string;
102
106
  }) => Promise<Array<CellItemRow>>;
103
107
  /**
104
108
  * Reverse items list (`child.lists[]`).
105
109
  *
106
- * Returns rows whose `child_id = $1`, joined to `cell` on `parent_id` so
107
- * items from tombstoned parents don't surface. The caller-side authz
108
- * filter (per-parent `can_view_cell`) runs after the SQL fetch — see
109
- * the 2-layer authz contract on `cell_item_list({child_id})`.
110
+ * Up to `limit` items whose parent is live and one `viewer` may view —
111
+ * filtered before the limit (`can_view_cell_sql`), so parents the caller
112
+ * can't see never crowd out ones it can. The child-view gate is the
113
+ * caller's responsibility.
110
114
  *
111
- * Bounded by `limit` (the wire `cell_item_list` cap) so a heavily
112
- * inbound-linked child can't force an unbounded fetch + per-parent authz
113
- * pass on the public, IP-rate-limited reverse endpoint.
115
+ * @param deps - query deps
116
+ * @param viewer - who is reading; `CELL_VIEWER_UNRESTRICTED` filters nothing
117
+ * @param child_id - child cell id
118
+ * @param options - `limit` caps the row count (omitted = unbounded)
119
+ * @returns matching rows, oldest item first (by the item row's `created_at`, then its key)
114
120
  */
115
- export declare const query_cell_item_list_for_child: (deps: QueryDeps, child_id: Uuid, options?: {
121
+ export declare const query_cell_item_list_for_child: (deps: QueryDeps, viewer: CellViewer, child_id: Uuid, options?: {
116
122
  limit?: number;
117
123
  }) => Promise<Array<CellItemRow>>;
118
124
  //# sourceMappingURL=cell_item_queries.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"cell_item_queries.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/db/cell_item_queries.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,yBAAyB,CAAC;AAIpD,iDAAiD;AACjD,MAAM,WAAW,WAAW;IAC3B,SAAS,EAAE,IAAI,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,IAAI,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;CACnB;AAED;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB,8DAKuB,CAAC;AAKtD,0CAA0C;AAC1C,MAAM,WAAW,wBAAwB;IACxC,SAAS,EAAE,IAAI,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,IAAI,CAAC;CACf;AAED;;;;;;;;;;GAUG;AACH,eAAO,MAAM,sBAAsB,GAClC,MAAM,SAAS,EACf,OAAO,wBAAwB,KAC7B,OAAO,CAAC,WAAW,CAQrB,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,mBAAmB,GAC/B,MAAM,SAAS,EACf,WAAW,IAAI,EACf,UAAU,MAAM,KACd,OAAO,CAAC,WAAW,GAAG,IAAI,CAM5B,CAAC;AAEF;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,oBAAoB,GAChC,MAAM,SAAS,EACf,WAAW,IAAI,EACf,cAAc,MAAM,EACpB,cAAc,MAAM,KAClB,OAAO,CAAC,WAAW,GAAG,IAAI,CAS5B,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,sBAAsB,GAClC,MAAM,SAAS,EACf,WAAW,IAAI,EACf,UAAU,MAAM,KACd,OAAO,CAAC,WAAW,GAAG,IAAI,CAO5B,CAAC;AAEF;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,+BAA+B,GAC3C,MAAM,SAAS,EACf,WAAW,IAAI,EACf,UAAU;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,cAAc,CAAC,EAAE,MAAM,CAAA;CAAE,KACnD,OAAO,CAAC,KAAK,CAAC,WAAW,CAAC,CAa5B,CAAC;AAEF;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,8BAA8B,GAC1C,MAAM,SAAS,EACf,UAAU,IAAI,EACd,UAAU;IAAE,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,KAC1B,OAAO,CAAC,KAAK,CAAC,WAAW,CAAC,CAS3B,CAAC"}
1
+ {"version":3,"file":"cell_item_queries.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/db/cell_item_queries.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,yBAAyB,CAAC;AAGpD,OAAO,EAIN,KAAK,UAAU,EACf,MAAM,oBAAoB,CAAC;AAE5B,iDAAiD;AACjD,MAAM,WAAW,WAAW;IAC3B,SAAS,EAAE,IAAI,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,IAAI,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;CACnB;AAED;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB,8DAKuB,CAAC;AAKtD,0CAA0C;AAC1C,MAAM,WAAW,wBAAwB;IACxC,SAAS,EAAE,IAAI,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,IAAI,CAAC;CACf;AAED;;;;;;;;;;GAUG;AACH,eAAO,MAAM,sBAAsB,GAClC,MAAM,SAAS,EACf,OAAO,wBAAwB,KAC7B,OAAO,CAAC,WAAW,CAQrB,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,mBAAmB,GAC/B,MAAM,SAAS,EACf,WAAW,IAAI,EACf,UAAU,MAAM,KACd,OAAO,CAAC,WAAW,GAAG,IAAI,CAM5B,CAAC;AAEF;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,oBAAoB,GAChC,MAAM,SAAS,EACf,WAAW,IAAI,EACf,cAAc,MAAM,EACpB,cAAc,MAAM,KAClB,OAAO,CAAC,WAAW,GAAG,IAAI,CAS5B,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,sBAAsB,GAClC,MAAM,SAAS,EACf,WAAW,IAAI,EACf,UAAU,MAAM,KACd,OAAO,CAAC,WAAW,GAAG,IAAI,CAO5B,CAAC;AAEF;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,+BAA+B,GAC3C,MAAM,SAAS,EACf,QAAQ,UAAU,EAClB,WAAW,IAAI,EACf,UAAU;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,cAAc,CAAC,EAAE,MAAM,CAAA;CAAE,KACnD,OAAO,CAAC,KAAK,CAAC,WAAW,CAAC,CAe5B,CAAC;AAEF;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,8BAA8B,GAC1C,MAAM,SAAS,EACf,QAAQ,UAAU,EAClB,UAAU,IAAI,EACd,UAAU;IAAE,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,KAC1B,OAAO,CAAC,KAAK,CAAC,WAAW,CAAC,CAW3B,CAAC"}
@@ -9,7 +9,9 @@
9
9
  * domain dedup rules ride on top).
10
10
  *
11
11
  * Reads filter both endpoints by `cell.deleted_at IS NULL` so items
12
- * dangling off a soft-deleted cell don't surface.
12
+ * dangling off a soft-deleted cell don't surface, and the list reads apply
13
+ * the view predicate (`db/cell_view_sql.ts`) to the far end before `LIMIT` —
14
+ * a page is up to `limit` edges whose far end the caller can view.
13
15
  *
14
16
  * `query_cell_item_insert` returns the inserted row OR throws the
15
17
  * underlying `23505` (Postgres unique violation) on a `(parent_id,
@@ -21,6 +23,7 @@
21
23
  */
22
24
  import { assert_row } from './assert_row.js';
23
25
  import { columns_sql, iso8601_timestamp_expr, qualify_columns } from './sql_columns.js';
26
+ import { can_view_cell_sql, caller_role_grants_cte, cell_viewer_params } from './cell_view_sql.js';
24
27
  /**
25
28
  * The full `cell_item` column set, named explicitly so a row read fails
26
29
  * loud on schema drift (see `CELL_COLUMNS` in `db/cell_queries.ts`). Column
@@ -98,42 +101,49 @@ export const query_cell_item_delete = async (deps, parent_id, position) => {
98
101
  /**
99
102
  * Forward items list (`parent.items[]`), ordered by lex `position`.
100
103
  *
101
- * Filters child by `deleted_at IS NULL` so items pointing at tombstoned
102
- * cells don't surface; the parent filter is the caller's responsibility
103
- * (gated upstream by `can_view_cell(parent)`).
104
+ * Up to `limit` items whose child is live and one `viewer` may view
105
+ * (`can_view_cell_sql`, applied before the limit); `position_after` pages on.
106
+ * The parent-view gate is the caller's responsibility.
104
107
  *
105
108
  * @param deps - query deps
109
+ * @param viewer - who is reading; `CELL_VIEWER_UNRESTRICTED` filters nothing
106
110
  * @param parent_id - parent cell id
107
- * @param options - `limit` caps the row count (passes through to SQL `LIMIT`);
111
+ * @param options - `limit` caps the row count (omitted = unbounded);
108
112
  * `position_after` resumes after a position (keyset pagination)
109
113
  * @returns matching rows in lex `position` order
110
114
  */
111
- export const query_cell_item_list_for_parent = async (deps, parent_id, options) => {
115
+ export const query_cell_item_list_for_parent = async (deps, viewer, parent_id, options) => {
112
116
  const limit = options?.limit ?? null;
113
117
  const position_after = options?.position_after ?? null;
114
- return deps.db.query(`SELECT ${qualify_columns(CELL_ITEM_COLUMNS, 'i', cell_item_expr('i'))} FROM cell_item i
118
+ return deps.db.query(`WITH ${caller_role_grants_cte('$6', '$7')}
119
+ SELECT ${qualify_columns(CELL_ITEM_COLUMNS, 'i', cell_item_expr('i'))} FROM cell_item i
115
120
  JOIN cell c ON c.id = i.child_id
116
121
  WHERE i.parent_id = $1
117
122
  AND c.deleted_at IS NULL
123
+ AND ${can_view_cell_sql('c', { is_admin: '$4', actor_id: '$5' })}
118
124
  AND ($3::text IS NULL OR i.position > $3)
119
125
  ORDER BY i.position ASC
120
- LIMIT $2`, [parent_id, limit, position_after]);
126
+ LIMIT $2`, [parent_id, limit, position_after, ...cell_viewer_params(viewer)]);
121
127
  };
122
128
  /**
123
129
  * Reverse items list (`child.lists[]`).
124
130
  *
125
- * Returns rows whose `child_id = $1`, joined to `cell` on `parent_id` so
126
- * items from tombstoned parents don't surface. The caller-side authz
127
- * filter (per-parent `can_view_cell`) runs after the SQL fetch — see
128
- * the 2-layer authz contract on `cell_item_list({child_id})`.
131
+ * Up to `limit` items whose parent is live and one `viewer` may view —
132
+ * filtered before the limit (`can_view_cell_sql`), so parents the caller
133
+ * can't see never crowd out ones it can. The child-view gate is the
134
+ * caller's responsibility.
129
135
  *
130
- * Bounded by `limit` (the wire `cell_item_list` cap) so a heavily
131
- * inbound-linked child can't force an unbounded fetch + per-parent authz
132
- * pass on the public, IP-rate-limited reverse endpoint.
136
+ * @param deps - query deps
137
+ * @param viewer - who is reading; `CELL_VIEWER_UNRESTRICTED` filters nothing
138
+ * @param child_id - child cell id
139
+ * @param options - `limit` caps the row count (omitted = unbounded)
140
+ * @returns matching rows, oldest item first (by the item row's `created_at`, then its key)
133
141
  */
134
- export const query_cell_item_list_for_child = async (deps, child_id, options) => deps.db.query(`SELECT ${qualify_columns(CELL_ITEM_COLUMNS, 'i', cell_item_expr('i'))} FROM cell_item i
142
+ export const query_cell_item_list_for_child = async (deps, viewer, child_id, options) => deps.db.query(`WITH ${caller_role_grants_cte('$5', '$6')}
143
+ SELECT ${qualify_columns(CELL_ITEM_COLUMNS, 'i', cell_item_expr('i'))} FROM cell_item i
135
144
  JOIN cell p ON p.id = i.parent_id
136
145
  WHERE i.child_id = $1
137
146
  AND p.deleted_at IS NULL
138
- ORDER BY i.created_at ASC
139
- LIMIT $2`, [child_id, options?.limit ?? null]);
147
+ AND ${can_view_cell_sql('p', { is_admin: '$3', actor_id: '$4' })}
148
+ ORDER BY i.created_at ASC, i.parent_id ASC, i.position ASC
149
+ LIMIT $2`, [child_id, options?.limit ?? null, ...cell_viewer_params(viewer)]);
@@ -0,0 +1,67 @@
1
+ /**
2
+ * The `cell.moderation` read rules, in pure and SQL form side by side.
3
+ *
4
+ * `moderation` is free `TEXT` with no CHECK, so each rule is an allowlist over
5
+ * the literals: a marker this module doesn't name (a typo, a future state)
6
+ * admits nothing.
7
+ *
8
+ * **Audience admission** — `cell_moderation_admits_audience` and
9
+ * `cell_moderation_admits_audience_sql`: unmoderated (`null`) or `'approved'`.
10
+ * A cell's effective audience is its visibility (or grants) **and** its
11
+ * admission, so the public and grant read arms of `can_view_cell` require it,
12
+ * as do the `editor` grant arm of `can_edit_cell` and the matching arms of
13
+ * `query_cell_list` (general and `shared_with` shapes). The owner and
14
+ * global-admin arms don't: an author keeps reading and editing their own
15
+ * pending or rejected contribution, and an admin reads everything.
16
+ *
17
+ * **Stewardship** — `cell_moderation_is_stewardable` and
18
+ * `cell_moderation_is_stewardable_sql`: exactly `'pending'` or `'rejected'`, the
19
+ * states in which the governing root's manager reads a contribution its
20
+ * audience can't (`can_steward_cell`). An unknown marker is neither admitted
21
+ * nor stewardable, so only its owner and admins read it.
22
+ *
23
+ * The pure and SQL forms are written once each here, next to each other, over
24
+ * the same literal constants; every predicate and query composes them rather
25
+ * than restating the rule. Twin of the Rust `fuz_cell::cell_moderation`.
26
+ *
27
+ * @module
28
+ */
29
+ /** `cell.moderation` for a gated contribution awaiting a decision. */
30
+ export declare const CELL_MODERATION_PENDING = "pending";
31
+ /** `cell.moderation` for an approved contribution. */
32
+ export declare const CELL_MODERATION_APPROVED = "approved";
33
+ /** `cell.moderation` for a rejected contribution. */
34
+ export declare const CELL_MODERATION_REJECTED = "rejected";
35
+ /**
36
+ * Whether a cell's `moderation` marker admits it to an audience beyond its
37
+ * owner — unmoderated (`null`) or `'approved'`; `'pending'`, `'rejected'`, and
38
+ * any unknown marker do not.
39
+ *
40
+ * @param moderation - the cell's `moderation` column
41
+ * @returns whether the public and grant read arms may admit the cell
42
+ */
43
+ export declare const cell_moderation_admits_audience: (moderation: string | null) => boolean;
44
+ /**
45
+ * SQL form of `cell_moderation_admits_audience` over the cell alias `alias`
46
+ * (a parenthesized boolean expression).
47
+ *
48
+ * @param alias - the `cell` table alias in the enclosing query
49
+ * @returns the SQL predicate
50
+ */
51
+ export declare const cell_moderation_admits_audience_sql: (alias: string) => string;
52
+ /**
53
+ * Whether a cell's `moderation` marker is one its governing root's manager
54
+ * stewards — exactly `'pending'` or `'rejected'`.
55
+ *
56
+ * @param moderation - the cell's `moderation` column
57
+ * @returns whether the steward read arm may admit the cell
58
+ */
59
+ export declare const cell_moderation_is_stewardable: (moderation: string | null) => boolean;
60
+ /**
61
+ * SQL form of `cell_moderation_is_stewardable` over the cell alias `alias`.
62
+ *
63
+ * @param alias - the `cell` table alias in the enclosing query
64
+ * @returns the SQL predicate
65
+ */
66
+ export declare const cell_moderation_is_stewardable_sql: (alias: string) => string;
67
+ //# sourceMappingURL=cell_moderation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cell_moderation.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/db/cell_moderation.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAEH,sEAAsE;AACtE,eAAO,MAAM,uBAAuB,YAAY,CAAC;AAEjD,sDAAsD;AACtD,eAAO,MAAM,wBAAwB,aAAa,CAAC;AAEnD,qDAAqD;AACrD,eAAO,MAAM,wBAAwB,aAAa,CAAC;AAEnD;;;;;;;GAOG;AACH,eAAO,MAAM,+BAA+B,GAAI,YAAY,MAAM,GAAG,IAAI,KAAG,OACb,CAAC;AAEhE;;;;;;GAMG;AACH,eAAO,MAAM,mCAAmC,GAAI,OAAO,MAAM,KAAG,MACmB,CAAC;AAExF;;;;;;GAMG;AACH,eAAO,MAAM,8BAA8B,GAAI,YAAY,MAAM,GAAG,IAAI,KAAG,OACO,CAAC;AAEnF;;;;;GAKG;AACH,eAAO,MAAM,kCAAkC,GAAI,OAAO,MAAM,KAAG,MACoB,CAAC"}
@@ -0,0 +1,66 @@
1
+ /**
2
+ * The `cell.moderation` read rules, in pure and SQL form side by side.
3
+ *
4
+ * `moderation` is free `TEXT` with no CHECK, so each rule is an allowlist over
5
+ * the literals: a marker this module doesn't name (a typo, a future state)
6
+ * admits nothing.
7
+ *
8
+ * **Audience admission** — `cell_moderation_admits_audience` and
9
+ * `cell_moderation_admits_audience_sql`: unmoderated (`null`) or `'approved'`.
10
+ * A cell's effective audience is its visibility (or grants) **and** its
11
+ * admission, so the public and grant read arms of `can_view_cell` require it,
12
+ * as do the `editor` grant arm of `can_edit_cell` and the matching arms of
13
+ * `query_cell_list` (general and `shared_with` shapes). The owner and
14
+ * global-admin arms don't: an author keeps reading and editing their own
15
+ * pending or rejected contribution, and an admin reads everything.
16
+ *
17
+ * **Stewardship** — `cell_moderation_is_stewardable` and
18
+ * `cell_moderation_is_stewardable_sql`: exactly `'pending'` or `'rejected'`, the
19
+ * states in which the governing root's manager reads a contribution its
20
+ * audience can't (`can_steward_cell`). An unknown marker is neither admitted
21
+ * nor stewardable, so only its owner and admins read it.
22
+ *
23
+ * The pure and SQL forms are written once each here, next to each other, over
24
+ * the same literal constants; every predicate and query composes them rather
25
+ * than restating the rule. Twin of the Rust `fuz_cell::cell_moderation`.
26
+ *
27
+ * @module
28
+ */
29
+ /** `cell.moderation` for a gated contribution awaiting a decision. */
30
+ export const CELL_MODERATION_PENDING = 'pending';
31
+ /** `cell.moderation` for an approved contribution. */
32
+ export const CELL_MODERATION_APPROVED = 'approved';
33
+ /** `cell.moderation` for a rejected contribution. */
34
+ export const CELL_MODERATION_REJECTED = 'rejected';
35
+ /**
36
+ * Whether a cell's `moderation` marker admits it to an audience beyond its
37
+ * owner — unmoderated (`null`) or `'approved'`; `'pending'`, `'rejected'`, and
38
+ * any unknown marker do not.
39
+ *
40
+ * @param moderation - the cell's `moderation` column
41
+ * @returns whether the public and grant read arms may admit the cell
42
+ */
43
+ export const cell_moderation_admits_audience = (moderation) => moderation === null || moderation === CELL_MODERATION_APPROVED;
44
+ /**
45
+ * SQL form of `cell_moderation_admits_audience` over the cell alias `alias`
46
+ * (a parenthesized boolean expression).
47
+ *
48
+ * @param alias - the `cell` table alias in the enclosing query
49
+ * @returns the SQL predicate
50
+ */
51
+ export const cell_moderation_admits_audience_sql = (alias) => `(${alias}.moderation IS NULL OR ${alias}.moderation = '${CELL_MODERATION_APPROVED}')`;
52
+ /**
53
+ * Whether a cell's `moderation` marker is one its governing root's manager
54
+ * stewards — exactly `'pending'` or `'rejected'`.
55
+ *
56
+ * @param moderation - the cell's `moderation` column
57
+ * @returns whether the steward read arm may admit the cell
58
+ */
59
+ export const cell_moderation_is_stewardable = (moderation) => moderation === CELL_MODERATION_PENDING || moderation === CELL_MODERATION_REJECTED;
60
+ /**
61
+ * SQL form of `cell_moderation_is_stewardable` over the cell alias `alias`.
62
+ *
63
+ * @param alias - the `cell` table alias in the enclosing query
64
+ * @returns the SQL predicate
65
+ */
66
+ export const cell_moderation_is_stewardable_sql = (alias) => `${alias}.moderation IN ('${CELL_MODERATION_PENDING}', '${CELL_MODERATION_REJECTED}')`;
@@ -85,6 +85,15 @@ export declare const CELL_COLUMNS: readonly ["id", "data", "kind", "visibility",
85
85
  * actually produces one.
86
86
  */
87
87
  export declare const cell_row_projection: (alias: string) => string;
88
+ /**
89
+ * The columns a view check reads (`can_view_cell`) — the `CELL_COLUMNS`
90
+ * subset `query_cell_view_load_many` projects, typed against `CELL_COLUMNS`
91
+ * so the base const's drift guard covers it. Twin of `fuz_cell`'s
92
+ * `CELL_VIEW_COLUMNS`.
93
+ */
94
+ export declare const CELL_VIEW_COLUMNS: readonly ["id", "visibility", "moderation", "created_by"];
95
+ /** A cell read for its view check alone — the `CELL_VIEW_COLUMNS` projection. */
96
+ export type CellViewRow = Pick<CellRow, (typeof CELL_VIEW_COLUMNS)[number]>;
88
97
  /**
89
98
  * Input for `query_cell_create`. `refs` is derived from `data`. `kind` is
90
99
  * the write-once capability axis (`cell.kind` column) — set here at INSERT
@@ -158,17 +167,28 @@ export declare const query_cell_get: (deps: QueryDeps, id: Uuid, options?: {
158
167
  */
159
168
  export declare const query_cell_get_by_path: (deps: QueryDeps, path: string) => Promise<CellRow | null>;
160
169
  /**
161
- * Bulk-load active cell rows by id, **no visibility filter applied**. Used
162
- * by the strict relation-read filter (`auth/cell_relation_visibility.ts`'s
163
- * `filter_visible_target_ids`), which runs `can_view_cell` per row in
164
- * memory rather than in SQL. Soft-deleted rows are excluded so relations
165
- * to tombstones never surface.
170
+ * Bulk-load active cell rows by id, **no visibility filter applied** — the
171
+ * full rows, for a caller that copies or returns them (the deep-clone walk).
172
+ * A caller that needs only the view check reads `query_cell_view_load_many`.
173
+ * Soft-deleted rows are excluded so relations to tombstones never surface.
166
174
  *
167
175
  * @param deps - query deps
168
176
  * @param ids - cell ids to load (duplicates are harmless)
169
177
  * @returns active rows in arbitrary order (caller indexes by `id`)
170
178
  */
171
179
  export declare const query_cell_load_many: (deps: QueryDeps, ids: ReadonlyArray<Uuid>) => Promise<Array<CellRow>>;
180
+ /**
181
+ * Bulk-load the active cells among `ids` for a view check — the
182
+ * `CELL_VIEW_COLUMNS` alone, never the payload. Backs the strict
183
+ * relation-read filter (`auth/cell_relation_visibility.ts`'s
184
+ * `filter_visible_target_ids`), which runs `can_view_cell` per row in memory
185
+ * rather than in SQL. Soft-deleted rows and ids with no row are absent.
186
+ *
187
+ * @param deps - query deps
188
+ * @param ids - cell ids to load (duplicates are harmless)
189
+ * @returns active rows in arbitrary order (caller indexes by `id`)
190
+ */
191
+ export declare const query_cell_view_load_many: (deps: QueryDeps, ids: ReadonlyArray<Uuid>) => Promise<Array<CellViewRow>>;
172
192
  /**
173
193
  * Update a cell. Fields left `undefined` in the patch keep their existing
174
194
  * value; explicit `null` writes `NULL`. `refs` is re-derived from `data`
@@ -247,15 +267,24 @@ export declare const query_cell_list_by_creator: (deps: QueryDeps, actor_id: Uui
247
267
  * dimension — keep it simple) plus an optional viewer-aware visibility
248
268
  * predicate.
249
269
  *
250
- * The visibility predicate mirrors `can_view_cell` in SQL form:
270
+ * The visibility predicate mirrors `can_view_cell || can_steward_cell` in SQL
271
+ * form:
251
272
  *
252
273
  * ```
253
274
  * (viewer_is_admin
254
- * OR cell.visibility = 'public'
255
275
  * OR (viewer_actor_id IS NOT NULL AND created_by = viewer_actor_id)
256
- * OR (viewer_actor_id IS NOT NULL AND <grant admits caller>))
276
+ * OR (<moderation admits an audience> AND (
277
+ * cell.visibility = 'public'
278
+ * OR (viewer_actor_id IS NOT NULL AND <grant admits caller>)))
279
+ * OR (viewer_actor_id IS NOT NULL AND <pending or rejected contribution>
280
+ * AND <viewer owns its live governing root>))
257
281
  * ```
258
282
  *
283
+ * The moderation rules are `cell_moderation_admits_audience_sql` and
284
+ * `cell_moderation_is_stewardable_sql` (`db/cell_moderation.ts`). The last arm
285
+ * is the steward arm (`auth/cell_steward.ts`) — a root owner reads the
286
+ * moderation queue under their root; a global admin is already admitted.
287
+ *
259
288
  * The grants branch closes parity with `can_view_cell`: a SQL `EXISTS`
260
289
  * over `cell_grant`, parameterized by the caller's `actor_id` and the
261
290
  * parallel `(role[], scope_id[])` projection of `auth.role_grants`. The
@@ -277,7 +306,9 @@ export declare const query_cell_list_by_creator: (deps: QueryDeps, actor_id: Uui
277
306
  * owner-excluding, but the explicit `created_by IS DISTINCT FROM caller`
278
307
  * guards against any future deviation. The shared_with branch does NOT
279
308
  * bypass for admin: an admin asking "what's shared with me" wants their
280
- * own grant footprint, not every cell.
309
+ * own grant footprint, not every cell. A grant admits there only while the
310
+ * cell's moderation admits an audience, as in `can_view_cell`, and the steward
311
+ * arm doesn't apply — a grant footprint is not a moderation queue.
281
312
  *
282
313
  * Soft-deleted rows are excluded by default; opt-in via `include_deleted`.
283
314
  *
@@ -313,11 +344,10 @@ export interface CellListParams {
313
344
  * Filter by moderation lifecycle marker (`'pending'` drives the mod queue via
314
345
  * `idx_cell_moderation_pending`).
315
346
  *
316
- * Note: the visibility predicate still applies, so a `'pending'` (private)
317
- * queue surfaces only to viewers it admits — admin / owner / grant. A
318
- * non-admin container manager won't see pending children here until a
319
- * manager-scoped visibility branch is added, so for now the queue is an admin
320
- * surface (`cell_moderate` of a known id still works regardless).
347
+ * The visibility predicate still applies, so `{root_id, moderation:
348
+ * 'pending'}` is the queue for the callers who moderate it — a global admin,
349
+ * and the governing root's owner through the steward arm — while each author
350
+ * sees only their own entries.
321
351
  */
322
352
  moderation?: string;
323
353
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"cell_queries.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/db/cell_queries.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,0BAA0B,CAAC;AACrD,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,yBAAyB,CAAC;AAEpD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kCAAkC,CAAC;AAIjE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,6BAA6B,CAAC;AAC5D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAEnE;;;;;;;;;;;;GAYG;AACH,MAAM,WAAW,OAAO;IACvB,EAAE,EAAE,IAAI,CAAC;IACT,IAAI,EAAE,QAAQ,CAAC;IACf,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,UAAU,EAAE,cAAc,CAAC;IAC3B,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,IAAI,EAAE,KAAK,CAAC,QAAQ,CAAC,GAAG,IAAI,CAAC;IAC7B,SAAS,EAAE,IAAI,GAAG,IAAI,CAAC;IACvB,OAAO,EAAE,IAAI,GAAG,IAAI,CAAC;IACrB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,UAAU,EAAE,IAAI,GAAG,IAAI,CAAC;IACxB,UAAU,EAAE,IAAI,GAAG,IAAI,CAAC;IACxB,WAAW,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;;;;GASG;AACH,eAAO,MAAM,YAAY,2KAegD,CAAC;AAK1E;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,mBAAmB,GAAI,OAAO,MAAM,KAAG,MAC2F,CAAC;AAEhJ;;;;;;;;GAQG;AACH,MAAM,WAAW,oBAAoB;IACpC,IAAI,EAAE,IAAI,CAAC;IACX,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,UAAU,CAAC,EAAE,cAAc,CAAC;IAC5B,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,SAAS,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;IACxB,OAAO,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,UAAU,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;CACzB;AAED;;;;GAIG;AACH,MAAM,WAAW,eAAe;IAC/B,IAAI,CAAC,EAAE,IAAI,CAAC;IACZ,UAAU,CAAC,EAAE,cAAc,CAAC;IAC5B,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,UAAU,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;CACzB;AAED,yEAAyE;AACzE,MAAM,WAAW,eAAe;IAC/B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,eAAe,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,iBAAiB,GAC7B,MAAM,SAAS,EACf,OAAO,oBAAoB,KACzB,OAAO,CAAC,OAAO,CAoBjB,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,cAAc,GAC1B,MAAM,SAAS,EACf,IAAI,IAAI,EACR,UAAU;IAAE,eAAe,CAAC,EAAE,OAAO,CAAA;CAAE,KACrC,OAAO,CAAC,OAAO,GAAG,IAAI,CAUxB,CAAC;AAEF;;;;;;;;GAQG;AACH,eAAO,MAAM,sBAAsB,GAClC,MAAM,SAAS,EACf,MAAM,MAAM,KACV,OAAO,CAAC,OAAO,GAAG,IAAI,CAQxB,CAAC;AAEF;;;;;;;;;;GAUG;AACH,eAAO,MAAM,oBAAoB,GAChC,MAAM,SAAS,EACf,KAAK,aAAa,CAAC,IAAI,CAAC,KACtB,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAQxB,CAAC;AAEF;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,iBAAiB,GAC7B,MAAM,SAAS,EACf,IAAI,IAAI,EACR,OAAO,eAAe,KACpB,OAAO,CAAC,OAAO,GAAG,IAAI,CA4BxB,CAAC;AAEF;;;;;;;;;;GAUG;AACH,eAAO,MAAM,iBAAiB,GAC7B,MAAM,SAAS,EACf,IAAI,IAAI,EACR,UAAU;IAAE,UAAU,CAAC,EAAE,IAAI,GAAG,IAAI,CAAA;CAAE,KACpC,OAAO,CAAC,OAAO,CAWjB,CAAC;AAEF;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,yBAAyB,GACrC,MAAM,SAAS,EACf,IAAI,IAAI,EACR,YAAY,MAAM,EAClB,SAAS;IAAE,qBAAqB,EAAE,OAAO,CAAC;IAAC,UAAU,CAAC,EAAE,IAAI,GAAG,IAAI,CAAA;CAAE,KACnE,OAAO,CAAC,OAAO,GAAG,IAAI,CAYxB,CAAC;AAEF;;;;;;;;GAQG;AACH,eAAO,MAAM,uBAAuB,GACnC,MAAM,SAAS,EACf,MAAM,MAAM,EACZ,UAAU,IAAI,CAAC,eAAe,EAAE,OAAO,GAAG,QAAQ,CAAC,KACjD,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CASvB,CAAC;AAEH;;;;;;;;GAQG;AACH,eAAO,MAAM,0BAA0B,GACtC,MAAM,SAAS,EACf,UAAU,IAAI,EACd,UAAU,IAAI,CAAC,eAAe,EAAE,OAAO,GAAG,QAAQ,CAAC,KACjD,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAQvB,CAAC;AAEH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6CG;AACH,eAAO,MAAM,eAAe,GAC3B,MAAM,SAAS,EACf,QAAQ,cAAc,KACpB,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CA4DxB,CAAC;AAqGF,4EAA4E;AAC5E,MAAM,WAAW,cAAc;IAC9B,oDAAoD;IACpD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;;;OAKG;IACH,UAAU,CAAC,EAAE,cAAc,CAAC;IAC5B,4EAA4E;IAC5E,GAAG,CAAC,EAAE,QAAQ,CAAC;IACf,0EAA0E;IAC1E,UAAU,CAAC,EAAE,IAAI,CAAC;IAClB;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,iGAAiG;IACjG,OAAO,CAAC,EAAE,IAAI,CAAC;IACf;;;;;;;;;OASG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;;;;OAMG;IACH,GAAG,CAAC,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;IAClB;;;;OAIG;IACH,eAAe,EAAE,IAAI,GAAG,IAAI,CAAC;IAC7B;;;;OAIG;IACH,eAAe,EAAE,OAAO,CAAC;IACzB;;;;;;OAMG;IACH,eAAe,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;IAC9B;;;;;;;OAOG;IACH,uBAAuB,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IAChD;;;;OAIG;IACH,2BAA2B,CAAC,EAAE,aAAa,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC;IACzD;;;;;OAKG;IACH,uBAAuB,CAAC,EAAE,OAAO,CAAC;IAClC,yCAAyC;IACzC,QAAQ,CAAC,EAAE,YAAY,GAAG,YAAY,CAAC;IACvC,sCAAsC;IACtC,eAAe,CAAC,EAAE,KAAK,GAAG,MAAM,CAAC;IACjC,iBAAiB;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,mBAAmB;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,kDAAkD;IAClD,eAAe,CAAC,EAAE,OAAO,CAAC;CAC1B"}
1
+ {"version":3,"file":"cell_queries.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/db/cell_queries.ts"],"names":[],"mappings":"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"}