@x12i/memorix-service 3.11.1 → 3.12.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 (45) hide show
  1. package/dist/app.d.ts.map +1 -1
  2. package/dist/app.js +3 -0
  3. package/dist/app.js.map +1 -1
  4. package/dist/hooks/contract.d.ts +9 -0
  5. package/dist/hooks/contract.d.ts.map +1 -0
  6. package/dist/hooks/contract.js +87 -0
  7. package/dist/hooks/contract.js.map +1 -0
  8. package/dist/hooks/deliver.d.ts +19 -0
  9. package/dist/hooks/deliver.d.ts.map +1 -0
  10. package/dist/hooks/deliver.js +57 -0
  11. package/dist/hooks/deliver.js.map +1 -0
  12. package/dist/hooks/enqueue.d.ts +4 -0
  13. package/dist/hooks/enqueue.d.ts.map +1 -0
  14. package/dist/hooks/enqueue.js +19 -0
  15. package/dist/hooks/enqueue.js.map +1 -0
  16. package/dist/hooks/store.d.ts +5 -0
  17. package/dist/hooks/store.d.ts.map +1 -0
  18. package/dist/hooks/store.js +229 -0
  19. package/dist/hooks/store.js.map +1 -0
  20. package/dist/hooks/types.d.ts +93 -0
  21. package/dist/hooks/types.d.ts.map +1 -0
  22. package/dist/hooks/types.js +25 -0
  23. package/dist/hooks/types.js.map +1 -0
  24. package/dist/hooks/validate.d.ts +19 -0
  25. package/dist/hooks/validate.d.ts.map +1 -0
  26. package/dist/hooks/validate.js +173 -0
  27. package/dist/hooks/validate.js.map +1 -0
  28. package/dist/hooks/worker.d.ts +13 -0
  29. package/dist/hooks/worker.d.ts.map +1 -0
  30. package/dist/hooks/worker.js +80 -0
  31. package/dist/hooks/worker.js.map +1 -0
  32. package/dist/openapi/openapi.json +139 -1
  33. package/dist/platform.d.ts +11 -0
  34. package/dist/platform.d.ts.map +1 -1
  35. package/dist/platform.js +129 -0
  36. package/dist/platform.js.map +1 -1
  37. package/dist/routes/data.d.ts.map +1 -1
  38. package/dist/routes/data.js +15 -0
  39. package/dist/routes/data.js.map +1 -1
  40. package/dist/routes/hooks.d.ts +4 -0
  41. package/dist/routes/hooks.d.ts.map +1 -0
  42. package/dist/routes/hooks.js +104 -0
  43. package/dist/routes/hooks.js.map +1 -0
  44. package/openapi/openapi.json +139 -1
  45. package/package.json +2 -2
@@ -0,0 +1,104 @@
1
+ import { resolveScope } from "../request-scope.js";
2
+ import { ServiceError } from "../errors.js";
3
+ import { sameAgentIds, toPublicDelivery, toPublicSubscription, } from "../hooks/types.js";
4
+ import { assertSubscriptionId, parseDeliveryLimit, parseDeliveryStatus, parseSubscriptionPatch, parseSubscriptionPut, } from "../hooks/validate.js";
5
+ function inScope(row, agentIds) {
6
+ return sameAgentIds(row.agentIds, agentIds);
7
+ }
8
+ export async function registerHookRoutes(app, platform) {
9
+ app.put("/api/hooks/v1/subscriptions/:subscriptionId", async (req) => {
10
+ const scope = resolveScope(req);
11
+ const subscriptionId = assertSubscriptionId(req.params.subscriptionId);
12
+ const body = parseSubscriptionPut(req.body);
13
+ const store = platform.hooksFor(scope.orgId);
14
+ const existing = await store.findSubscription(subscriptionId);
15
+ if (existing && !inScope(existing, scope.agentIds)) {
16
+ throw new ServiceError("HOOK_SUBSCRIPTION_INVALID", "subscriptionId is registered to a different agent scope", 409);
17
+ }
18
+ if (!existing && !body.signingSecret) {
19
+ throw new ServiceError("HOOK_SUBSCRIPTION_INVALID", "signing key is required on create", 400);
20
+ }
21
+ const now = new Date().toISOString();
22
+ const endpointChanged = Boolean(existing && existing.endpoint !== body.endpoint);
23
+ const row = {
24
+ subscriptionId,
25
+ orgId: scope.orgId,
26
+ agentIds: [...scope.agentIds],
27
+ endpoint: body.endpoint,
28
+ signingSecret: body.signingSecret ?? existing.signingSecret,
29
+ enabled: body.enabled,
30
+ match: body.match,
31
+ health: endpointChanged ? "ok" : (existing?.health ?? "ok"),
32
+ createdAt: existing?.createdAt ?? now,
33
+ updatedAt: now,
34
+ };
35
+ await store.saveSubscription(row);
36
+ if (endpointChanged)
37
+ await store.retargetPending(subscriptionId, body.endpoint);
38
+ return toPublicSubscription(row);
39
+ });
40
+ app.get("/api/hooks/v1/subscriptions", async (req) => {
41
+ const scope = resolveScope(req);
42
+ const store = platform.hooksFor(scope.orgId);
43
+ const rows = await store.listSubscriptions();
44
+ return { subscriptions: rows.filter((row) => inScope(row, scope.agentIds)).map(toPublicSubscription) };
45
+ });
46
+ app.get("/api/hooks/v1/subscriptions/:subscriptionId", async (req) => {
47
+ const scope = resolveScope(req);
48
+ const subscriptionId = assertSubscriptionId(req.params.subscriptionId);
49
+ const row = await platform.hooksFor(scope.orgId).findSubscription(subscriptionId);
50
+ if (!row || !inScope(row, scope.agentIds)) {
51
+ throw new ServiceError("HOOK_SUBSCRIPTION_NOT_FOUND", "subscription not found", 404);
52
+ }
53
+ return toPublicSubscription(row);
54
+ });
55
+ app.patch("/api/hooks/v1/subscriptions/:subscriptionId", async (req) => {
56
+ const scope = resolveScope(req);
57
+ const subscriptionId = assertSubscriptionId(req.params.subscriptionId);
58
+ const patch = parseSubscriptionPatch(req.body);
59
+ const store = platform.hooksFor(scope.orgId);
60
+ const existing = await store.findSubscription(subscriptionId);
61
+ if (!existing || !inScope(existing, scope.agentIds)) {
62
+ throw new ServiceError("HOOK_SUBSCRIPTION_NOT_FOUND", "subscription not found", 404);
63
+ }
64
+ const endpointChanged = patch.endpoint !== undefined && patch.endpoint !== existing.endpoint;
65
+ const row = {
66
+ ...existing,
67
+ ...(patch.endpoint !== undefined ? { endpoint: patch.endpoint } : {}),
68
+ ...(patch.enabled !== undefined ? { enabled: patch.enabled } : {}),
69
+ ...(patch.match !== undefined ? { match: patch.match } : {}),
70
+ health: endpointChanged ? "ok" : existing.health,
71
+ updatedAt: new Date().toISOString(),
72
+ };
73
+ await store.saveSubscription(row);
74
+ if (endpointChanged && patch.endpoint)
75
+ await store.retargetPending(subscriptionId, patch.endpoint);
76
+ return toPublicSubscription(row);
77
+ });
78
+ app.delete("/api/hooks/v1/subscriptions/:subscriptionId", async (req) => {
79
+ const scope = resolveScope(req);
80
+ const subscriptionId = assertSubscriptionId(req.params.subscriptionId);
81
+ const store = platform.hooksFor(scope.orgId);
82
+ const existing = await store.findSubscription(subscriptionId);
83
+ if (!existing || !inScope(existing, scope.agentIds)) {
84
+ throw new ServiceError("HOOK_SUBSCRIPTION_NOT_FOUND", "subscription not found", 404);
85
+ }
86
+ await store.deletePending(subscriptionId);
87
+ await store.deleteSubscription(subscriptionId);
88
+ return { removed: true };
89
+ });
90
+ app.get("/api/hooks/v1/subscriptions/:subscriptionId/deliveries", async (req) => {
91
+ const scope = resolveScope(req);
92
+ const subscriptionId = assertSubscriptionId(req.params.subscriptionId);
93
+ const store = platform.hooksFor(scope.orgId);
94
+ const existing = await store.findSubscription(subscriptionId);
95
+ if (!existing || !inScope(existing, scope.agentIds)) {
96
+ throw new ServiceError("HOOK_SUBSCRIPTION_NOT_FOUND", "subscription not found", 404);
97
+ }
98
+ const status = parseDeliveryStatus(req.query.status);
99
+ const limit = parseDeliveryLimit(req.query.limit);
100
+ const rows = await store.listDeliveries(subscriptionId, { ...(status ? { status } : {}), limit });
101
+ return { deliveries: rows.map(toPublicDelivery) };
102
+ });
103
+ }
104
+ //# sourceMappingURL=hooks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hooks.js","sourceRoot":"","sources":["../../src/routes/hooks.ts"],"names":[],"mappings":"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"}
@@ -2,7 +2,7 @@
2
2
  "openapi": "3.0.3",
3
3
  "info": {
4
4
  "title": "Memorix Service API",
5
- "version": "3.11.1",
5
+ "version": "3.12.0",
6
6
  "description": "One versioned product API over accepted Memorix packages. Scope: orgId + agentIds[]. Headers x-memorix-org-id and x-memorix-agent-ids (comma-separated). MX-CALLER-01: every /api request requires x-memorix-caller (calling app id). Intelligence never auto-installs. Relationships /links is forbidden. IntegrationsRegistry (Stage −1) and RestrictedStore (FG-A3 dual-mode blob)."
7
7
  },
8
8
  "servers": [
@@ -46,6 +46,10 @@
46
46
  "name": "Jobs",
47
47
  "description": "Jobs Manager repeated-work API. P3 reads and P4 writes live."
48
48
  },
49
+ {
50
+ "name": "Hooks",
51
+ "description": "Content hooks. A subscription is notified after one address is created, updated, or removed. The callback does not run a skill."
52
+ },
49
53
  {
50
54
  "name": "Connectors",
51
55
  "description": "Unified connector catalog (registry + builtins + MGC remote hosts)"
@@ -2880,6 +2884,10 @@
2880
2884
  "$ref": "#/components/schemas/PatchOp"
2881
2885
  }
2882
2886
  },
2887
+ "suppressHooks": {
2888
+ "type": "boolean",
2889
+ "description": "When true, this write does not notify content-hook subscriptions. Not stored on the record. For bulk load and migration."
2890
+ },
2883
2891
  "address": {
2884
2892
  "$ref": "#/components/schemas/ContentAddress"
2885
2893
  },
@@ -14923,6 +14931,106 @@
14923
14931
  }
14924
14932
  }
14925
14933
  }
14934
+ },
14935
+ "/api/hooks/v1/subscriptions": {
14936
+ "get": {
14937
+ "operationId": "hooksListSubscriptions",
14938
+ "tags": ["Hooks"],
14939
+ "summary": "List content-hook subscriptions for this org and agent set",
14940
+ "parameters": [
14941
+ { "$ref": "#/components/parameters/XMemorixCaller" },
14942
+ { "$ref": "#/components/parameters/XMemorixOrgId" },
14943
+ { "$ref": "#/components/parameters/XMemorixAgentIds" }
14944
+ ],
14945
+ "responses": {
14946
+ "200": { "description": "Subscriptions. signingSecret is omitted." }
14947
+ }
14948
+ }
14949
+ },
14950
+ "/api/hooks/v1/subscriptions/{subscriptionId}": {
14951
+ "put": {
14952
+ "operationId": "hooksPutSubscription",
14953
+ "tags": ["Hooks"],
14954
+ "summary": "Create or replace a content-hook subscription",
14955
+ "parameters": [
14956
+ { "$ref": "#/components/parameters/XMemorixCaller" },
14957
+ { "$ref": "#/components/parameters/XMemorixOrgId" },
14958
+ { "$ref": "#/components/parameters/XMemorixAgentIds" },
14959
+ { "name": "subscriptionId", "in": "path", "required": true, "schema": { "type": "string" } }
14960
+ ],
14961
+ "requestBody": {
14962
+ "required": true,
14963
+ "content": { "application/json": { "schema": { "$ref": "#/components/schemas/HookSubscriptionWrite" } } }
14964
+ },
14965
+ "responses": {
14966
+ "200": { "description": "Stored subscription. signingSecret is omitted." },
14967
+ "400": { "description": "HOOK_SUBSCRIPTION_INVALID" },
14968
+ "409": { "description": "subscriptionId belongs to a different agent scope" }
14969
+ }
14970
+ },
14971
+ "get": {
14972
+ "operationId": "hooksGetSubscription",
14973
+ "tags": ["Hooks"],
14974
+ "summary": "Read one content-hook subscription",
14975
+ "parameters": [
14976
+ { "$ref": "#/components/parameters/XMemorixCaller" },
14977
+ { "$ref": "#/components/parameters/XMemorixOrgId" },
14978
+ { "$ref": "#/components/parameters/XMemorixAgentIds" },
14979
+ { "name": "subscriptionId", "in": "path", "required": true, "schema": { "type": "string" } }
14980
+ ],
14981
+ "responses": {
14982
+ "200": { "description": "Subscription. signingSecret is omitted." },
14983
+ "404": { "description": "HOOK_SUBSCRIPTION_NOT_FOUND" }
14984
+ }
14985
+ },
14986
+ "patch": {
14987
+ "operationId": "hooksPatchSubscription",
14988
+ "tags": ["Hooks"],
14989
+ "summary": "Update enabled, endpoint, or match",
14990
+ "parameters": [
14991
+ { "$ref": "#/components/parameters/XMemorixCaller" },
14992
+ { "$ref": "#/components/parameters/XMemorixOrgId" },
14993
+ { "$ref": "#/components/parameters/XMemorixAgentIds" },
14994
+ { "name": "subscriptionId", "in": "path", "required": true, "schema": { "type": "string" } }
14995
+ ],
14996
+ "responses": {
14997
+ "200": { "description": "Updated subscription. signingSecret is omitted." },
14998
+ "400": { "description": "HOOK_SUBSCRIPTION_INVALID" },
14999
+ "404": { "description": "HOOK_SUBSCRIPTION_NOT_FOUND" }
15000
+ }
15001
+ },
15002
+ "delete": {
15003
+ "operationId": "hooksDeleteSubscription",
15004
+ "tags": ["Hooks"],
15005
+ "summary": "Remove a subscription and stop pending delivery",
15006
+ "parameters": [
15007
+ { "$ref": "#/components/parameters/XMemorixCaller" },
15008
+ { "$ref": "#/components/parameters/XMemorixOrgId" },
15009
+ { "$ref": "#/components/parameters/XMemorixAgentIds" },
15010
+ { "name": "subscriptionId", "in": "path", "required": true, "schema": { "type": "string" } }
15011
+ ],
15012
+ "responses": {
15013
+ "200": { "description": "Removed" },
15014
+ "404": { "description": "HOOK_SUBSCRIPTION_NOT_FOUND" }
15015
+ }
15016
+ }
15017
+ },
15018
+ "/api/hooks/v1/subscriptions/{subscriptionId}/deliveries": {
15019
+ "get": {
15020
+ "operationId": "hooksListDeliveries",
15021
+ "tags": ["Hooks"],
15022
+ "summary": "Recent delivery status, newest first",
15023
+ "parameters": [
15024
+ { "$ref": "#/components/parameters/XMemorixCaller" },
15025
+ { "$ref": "#/components/parameters/XMemorixOrgId" },
15026
+ { "$ref": "#/components/parameters/XMemorixAgentIds" },
15027
+ { "name": "subscriptionId", "in": "path", "required": true, "schema": { "type": "string" } },
15028
+ { "name": "status", "in": "query", "schema": { "type": "string", "enum": ["pending", "delivered", "rejected", "failed"] } }
15029
+ ],
15030
+ "responses": {
15031
+ "200": { "description": "Delivery rows. Not stored on the subject record." }
15032
+ }
15033
+ }
14926
15034
  }
14927
15035
  },
14928
15036
  "components": {
@@ -14963,6 +15071,36 @@
14963
15071
  }
14964
15072
  },
14965
15073
  "schemas": {
15074
+ "HookSubscriptionWrite": {
15075
+ "type": "object",
15076
+ "required": ["endpoint", "match"],
15077
+ "additionalProperties": false,
15078
+ "properties": {
15079
+ "endpoint": { "type": "string", "format": "uri" },
15080
+ "enabled": { "type": "boolean" },
15081
+ "signingSecret": { "type": "string", "description": "Required on create. Write-only. A later PUT that omits it keeps the stored secret." },
15082
+ "match": {
15083
+ "type": "object",
15084
+ "required": ["objectType", "contentType", "events"],
15085
+ "additionalProperties": false,
15086
+ "properties": {
15087
+ "objectType": { "type": "string" },
15088
+ "contentType": { "type": "string" },
15089
+ "discriminator": {
15090
+ "type": "object",
15091
+ "required": ["path", "equals"],
15092
+ "additionalProperties": false,
15093
+ "properties": {
15094
+ "path": { "type": "string" },
15095
+ "equals": {}
15096
+ }
15097
+ },
15098
+ "events": { "type": "array", "minItems": 1, "items": { "type": "string", "enum": ["created", "updated", "removed"] } },
15099
+ "ignoreCallers": { "type": "array", "items": { "type": "string" } }
15100
+ }
15101
+ }
15102
+ }
15103
+ },
14966
15104
  "MemorixScope": {
14967
15105
  "type": "object",
14968
15106
  "required": [
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@x12i/memorix-service",
3
- "version": "3.11.1",
3
+ "version": "3.12.0",
4
4
  "description": "Memorix production service composition root — one versioned API over accepted packages.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -47,7 +47,7 @@
47
47
  "@x12i/funcx": "^4.12.0",
48
48
  "@x12i/magit": "2.14.0",
49
49
  "@x12i/memorix-connector-sdk": "^1.3.0",
50
- "@x12i/memorix-data": "^3.1.0",
50
+ "@x12i/memorix-data": "^3.1.1",
51
51
  "@x12i/memorix-data-journey": "^3.1.0",
52
52
  "@x12i/memorix-format": "^3.0.8",
53
53
  "@x12i/memorix-intelligence": "^3.0.2",