@fuzdev/fuz_app 0.54.0 → 0.56.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 (348) hide show
  1. package/dist/actions/CLAUDE.md +214 -103
  2. package/dist/actions/action_bridge.d.ts +8 -5
  3. package/dist/actions/action_bridge.d.ts.map +1 -1
  4. package/dist/actions/action_bridge.js +1 -11
  5. package/dist/actions/action_codegen.d.ts +32 -0
  6. package/dist/actions/action_codegen.d.ts.map +1 -1
  7. package/dist/actions/action_codegen.js +35 -15
  8. package/dist/actions/action_registry.d.ts.map +1 -1
  9. package/dist/actions/action_registry.js +5 -2
  10. package/dist/actions/action_rpc.d.ts +141 -22
  11. package/dist/actions/action_rpc.d.ts.map +1 -1
  12. package/dist/actions/action_rpc.js +106 -187
  13. package/dist/actions/action_spec.d.ts +55 -16
  14. package/dist/actions/action_spec.d.ts.map +1 -1
  15. package/dist/actions/action_spec.js +16 -11
  16. package/dist/actions/action_types.d.ts +28 -60
  17. package/dist/actions/action_types.d.ts.map +1 -1
  18. package/dist/actions/action_types.js +13 -5
  19. package/dist/actions/broadcast_api.d.ts +2 -2
  20. package/dist/actions/broadcast_api.js +2 -2
  21. package/dist/actions/compile_action_registry.d.ts +50 -0
  22. package/dist/actions/compile_action_registry.d.ts.map +1 -0
  23. package/dist/actions/compile_action_registry.js +69 -0
  24. package/dist/actions/heartbeat.d.ts +8 -4
  25. package/dist/actions/heartbeat.d.ts.map +1 -1
  26. package/dist/actions/heartbeat.js +5 -4
  27. package/dist/actions/perform_action.d.ts +145 -0
  28. package/dist/actions/perform_action.d.ts.map +1 -0
  29. package/dist/actions/perform_action.js +258 -0
  30. package/dist/actions/register_action_ws.d.ts +46 -40
  31. package/dist/actions/register_action_ws.d.ts.map +1 -1
  32. package/dist/actions/register_action_ws.js +101 -159
  33. package/dist/actions/register_ws_endpoint.d.ts +15 -10
  34. package/dist/actions/register_ws_endpoint.d.ts.map +1 -1
  35. package/dist/actions/register_ws_endpoint.js +54 -7
  36. package/dist/actions/transports.d.ts.map +1 -1
  37. package/dist/actions/transports.js +0 -4
  38. package/dist/actions/transports_ws_auth_guard.d.ts +1 -1
  39. package/dist/actions/transports_ws_auth_guard.js +1 -1
  40. package/dist/actions/transports_ws_backend.d.ts +1 -1
  41. package/dist/actions/transports_ws_backend.js +1 -1
  42. package/dist/auth/CLAUDE.md +794 -410
  43. package/dist/auth/account_action_specs.d.ts +28 -7
  44. package/dist/auth/account_action_specs.d.ts.map +1 -1
  45. package/dist/auth/account_action_specs.js +7 -7
  46. package/dist/auth/account_actions.d.ts +7 -13
  47. package/dist/auth/account_actions.d.ts.map +1 -1
  48. package/dist/auth/account_actions.js +26 -35
  49. package/dist/auth/account_queries.d.ts +52 -16
  50. package/dist/auth/account_queries.d.ts.map +1 -1
  51. package/dist/auth/account_queries.js +87 -38
  52. package/dist/auth/account_routes.d.ts +9 -11
  53. package/dist/auth/account_routes.d.ts.map +1 -1
  54. package/dist/auth/account_routes.js +118 -46
  55. package/dist/auth/account_schema.d.ts +46 -35
  56. package/dist/auth/account_schema.d.ts.map +1 -1
  57. package/dist/auth/account_schema.js +21 -28
  58. package/dist/auth/admin_action_specs.d.ts +100 -32
  59. package/dist/auth/admin_action_specs.d.ts.map +1 -1
  60. package/dist/auth/admin_action_specs.js +64 -33
  61. package/dist/auth/admin_actions.d.ts +13 -19
  62. package/dist/auth/admin_actions.d.ts.map +1 -1
  63. package/dist/auth/admin_actions.js +37 -41
  64. package/dist/auth/audit_emitter.d.ts +160 -0
  65. package/dist/auth/audit_emitter.d.ts.map +1 -0
  66. package/dist/auth/audit_emitter.js +83 -0
  67. package/dist/auth/audit_log_queries.d.ts +17 -48
  68. package/dist/auth/audit_log_queries.d.ts.map +1 -1
  69. package/dist/auth/audit_log_queries.js +20 -56
  70. package/dist/auth/audit_log_routes.d.ts +1 -1
  71. package/dist/auth/audit_log_routes.d.ts.map +1 -1
  72. package/dist/auth/audit_log_routes.js +7 -3
  73. package/dist/auth/audit_log_schema.d.ts +92 -32
  74. package/dist/auth/audit_log_schema.d.ts.map +1 -1
  75. package/dist/auth/audit_log_schema.js +75 -46
  76. package/dist/auth/auth_guard_resolver.d.ts +44 -0
  77. package/dist/auth/auth_guard_resolver.d.ts.map +1 -0
  78. package/dist/auth/auth_guard_resolver.js +56 -0
  79. package/dist/auth/bearer_auth.d.ts +9 -7
  80. package/dist/auth/bearer_auth.d.ts.map +1 -1
  81. package/dist/auth/bearer_auth.js +13 -21
  82. package/dist/auth/bootstrap_account.d.ts +7 -7
  83. package/dist/auth/bootstrap_account.d.ts.map +1 -1
  84. package/dist/auth/bootstrap_account.js +7 -7
  85. package/dist/auth/bootstrap_routes.d.ts.map +1 -1
  86. package/dist/auth/bootstrap_routes.js +11 -10
  87. package/dist/auth/cleanup.d.ts +20 -26
  88. package/dist/auth/cleanup.d.ts.map +1 -1
  89. package/dist/auth/cleanup.js +33 -42
  90. package/dist/auth/credential_type_schema.d.ts +115 -0
  91. package/dist/auth/credential_type_schema.d.ts.map +1 -0
  92. package/dist/auth/credential_type_schema.js +127 -0
  93. package/dist/auth/daemon_token_middleware.d.ts +23 -11
  94. package/dist/auth/daemon_token_middleware.d.ts.map +1 -1
  95. package/dist/auth/daemon_token_middleware.js +28 -22
  96. package/dist/auth/ddl.d.ts +2 -2
  97. package/dist/auth/ddl.d.ts.map +1 -1
  98. package/dist/auth/ddl.js +6 -6
  99. package/dist/auth/deps.d.ts +7 -18
  100. package/dist/auth/deps.d.ts.map +1 -1
  101. package/dist/auth/grant_path_schema.d.ts +117 -0
  102. package/dist/auth/grant_path_schema.d.ts.map +1 -0
  103. package/dist/auth/grant_path_schema.js +137 -0
  104. package/dist/auth/invite_queries.d.ts +12 -1
  105. package/dist/auth/invite_queries.d.ts.map +1 -1
  106. package/dist/auth/invite_queries.js +12 -1
  107. package/dist/auth/invite_schema.d.ts +1 -1
  108. package/dist/auth/invite_schema.d.ts.map +1 -1
  109. package/dist/auth/invite_schema.js +1 -1
  110. package/dist/auth/middleware.d.ts.map +1 -1
  111. package/dist/auth/middleware.js +9 -4
  112. package/dist/auth/migrations.d.ts +37 -14
  113. package/dist/auth/migrations.d.ts.map +1 -1
  114. package/dist/auth/migrations.js +79 -32
  115. package/dist/auth/request_context.d.ts +331 -61
  116. package/dist/auth/request_context.d.ts.map +1 -1
  117. package/dist/auth/request_context.js +378 -95
  118. package/dist/auth/{permit_offer_action_specs.d.ts → role_grant_offer_action_specs.d.ts} +163 -94
  119. package/dist/auth/role_grant_offer_action_specs.d.ts.map +1 -0
  120. package/dist/auth/role_grant_offer_action_specs.js +262 -0
  121. package/dist/auth/role_grant_offer_actions.d.ts +104 -0
  122. package/dist/auth/role_grant_offer_actions.d.ts.map +1 -0
  123. package/dist/auth/role_grant_offer_actions.js +473 -0
  124. package/dist/auth/{permit_offer_notifications.d.ts → role_grant_offer_notifications.d.ts} +90 -70
  125. package/dist/auth/role_grant_offer_notifications.d.ts.map +1 -0
  126. package/dist/auth/role_grant_offer_notifications.js +182 -0
  127. package/dist/auth/role_grant_offer_queries.d.ts +242 -0
  128. package/dist/auth/role_grant_offer_queries.d.ts.map +1 -0
  129. package/dist/auth/role_grant_offer_queries.js +533 -0
  130. package/dist/auth/role_grant_offer_schema.d.ts +150 -0
  131. package/dist/auth/role_grant_offer_schema.d.ts.map +1 -0
  132. package/dist/auth/{permit_offer_schema.js → role_grant_offer_schema.js} +60 -36
  133. package/dist/auth/role_grant_queries.d.ts +231 -0
  134. package/dist/auth/role_grant_queries.d.ts.map +1 -0
  135. package/dist/auth/role_grant_queries.js +320 -0
  136. package/dist/auth/role_schema.d.ts +150 -40
  137. package/dist/auth/role_schema.d.ts.map +1 -1
  138. package/dist/auth/role_schema.js +144 -45
  139. package/dist/auth/scope_kind_schema.d.ts +96 -0
  140. package/dist/auth/scope_kind_schema.d.ts.map +1 -0
  141. package/dist/auth/scope_kind_schema.js +94 -0
  142. package/dist/auth/self_service_role_action_specs.d.ts +6 -1
  143. package/dist/auth/self_service_role_action_specs.d.ts.map +1 -1
  144. package/dist/auth/self_service_role_action_specs.js +3 -1
  145. package/dist/auth/self_service_role_actions.d.ts +34 -27
  146. package/dist/auth/self_service_role_actions.d.ts.map +1 -1
  147. package/dist/auth/self_service_role_actions.js +68 -48
  148. package/dist/auth/session_cookie.d.ts +43 -6
  149. package/dist/auth/session_cookie.d.ts.map +1 -1
  150. package/dist/auth/session_cookie.js +31 -5
  151. package/dist/auth/session_middleware.d.ts +37 -3
  152. package/dist/auth/session_middleware.d.ts.map +1 -1
  153. package/dist/auth/session_middleware.js +33 -7
  154. package/dist/auth/signup_routes.d.ts.map +1 -1
  155. package/dist/auth/signup_routes.js +48 -19
  156. package/dist/auth/standard_action_specs.d.ts +2 -2
  157. package/dist/auth/standard_action_specs.js +4 -4
  158. package/dist/auth/standard_rpc_actions.d.ts +23 -19
  159. package/dist/auth/standard_rpc_actions.d.ts.map +1 -1
  160. package/dist/auth/standard_rpc_actions.js +12 -12
  161. package/dist/db/migrate.d.ts +12 -8
  162. package/dist/db/migrate.d.ts.map +1 -1
  163. package/dist/db/migrate.js +10 -7
  164. package/dist/dev/setup.d.ts +2 -2
  165. package/dist/dev/setup.d.ts.map +1 -1
  166. package/dist/dev/setup.js +9 -7
  167. package/dist/env/load.d.ts +1 -1
  168. package/dist/env/load.js +1 -1
  169. package/dist/hono_context.d.ts +64 -5
  170. package/dist/hono_context.d.ts.map +1 -1
  171. package/dist/hono_context.js +38 -2
  172. package/dist/http/CLAUDE.md +264 -87
  173. package/dist/http/auth_shape.d.ts +191 -0
  174. package/dist/http/auth_shape.d.ts.map +1 -0
  175. package/dist/http/auth_shape.js +237 -0
  176. package/dist/http/common_routes.js +3 -3
  177. package/dist/http/db_routes.d.ts +4 -0
  178. package/dist/http/db_routes.d.ts.map +1 -1
  179. package/dist/http/db_routes.js +44 -7
  180. package/dist/http/error_schemas.d.ts +132 -19
  181. package/dist/http/error_schemas.d.ts.map +1 -1
  182. package/dist/http/error_schemas.js +132 -40
  183. package/dist/http/jsonrpc_errors.d.ts +27 -2
  184. package/dist/http/jsonrpc_errors.d.ts.map +1 -1
  185. package/dist/http/jsonrpc_errors.js +26 -2
  186. package/dist/http/pending_effects.d.ts +71 -18
  187. package/dist/http/pending_effects.d.ts.map +1 -1
  188. package/dist/http/pending_effects.js +87 -18
  189. package/dist/http/proxy.d.ts +52 -5
  190. package/dist/http/proxy.d.ts.map +1 -1
  191. package/dist/http/proxy.js +92 -14
  192. package/dist/http/route_spec.d.ts +113 -41
  193. package/dist/http/route_spec.d.ts.map +1 -1
  194. package/dist/http/route_spec.js +130 -52
  195. package/dist/http/schema_helpers.d.ts +3 -2
  196. package/dist/http/schema_helpers.d.ts.map +1 -1
  197. package/dist/http/schema_helpers.js +9 -2
  198. package/dist/http/surface.d.ts +2 -1
  199. package/dist/http/surface.d.ts.map +1 -1
  200. package/dist/http/surface.js +1 -2
  201. package/dist/http/surface_query.d.ts +39 -35
  202. package/dist/http/surface_query.d.ts.map +1 -1
  203. package/dist/http/surface_query.js +79 -36
  204. package/dist/primitive_schemas.d.ts +39 -0
  205. package/dist/primitive_schemas.d.ts.map +1 -0
  206. package/dist/primitive_schemas.js +40 -0
  207. package/dist/realtime/sse_auth_guard.d.ts +5 -5
  208. package/dist/realtime/sse_auth_guard.js +9 -9
  209. package/dist/runtime/mock.d.ts +1 -1
  210. package/dist/runtime/mock.js +1 -1
  211. package/dist/server/app_backend.d.ts +14 -11
  212. package/dist/server/app_backend.d.ts.map +1 -1
  213. package/dist/server/app_backend.js +12 -8
  214. package/dist/server/app_server.d.ts +7 -7
  215. package/dist/server/app_server.d.ts.map +1 -1
  216. package/dist/server/app_server.js +36 -31
  217. package/dist/server/validate_nginx.d.ts +1 -1
  218. package/dist/server/validate_nginx.js +1 -1
  219. package/dist/testing/CLAUDE.md +73 -55
  220. package/dist/testing/admin_integration.d.ts +5 -6
  221. package/dist/testing/admin_integration.d.ts.map +1 -1
  222. package/dist/testing/admin_integration.js +100 -96
  223. package/dist/testing/adversarial_headers.js +1 -1
  224. package/dist/testing/app_server.d.ts +11 -14
  225. package/dist/testing/app_server.d.ts.map +1 -1
  226. package/dist/testing/app_server.js +18 -17
  227. package/dist/testing/assertions.d.ts.map +1 -1
  228. package/dist/testing/assertions.js +2 -1
  229. package/dist/testing/attack_surface.d.ts.map +1 -1
  230. package/dist/testing/attack_surface.js +15 -9
  231. package/dist/testing/audit_completeness.d.ts +2 -2
  232. package/dist/testing/audit_completeness.d.ts.map +1 -1
  233. package/dist/testing/audit_completeness.js +53 -39
  234. package/dist/testing/auth_apps.d.ts +5 -4
  235. package/dist/testing/auth_apps.d.ts.map +1 -1
  236. package/dist/testing/auth_apps.js +28 -22
  237. package/dist/testing/data_exposure.d.ts.map +1 -1
  238. package/dist/testing/data_exposure.js +5 -5
  239. package/dist/testing/db.d.ts +1 -1
  240. package/dist/testing/db.d.ts.map +1 -1
  241. package/dist/testing/db.js +4 -4
  242. package/dist/testing/db_entities.d.ts +22 -0
  243. package/dist/testing/db_entities.d.ts.map +1 -0
  244. package/dist/testing/db_entities.js +28 -0
  245. package/dist/testing/entities.d.ts +10 -8
  246. package/dist/testing/entities.d.ts.map +1 -1
  247. package/dist/testing/entities.js +22 -18
  248. package/dist/testing/integration.d.ts.map +1 -1
  249. package/dist/testing/integration.js +13 -14
  250. package/dist/testing/integration_helpers.d.ts +8 -6
  251. package/dist/testing/integration_helpers.d.ts.map +1 -1
  252. package/dist/testing/integration_helpers.js +29 -23
  253. package/dist/testing/middleware.d.ts +15 -11
  254. package/dist/testing/middleware.d.ts.map +1 -1
  255. package/dist/testing/middleware.js +75 -32
  256. package/dist/testing/rpc_attack_surface.d.ts.map +1 -1
  257. package/dist/testing/rpc_attack_surface.js +40 -24
  258. package/dist/testing/rpc_helpers.d.ts.map +1 -1
  259. package/dist/testing/rpc_helpers.js +3 -1
  260. package/dist/testing/rpc_round_trip.d.ts +1 -1
  261. package/dist/testing/rpc_round_trip.d.ts.map +1 -1
  262. package/dist/testing/rpc_round_trip.js +14 -13
  263. package/dist/testing/sse_round_trip.d.ts +3 -4
  264. package/dist/testing/sse_round_trip.d.ts.map +1 -1
  265. package/dist/testing/sse_round_trip.js +7 -11
  266. package/dist/testing/standard.d.ts +1 -1
  267. package/dist/testing/stubs.d.ts +25 -0
  268. package/dist/testing/stubs.d.ts.map +1 -1
  269. package/dist/testing/stubs.js +43 -2
  270. package/dist/testing/surface_invariants.d.ts +2 -2
  271. package/dist/testing/ws_round_trip.d.ts +12 -13
  272. package/dist/testing/ws_round_trip.d.ts.map +1 -1
  273. package/dist/testing/ws_round_trip.js +24 -12
  274. package/dist/ui/AdminAccounts.svelte +23 -20
  275. package/dist/ui/AdminOverview.svelte +15 -13
  276. package/dist/ui/AdminOverview.svelte.d.ts.map +1 -1
  277. package/dist/ui/{AdminPermitHistory.svelte → AdminRoleGrantHistory.svelte} +12 -12
  278. package/dist/ui/AdminRoleGrantHistory.svelte.d.ts +4 -0
  279. package/dist/ui/AdminRoleGrantHistory.svelte.d.ts.map +1 -0
  280. package/dist/ui/BootstrapForm.svelte +1 -1
  281. package/dist/ui/CLAUDE.md +65 -59
  282. package/dist/ui/{PermitOfferForm.svelte → RoleGrantOfferForm.svelte} +37 -22
  283. package/dist/ui/RoleGrantOfferForm.svelte.d.ts +20 -0
  284. package/dist/ui/RoleGrantOfferForm.svelte.d.ts.map +1 -0
  285. package/dist/ui/{PermitOfferHistory.svelte → RoleGrantOfferHistory.svelte} +12 -12
  286. package/dist/ui/{PermitOfferHistory.svelte.d.ts → RoleGrantOfferHistory.svelte.d.ts} +4 -4
  287. package/dist/ui/RoleGrantOfferHistory.svelte.d.ts.map +1 -0
  288. package/dist/ui/{PermitOfferInbox.svelte → RoleGrantOfferInbox.svelte} +14 -14
  289. package/dist/ui/{PermitOfferInbox.svelte.d.ts → RoleGrantOfferInbox.svelte.d.ts} +4 -4
  290. package/dist/ui/RoleGrantOfferInbox.svelte.d.ts.map +1 -0
  291. package/dist/ui/SignupForm.svelte +1 -1
  292. package/dist/ui/SurfaceExplorer.svelte +35 -15
  293. package/dist/ui/SurfaceExplorer.svelte.d.ts.map +1 -1
  294. package/dist/ui/account_sessions_state.svelte.d.ts +2 -3
  295. package/dist/ui/account_sessions_state.svelte.d.ts.map +1 -1
  296. package/dist/ui/account_sessions_state.svelte.js +2 -3
  297. package/dist/ui/admin_accounts_state.svelte.d.ts +25 -18
  298. package/dist/ui/admin_accounts_state.svelte.d.ts.map +1 -1
  299. package/dist/ui/admin_accounts_state.svelte.js +28 -17
  300. package/dist/ui/admin_rpc_adapters.d.ts +20 -20
  301. package/dist/ui/admin_rpc_adapters.d.ts.map +1 -1
  302. package/dist/ui/admin_rpc_adapters.js +17 -17
  303. package/dist/ui/admin_sessions_state.svelte.d.ts +2 -2
  304. package/dist/ui/admin_sessions_state.svelte.js +2 -2
  305. package/dist/ui/audit_log_state.svelte.d.ts +7 -7
  306. package/dist/ui/audit_log_state.svelte.d.ts.map +1 -1
  307. package/dist/ui/audit_log_state.svelte.js +6 -6
  308. package/dist/ui/auth_state.svelte.d.ts +3 -3
  309. package/dist/ui/auth_state.svelte.d.ts.map +1 -1
  310. package/dist/ui/auth_state.svelte.js +6 -6
  311. package/dist/ui/format_scope.d.ts +2 -2
  312. package/dist/ui/format_scope.js +2 -2
  313. package/dist/ui/{permit_offers_state.svelte.d.ts → role_grant_offers_state.svelte.d.ts} +39 -31
  314. package/dist/ui/role_grant_offers_state.svelte.d.ts.map +1 -0
  315. package/dist/ui/{permit_offers_state.svelte.js → role_grant_offers_state.svelte.js} +25 -19
  316. package/dist/ui/ui_format.js +2 -2
  317. package/package.json +3 -3
  318. package/dist/auth/permit_offer_action_specs.d.ts.map +0 -1
  319. package/dist/auth/permit_offer_action_specs.js +0 -227
  320. package/dist/auth/permit_offer_actions.d.ts +0 -110
  321. package/dist/auth/permit_offer_actions.d.ts.map +0 -1
  322. package/dist/auth/permit_offer_actions.js +0 -452
  323. package/dist/auth/permit_offer_notifications.d.ts.map +0 -1
  324. package/dist/auth/permit_offer_notifications.js +0 -182
  325. package/dist/auth/permit_offer_queries.d.ts +0 -183
  326. package/dist/auth/permit_offer_queries.d.ts.map +0 -1
  327. package/dist/auth/permit_offer_queries.js +0 -408
  328. package/dist/auth/permit_offer_schema.d.ts +0 -103
  329. package/dist/auth/permit_offer_schema.d.ts.map +0 -1
  330. package/dist/auth/permit_queries.d.ts +0 -210
  331. package/dist/auth/permit_queries.d.ts.map +0 -1
  332. package/dist/auth/permit_queries.js +0 -294
  333. package/dist/auth/require_keeper.d.ts +0 -20
  334. package/dist/auth/require_keeper.d.ts.map +0 -1
  335. package/dist/auth/require_keeper.js +0 -35
  336. package/dist/auth/route_guards.d.ts +0 -21
  337. package/dist/auth/route_guards.d.ts.map +0 -1
  338. package/dist/auth/route_guards.js +0 -32
  339. package/dist/auth/session_lifecycle.d.ts +0 -37
  340. package/dist/auth/session_lifecycle.d.ts.map +0 -1
  341. package/dist/auth/session_lifecycle.js +0 -29
  342. package/dist/ui/AdminPermitHistory.svelte.d.ts +0 -4
  343. package/dist/ui/AdminPermitHistory.svelte.d.ts.map +0 -1
  344. package/dist/ui/PermitOfferForm.svelte.d.ts +0 -14
  345. package/dist/ui/PermitOfferForm.svelte.d.ts.map +0 -1
  346. package/dist/ui/PermitOfferHistory.svelte.d.ts.map +0 -1
  347. package/dist/ui/PermitOfferInbox.svelte.d.ts.map +0 -1
  348. package/dist/ui/permit_offers_state.svelte.d.ts.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"role_grant_offer_schema.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/auth/role_grant_offer_schema.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAC,CAAC,EAAC,MAAM,KAAK,CAAC;AACtB,OAAO,EAAC,IAAI,EAAC,MAAM,wBAAwB,CAAC;AAI5C,mHAAmH;AACnH,eAAO,MAAM,oCAAoC,yCAAyC,CAAC;AAE3F,mEAAmE;AACnE,eAAO,MAAM,mCAAmC,MAAM,CAAC;AAEvD,yFAAyF;AACzF,eAAO,MAAM,+BAA+B,QAA2B,CAAC;AAExE,eAAO,MAAM,uBAAuB,qzCAkClC,CAAC;AAEH;;;;;GAKG;AACH,eAAO,MAAM,wCAAwC,WAAW,CAAC;AAEjE;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,qCAAqC,2XAYpB,CAAC;AAE/B,+EAA+E;AAC/E,eAAO,MAAM,4BAA4B,kOAMX,CAAC;AAQ/B,wDAAwD;AACxD,MAAM,WAAW,cAAc;IAC9B,EAAE,EAAE,IAAI,CAAC;IACT,aAAa,EAAE,IAAI,CAAC;IACpB,aAAa,EAAE,IAAI,CAAC;IACpB;;;;;;;;;;;OAWG;IACH,WAAW,EAAE,IAAI,GAAG,IAAI,CAAC;IACzB,IAAI,EAAE,MAAM,CAAC;IACb;;;;;;OAMG;IACH,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,QAAQ,EAAE,IAAI,GAAG,IAAI,CAAC;IACtB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B;;;;;OAKG;IACH,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,uBAAuB,EAAE,IAAI,GAAG,IAAI,CAAC;CACrC;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,eAAgB,SAAQ,cAAc;IACtD,eAAe,EAAE,IAAI,CAAC;CACtB;AAED;;;;;GAKG;AACH,MAAM,WAAW,yBAAyB;IACzC,aAAa,EAAE,IAAI,CAAC;IACpB,aAAa,EAAE,IAAI,CAAC;IACpB;;;;;;OAMG;IACH,WAAW,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,QAAQ,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;IACvB,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,UAAU,EAAE,IAAI,CAAC;CACjB;AAED,wDAAwD;AACxD,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;kBAoD0D,CAAC;AAC1F,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAEpE,gEAAgE;AAChE,eAAO,MAAM,wBAAwB,GAAI,OAAO,cAAc,KAAG,kBAiB/D,CAAC"}
@@ -1,10 +1,10 @@
1
1
  /**
2
- * Permit offer DDL, types, and client-safe schemas.
2
+ * Role grant offer DDL, types, and client-safe schemas.
3
3
  *
4
4
  * An offer is a pending grant awaiting recipient consent. Lifecycle states
5
- * are mutually exclusive via a CHECK constraint (`permit_offer_single_terminal`):
5
+ * are mutually exclusive via a CHECK constraint (`role_grant_offer_single_terminal`):
6
6
  * at most one of `accepted_at` / `declined_at` / `retracted_at` may be set.
7
- * On accept, the offer's `resulting_permit_id` links to the permit row
7
+ * On accept, the offer's `resulting_role_grant_id` links to the role_grant row
8
8
  * produced by `query_accept_offer`.
9
9
  *
10
10
  * @module
@@ -13,17 +13,19 @@ import { z } from 'zod';
13
13
  import { Uuid } from '@fuzdev/fuz_util/id.js';
14
14
  import { RoleName } from './role_schema.js';
15
15
  /** Sentinel UUID used inside the partial unique indexes to collapse `scope_id IS NULL` into a comparable value. */
16
- export const PERMIT_OFFER_SCOPE_SENTINEL_UUID = '00000000-0000-0000-0000-000000000000';
16
+ export const ROLE_GRANT_OFFER_SCOPE_SENTINEL_UUID = '00000000-0000-0000-0000-000000000000';
17
17
  /** Maximum length of the optional message attached to an offer. */
18
- export const PERMIT_OFFER_MESSAGE_LENGTH_MAX = 500;
18
+ export const ROLE_GRANT_OFFER_MESSAGE_LENGTH_MAX = 500;
19
19
  /** Default TTL for a newly created offer — 30 days. Matches GitHub org-invite expiry. */
20
- export const PERMIT_OFFER_DEFAULT_TTL_MS = 30 * 24 * 60 * 60 * 1000;
21
- export const PERMIT_OFFER_SCHEMA = `
22
- CREATE TABLE IF NOT EXISTS permit_offer (
20
+ export const ROLE_GRANT_OFFER_DEFAULT_TTL_MS = 30 * 24 * 60 * 60 * 1000;
21
+ export const ROLE_GRANT_OFFER_SCHEMA = `
22
+ CREATE TABLE IF NOT EXISTS role_grant_offer (
23
23
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
24
24
  from_actor_id UUID NOT NULL REFERENCES actor(id) ON DELETE CASCADE,
25
25
  to_account_id UUID NOT NULL REFERENCES account(id) ON DELETE CASCADE,
26
+ to_actor_id UUID NULL REFERENCES actor(id) ON DELETE CASCADE,
26
27
  role TEXT NOT NULL,
28
+ scope_kind TEXT NULL,
27
29
  scope_id UUID NULL,
28
30
  message TEXT NULL,
29
31
  created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
@@ -33,38 +35,52 @@ CREATE TABLE IF NOT EXISTS permit_offer (
33
35
  decline_reason TEXT NULL,
34
36
  retracted_at TIMESTAMPTZ NULL,
35
37
  superseded_at TIMESTAMPTZ NULL,
36
- resulting_permit_id UUID NULL REFERENCES permit(id) ON DELETE SET NULL,
37
- CONSTRAINT permit_offer_single_terminal CHECK (
38
+ resulting_role_grant_id UUID NULL REFERENCES role_grant(id) ON DELETE SET NULL,
39
+ CONSTRAINT role_grant_offer_single_terminal CHECK (
38
40
  (accepted_at IS NOT NULL)::int
39
41
  + (declined_at IS NOT NULL)::int
40
42
  + (retracted_at IS NOT NULL)::int
41
43
  + (superseded_at IS NOT NULL)::int
42
44
  <= 1
43
45
  ),
44
- CONSTRAINT permit_offer_permit_iff_accepted CHECK (
45
- (accepted_at IS NOT NULL) = (resulting_permit_id IS NOT NULL)
46
+ CONSTRAINT role_grant_offer_role_grant_iff_accepted CHECK (
47
+ (accepted_at IS NOT NULL) = (resulting_role_grant_id IS NOT NULL)
46
48
  ),
47
- CONSTRAINT permit_offer_reason_iff_declined CHECK (
49
+ CONSTRAINT role_grant_offer_reason_iff_declined CHECK (
48
50
  decline_reason IS NULL OR declined_at IS NOT NULL
51
+ ),
52
+ CONSTRAINT role_grant_offer_scope_kind_paired CHECK (
53
+ (scope_kind IS NULL) = (scope_id IS NULL)
49
54
  )
50
55
  )`;
51
56
  /**
52
- * At most one pending offer per (to_account, role, scope, from_actor).
57
+ * Index-side token for the global case in the partial unique index. Uppercase
58
+ * so it cannot collide with consumer-declared `ScopeKindName` values (which
59
+ * are lowercase by regex). Never appears as a column value — column-level
60
+ * `scope_kind = NULL` and `scope_id = NULL` together encode the global case.
61
+ */
62
+ export const ROLE_GRANT_OFFER_SCOPE_KIND_GLOBAL_TOKEN = 'GLOBAL';
63
+ /**
64
+ * At most one pending offer per (to_account, role, scope_kind, scope, from_actor).
53
65
  *
54
66
  * Including `from_actor_id` in the tuple lets multiple grantors coexist —
55
67
  * teacher A and teacher B can each have a pending `classroom_student` offer
56
68
  * for the same student and scope. A same-grantor re-offer upserts the
57
69
  * existing pending row. `COALESCE` collapses `NULL` scopes into the
58
- * sentinel UUID so Postgres's NULL-in-unique-index quirk does not allow
59
- * duplicate global pending offers. The ON CONFLICT target in
60
- * `query_permit_offer_create` must match this expression literally.
70
+ * sentinel values so Postgres's NULL-in-unique-index quirk does not allow
71
+ * duplicate global pending offers; the `scope_kind` / `scope_id` pair is
72
+ * always either both null (global) or both non-null (scoped) per the
73
+ * `role_grant_offer_scope_kind_paired` CHECK, so the two COALESCE expressions
74
+ * always agree. The ON CONFLICT target in `query_role_grant_offer_create` must
75
+ * match this expression literally.
61
76
  */
62
- export const PERMIT_OFFER_PENDING_UNIQUE_INDEX = `
63
- CREATE UNIQUE INDEX IF NOT EXISTS permit_offer_pending_unique
64
- ON permit_offer (
77
+ export const ROLE_GRANT_OFFER_PENDING_UNIQUE_INDEX = `
78
+ CREATE UNIQUE INDEX IF NOT EXISTS role_grant_offer_pending_unique
79
+ ON role_grant_offer (
65
80
  to_account_id,
66
81
  role,
67
- COALESCE(scope_id, '${PERMIT_OFFER_SCOPE_SENTINEL_UUID}'::uuid),
82
+ COALESCE(scope_kind, '${ROLE_GRANT_OFFER_SCOPE_KIND_GLOBAL_TOKEN}'),
83
+ COALESCE(scope_id, '${ROLE_GRANT_OFFER_SCOPE_SENTINEL_UUID}'::uuid),
68
84
  from_actor_id
69
85
  )
70
86
  WHERE accepted_at IS NULL
@@ -72,26 +88,32 @@ CREATE UNIQUE INDEX IF NOT EXISTS permit_offer_pending_unique
72
88
  AND retracted_at IS NULL
73
89
  AND superseded_at IS NULL`;
74
90
  /** Inbox lookup — pending offers for an account, ordered by soonest expiry. */
75
- export const PERMIT_OFFER_INBOX_INDEX = `
76
- CREATE INDEX IF NOT EXISTS permit_offer_inbox
77
- ON permit_offer (to_account_id, expires_at)
91
+ export const ROLE_GRANT_OFFER_INBOX_INDEX = `
92
+ CREATE INDEX IF NOT EXISTS role_grant_offer_inbox
93
+ ON role_grant_offer (to_account_id, expires_at)
78
94
  WHERE accepted_at IS NULL
79
95
  AND declined_at IS NULL
80
96
  AND retracted_at IS NULL
81
97
  AND superseded_at IS NULL`;
82
- /** Zod schema for client-safe permit offer data. */
83
- export const PermitOfferJson = z
98
+ /** Zod schema for client-safe role_grant offer data. */
99
+ export const RoleGrantOfferJson = z
84
100
  .strictObject({
85
101
  id: Uuid.meta({ description: 'Offer id.' }),
86
102
  from_actor_id: Uuid.meta({ description: 'Actor that issued the offer.' }),
87
103
  to_account_id: Uuid.meta({ description: 'Account the offer is directed to.' }),
104
+ to_actor_id: Uuid.nullable().meta({
105
+ description: 'Optional actor-grain target on the recipient account. When set, only this actor may accept; when null any actor on `to_account_id` may accept.',
106
+ }),
88
107
  role: RoleName.meta({ description: 'Role being offered.' }),
108
+ scope_kind: z.string().nullable().meta({
109
+ description: 'Machine-readable kind tag for `scope_id` — paired-null with `scope_id` (both null for global, both non-null for scoped).',
110
+ }),
89
111
  scope_id: Uuid.nullable().meta({
90
- description: 'Scope the offered permit applies to (e.g. a classroom id). `null` for global permits.',
112
+ description: 'Scope the offered role_grant applies to (e.g. a classroom id). `null` for global role_grants.',
91
113
  }),
92
114
  message: z
93
115
  .string()
94
- .max(PERMIT_OFFER_MESSAGE_LENGTH_MAX)
116
+ .max(ROLE_GRANT_OFFER_MESSAGE_LENGTH_MAX)
95
117
  .nullable()
96
118
  .meta({ description: 'Optional free-form note from the grantor.' }),
97
119
  created_at: z.string().meta({ description: 'ISO timestamp when the offer was created.' }),
@@ -108,7 +130,7 @@ export const PermitOfferJson = z
108
130
  .meta({ description: 'ISO timestamp when the offer was declined.' }),
109
131
  decline_reason: z
110
132
  .string()
111
- .max(PERMIT_OFFER_MESSAGE_LENGTH_MAX)
133
+ .max(ROLE_GRANT_OFFER_MESSAGE_LENGTH_MAX)
112
134
  .nullable()
113
135
  .meta({ description: 'Optional reason given on decline.' }),
114
136
  retracted_at: z
@@ -116,19 +138,21 @@ export const PermitOfferJson = z
116
138
  .nullable()
117
139
  .meta({ description: 'ISO timestamp when the grantor retracted the offer.' }),
118
140
  superseded_at: z.string().nullable().meta({
119
- description: 'ISO timestamp when this offer was obsoleted by a sibling accept or by revoke of the resulting permit.',
141
+ description: 'ISO timestamp when this offer was obsoleted by a sibling accept or by revoke of the resulting role_grant.',
120
142
  }),
121
- resulting_permit_id: Uuid.nullable().meta({
122
- description: 'Permit produced by accepting this offer. `null` until/unless accepted.',
143
+ resulting_role_grant_id: Uuid.nullable().meta({
144
+ description: 'Role grant produced by accepting this offer. `null` until/unless accepted.',
123
145
  }),
124
146
  })
125
- .meta({ description: 'A permit offer — a pending grant awaiting recipient consent.' });
126
- /** Convert a `PermitOffer` row to its JSON payload shape. */
127
- export const to_permit_offer_json = (offer) => ({
147
+ .meta({ description: 'A role_grant offer — a pending grant awaiting recipient consent.' });
148
+ /** Convert a `RoleGrantOffer` row to its JSON payload shape. */
149
+ export const to_role_grant_offer_json = (offer) => ({
128
150
  id: offer.id,
129
151
  from_actor_id: offer.from_actor_id,
130
152
  to_account_id: offer.to_account_id,
153
+ to_actor_id: offer.to_actor_id,
131
154
  role: offer.role,
155
+ scope_kind: offer.scope_kind,
132
156
  scope_id: offer.scope_id,
133
157
  message: offer.message,
134
158
  created_at: offer.created_at,
@@ -138,5 +162,5 @@ export const to_permit_offer_json = (offer) => ({
138
162
  decline_reason: offer.decline_reason,
139
163
  retracted_at: offer.retracted_at,
140
164
  superseded_at: offer.superseded_at,
141
- resulting_permit_id: offer.resulting_permit_id,
165
+ resulting_role_grant_id: offer.resulting_role_grant_id,
142
166
  });
@@ -0,0 +1,231 @@
1
+ /**
2
+ * Role grant database queries.
3
+ *
4
+ * Role grants are time-bounded, revocable grants of a role to an actor.
5
+ * The system is safe by default — no role_grant, no capability.
6
+ *
7
+ * @module
8
+ */
9
+ import type { Uuid } from '@fuzdev/fuz_util/id.js';
10
+ import type { QueryDeps } from '../db/query_deps.js';
11
+ import type { RoleGrant, CreateRoleGrantInput } from './account_schema.js';
12
+ import { type SupersededOffer } from './role_grant_offer_schema.js';
13
+ /**
14
+ * Grant a role_grant to an actor.
15
+ * Idempotent — if an active role_grant already exists for this actor, role, and
16
+ * scope, returns the existing role_grant instead of creating a duplicate.
17
+ *
18
+ * The `ON CONFLICT` target and the fallback `SELECT` both collapse `NULL`
19
+ * scopes via the same sentinel + index-side `'GLOBAL'` token used by the
20
+ * partial unique index (`role_grant_actor_role_scope_active_unique`). The
21
+ * `IS NOT DISTINCT FROM` form on the fallback is deliberate — plain `=`
22
+ * would miss the NULL-scope case where the conflict fired.
23
+ *
24
+ * `scope_kind` is paired-null with `scope_id` per the
25
+ * `role_grant_scope_kind_paired` CHECK; mismatched pairs raise at the DB
26
+ * layer rather than producing silent rows.
27
+ *
28
+ * @param deps - query dependencies
29
+ * @param input - the role_grant fields
30
+ * @returns the created or existing active role_grant
31
+ * @mutates `role_grant` table - inserts a row when no active role_grant matches `(actor_id, role, scope_kind, scope_id)`
32
+ */
33
+ export declare const query_create_role_grant: (deps: QueryDeps, input: CreateRoleGrantInput) => Promise<RoleGrant>;
34
+ /**
35
+ * Look up the role of an active role_grant (constrained to a specific
36
+ * actor) plus the actor's `account_id`.
37
+ *
38
+ * Used by admin routes to inspect the role_grant's role before acting
39
+ * (e.g., enforcing the admin-grant-path gate on revoke). The actor constraint
40
+ * mirrors `query_revoke_role_grant` so IDOR protection is consistent:
41
+ * a caller can only see role_grants belonging to the target actor.
42
+ *
43
+ * The JOIN to `actor` collapses what used to be a second
44
+ * `query_actor_by_id` round-trip in the revoke handler into one read,
45
+ * which closes the small TOCTOU window where the actor row could be
46
+ * deleted between the IDOR check and the actor lookup. The `account_id`
47
+ * is needed by the audit envelope's `target_account_id` field and the
48
+ * SSE/WS socket-close fan-out targeting.
49
+ *
50
+ * Returns `null` if the role_grant is not found, already revoked, or
51
+ * belongs to a different actor.
52
+ *
53
+ * @param deps - query dependencies
54
+ * @param role_grant_id - the role_grant id to look up
55
+ * @param actor_id - the actor that must own the role_grant
56
+ * @returns `{role, account_id}` on a match, or `null`
57
+ */
58
+ export declare const query_role_grant_find_active_role_for_actor: (deps: QueryDeps, role_grant_id: string, actor_id: string) => Promise<{
59
+ role: string;
60
+ account_id: Uuid;
61
+ } | null>;
62
+ /** Result of `query_revoke_role_grant` — the revoked role_grant plus any pending offers superseded by the revoke. */
63
+ export interface RevokeRoleGrantResult {
64
+ id: Uuid;
65
+ role: string;
66
+ scope_kind: string | null;
67
+ scope_id: Uuid | null;
68
+ /**
69
+ * Pending offers for the revoked role_grant's `(account, role, scope)` that
70
+ * were marked superseded as a side effect. Each entry carries its
71
+ * grantor's `from_account_id` so callers can fan out
72
+ * `role_grant_offer_supersede` notifications without a second round-trip.
73
+ * The caller is responsible for emitting a `role_grant_offer_supersede`
74
+ * audit event per entry (with `reason: 'role_grant_revoked'` and
75
+ * `cause_id: <revoked role_grant id>`).
76
+ */
77
+ superseded_offers: Array<SupersededOffer>;
78
+ }
79
+ /**
80
+ * Revoke a role_grant by id, constrained to a specific actor.
81
+ *
82
+ * Requires `actor_id` to prevent cross-account revocation (IDOR guard).
83
+ * Returns `null` if the role_grant is not found, already revoked, or belongs
84
+ * to a different actor.
85
+ *
86
+ * Supersedes any pending offers for the revoked role_grant's
87
+ * `(to_account, role, scope)` in the same transaction. Prevents the
88
+ * "accept a pre-revoke offer to bypass the revoke" path — any stale
89
+ * offer becomes terminal at revoke time. A fresh post-revoke grant
90
+ * requires the grantor to call `query_role_grant_offer_create` again.
91
+ *
92
+ * @param deps - query dependencies
93
+ * @param role_grant_id - the role_grant to revoke
94
+ * @param actor_id - the actor that must own the role_grant
95
+ * @param revoked_by - the actor who revoked it (for audit trail)
96
+ * @param reason - optional free-form reason, stamped on `role_grant.revoked_reason` and surfaced to the revokee notification.
97
+ * @mutates `role_grant` row - sets `revoked_at`, `revoked_by`, and `revoked_reason`
98
+ * @mutates `role_grant_offer` rows - stamps `superseded_at` on every pending sibling for the same `(account, role, scope)`
99
+ */
100
+ export declare const query_revoke_role_grant: (deps: QueryDeps, role_grant_id: Uuid, actor_id: Uuid, revoked_by: Uuid | null, reason?: string | null) => Promise<RevokeRoleGrantResult | null>;
101
+ /**
102
+ * Find all active (non-revoked, non-expired) role_grants for an actor.
103
+ */
104
+ export declare const query_role_grant_find_active_for_actor: (deps: QueryDeps, actor_id: string) => Promise<Array<RoleGrant>>;
105
+ /**
106
+ * Check if an actor has an active role_grant for a given role.
107
+ *
108
+ * The `scope_id` parameter selects between global and scoped checks:
109
+ * - Omitted or `null` — matches a global role_grant (`scope_id IS NULL`).
110
+ * Pre-scope callers keep their existing semantics.
111
+ * - A scope uuid — matches a role_grant bound to that exact scope.
112
+ *
113
+ * The `IS NOT DISTINCT FROM` comparison handles the NULL case uniformly.
114
+ */
115
+ export declare const query_role_grant_has_role: (deps: QueryDeps, actor_id: string, role: string, scope_id?: string | null) => Promise<boolean>;
116
+ /**
117
+ * List all role_grants for an actor (including revoked/expired).
118
+ */
119
+ export declare const query_role_grant_list_for_actor: (deps: QueryDeps, actor_id: string) => Promise<Array<RoleGrant>>;
120
+ /**
121
+ * Find the account ID of an account that holds an active role_grant for a given role.
122
+ *
123
+ * Joins role_grant → actor → account. Returns the first match, or `null` if none.
124
+ *
125
+ * @param deps - query dependencies
126
+ * @param role - the role to search for
127
+ * @returns the account ID, or `null`
128
+ */
129
+ export declare const query_role_grant_find_account_id_for_role: (deps: QueryDeps, role: string) => Promise<string | null>;
130
+ /** Result of `query_role_grant_revoke_for_scope` — every role_grant revoked plus every pending offer superseded by the scope-wide cascade. */
131
+ export interface RevokeForScopeResult {
132
+ /**
133
+ * One entry per role_grant revoked by this call. Carries both the revokee's
134
+ * `actor_id` (the role_grant's grantee — drives `target_actor_id` audit
135
+ * envelopes) and `account_id` (the actor's account — drives
136
+ * `target_account_id` for SSE/WS socket-close fan-out). Empty array
137
+ * means no active role_grant was bound to the scope. `scope_kind` is
138
+ * surfaced for forensic completeness; the cascade itself keys on
139
+ * `scope_id` regardless of kind.
140
+ */
141
+ revoked: Array<{
142
+ role_grant_id: Uuid;
143
+ role: string;
144
+ scope_kind: string | null;
145
+ scope_id: Uuid;
146
+ actor_id: Uuid;
147
+ account_id: Uuid;
148
+ }>;
149
+ /**
150
+ * Every pending offer at the scope — tuple-matched and orphan, undifferentiated
151
+ * — superseded in the same cascade. Each entry carries its grantor's
152
+ * `from_account_id` for `role_grant_offer_supersede` notification fan-out.
153
+ *
154
+ * The caller is responsible for emitting `role_grant_offer_supersede` audit
155
+ * events with `reason: 'scope_destroyed'` and `cause_id: <destroyed scope row id>`
156
+ * per entry — the cause of every supersede here is the scope deletion,
157
+ * not any individual role_grant revoke (the revokes are themselves
158
+ * consequences of the scope going away).
159
+ */
160
+ superseded_offers: Array<SupersededOffer>;
161
+ }
162
+ /**
163
+ * Revoke every active role_grant bound to a scope and supersede every pending
164
+ * offer at the scope, in one cascade.
165
+ *
166
+ * Use this from a consumer's parent-scope delete handler (e.g., classroom
167
+ * deletion) — `role_grant.scope_id` and `role_grant_offer.scope_id` are polymorphic
168
+ * with no FK constraint by design, so a parent row deletion would otherwise
169
+ * orphan role_grants and offers. The cascade is **role-agnostic**: anything
170
+ * attached to the destroyed scope is cleaned up.
171
+ *
172
+ * Both updates run as separate statements inside the caller's transaction
173
+ * (mirrors `query_role_grant_revoke_role`'s shape). The two halves are
174
+ * independent — orphan pending offers can exist at a scope with no active
175
+ * role_grants, so the supersede half always runs even when no role_grant was
176
+ * revoked.
177
+ *
178
+ * @param deps - query dependencies
179
+ * @param scope_id - the scope whose role_grants and offers to terminate
180
+ * @param revoked_by - the actor performing the cascade (audit trail)
181
+ * @param reason - optional free-form reason, stamped on `role_grant.revoked_reason`.
182
+ * @returns the revoked role_grants (with `account_id` for fan-out) and superseded offers (with `from_account_id` for fan-out)
183
+ * @mutates `role_grant` table - sets `revoked_at`/`revoked_by`/`revoked_reason` on every active row at `scope_id`
184
+ * @mutates `role_grant_offer` table - stamps `superseded_at` on every pending row at `scope_id`
185
+ */
186
+ export declare const query_role_grant_revoke_for_scope: (deps: QueryDeps, scope_id: Uuid, revoked_by: Uuid | null, reason?: string | null) => Promise<RevokeForScopeResult>;
187
+ /** Result of `query_role_grant_revoke_role` — every role_grant revoked plus the pending offers superseded by the bulk revoke. */
188
+ export interface RevokeRoleResult {
189
+ /**
190
+ * One entry per role_grant revoked by this call. Carries the revokee's
191
+ * `account_id` so callers can fan out a `role_grant_revoke` notification per
192
+ * scope-instance. Empty array means nothing was active for `(actor, role)`.
193
+ */
194
+ revoked: Array<{
195
+ role_grant_id: string;
196
+ role: string;
197
+ scope_kind: string | null;
198
+ scope_id: string | null;
199
+ account_id: string;
200
+ }>;
201
+ /**
202
+ * Pending offers for the actor's account+role (all scopes) superseded by
203
+ * the bulk revoke. Each entry carries its grantor's `from_account_id` so
204
+ * callers can fan out `role_grant_offer_supersede` notifications without a
205
+ * second round-trip.
206
+ */
207
+ superseded_offers: Array<SupersededOffer>;
208
+ }
209
+ /**
210
+ * Revoke every active role_grant an actor holds for a given role.
211
+ *
212
+ * With scoped role_grants a single actor+role tuple can hold several active
213
+ * role_grants (one per scope), so this revokes all of them. Pass
214
+ * `query_revoke_role_grant(role_grant_id, ...)` when a single scoped role_grant
215
+ * is the target.
216
+ *
217
+ * Also supersedes pending offers for the actor's account across every
218
+ * scope of this role (the actor can no longer hold the role, so any
219
+ * pending offer of the same role is a bypass vector).
220
+ *
221
+ * @param deps - query dependencies
222
+ * @param actor_id - the actor whose role_grants to revoke
223
+ * @param role - the role to revoke
224
+ * @param revoked_by - the actor who revoked it (for audit trail)
225
+ * @param reason - optional free-form reason, stamped on `role_grant.revoked_reason`.
226
+ * @returns the list of revoked role_grants (empty if none were active) and superseded pending offers
227
+ * @mutates `role_grant` table - sets `revoked_at`/`revoked_by`/`revoked_reason` on every active row for `(actor, role)`
228
+ * @mutates `role_grant_offer` table - stamps `superseded_at` on every matching pending offer
229
+ */
230
+ export declare const query_role_grant_revoke_role: (deps: QueryDeps, actor_id: string, role: string, revoked_by: string | null, reason?: string | null) => Promise<RevokeRoleResult>;
231
+ //# sourceMappingURL=role_grant_queries.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"role_grant_queries.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/auth/role_grant_queries.ts"],"names":[],"mappings":"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"}