@rubytech/create-sitedesk-code 0.1.524 → 0.1.526
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/__tests__/samba-provision.test.js +46 -1
- package/dist/__tests__/websockify-bind-wiring.test.js +47 -0
- package/dist/index.js +39 -1
- package/dist/samba-provision.js +37 -0
- package/package.json +1 -1
- package/payload/platform/plugins/admin/skills/platform-architecture/SKILL.md +8 -7
- package/payload/platform/plugins/admin/skills/superpowers-sprint/SKILL.md +26 -0
- package/payload/platform/plugins/admin/skills/whats-new/SKILL.md +12 -0
- package/payload/platform/plugins/memory/PLUGIN.md +10 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/compiled-truth-revision.test.js +5 -1
- package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/compiled-truth-revision.test.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/temporal-type-preserve.test.d.ts +2 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/temporal-type-preserve.test.d.ts.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/temporal-type-preserve.test.js +141 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/temporal-type-preserve.test.js.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/log-ingest.d.ts +1 -1
- package/payload/platform/plugins/memory/mcp/dist/lib/log-ingest.d.ts.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/lib/log-ingest.js +6 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/log-ingest.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/lib/temporal-type-preserve.d.ts +45 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/temporal-type-preserve.d.ts.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/temporal-type-preserve.js +122 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/temporal-type-preserve.js.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-update-by-name.test.js +26 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-update-by-name.test.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-update-type-preserve.test.d.ts +2 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-update-type-preserve.test.d.ts.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-update-type-preserve.test.js +201 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-update-type-preserve.test.js.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-update.d.ts.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-update.js +89 -33
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-update.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/vitest.config.ts +2 -0
- package/payload/platform/plugins/scheduling/PLUGIN.md +6 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/meeting-retype.test.d.ts +2 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/meeting-retype.test.d.ts.map +1 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/meeting-retype.test.js +148 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/meeting-retype.test.js.map +1 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/booking-reconcile.d.ts +83 -6
- package/payload/platform/plugins/scheduling/mcp/dist/lib/booking-reconcile.d.ts.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/lib/booking-reconcile.js +90 -5
- package/payload/platform/plugins/scheduling/mcp/dist/lib/booking-reconcile.js.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/__tests__/routine-roster-audit.test.js +173 -2
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/__tests__/routine-roster-audit.test.js.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/agent-turn-dispatch.d.ts +73 -0
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/agent-turn-dispatch.d.ts.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/agent-turn-dispatch.js +194 -0
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/agent-turn-dispatch.js.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/check-due-events.js +25 -1
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/check-due-events.js.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/reconcile-bookings.js +81 -8
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/reconcile-bookings.js.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/tools/__tests__/schedule-event-agent.test.js +39 -0
- package/payload/platform/plugins/scheduling/mcp/dist/tools/__tests__/schedule-event-agent.test.js.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-event.d.ts.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-event.js +9 -1
- package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-event.js.map +1 -1
- package/payload/platform/scripts/__tests__/check-canonical-tool-names.test.sh +162 -0
- package/payload/platform/scripts/__tests__/check-no-task-id-leaks.test.sh +53 -0
- package/payload/platform/scripts/__tests__/task-id-citation.test.sh +72 -0
- package/payload/platform/scripts/check-canonical-tool-names.mjs +36 -4
- package/payload/platform/scripts/check-no-task-id-leaks.mjs +80 -62
- package/payload/platform/scripts/lib/canonical-tool-names.mjs +130 -26
- package/payload/platform/scripts/lib/task-id-citation.mjs +67 -0
- package/payload/platform/scripts/vnc.sh +45 -1
- package/payload/server/{chunk-VUXKXOJU.js → chunk-7MGR5M6G.js} +4 -2
- package/payload/server/{manager-4TJK3YOY.js → manager-6XOWHREK.js} +1 -1
- package/payload/server/server.js +10 -4
- package/payload/platform/.docs/search-surface-contract.md +0 -58
- package/payload/platform/docs/superpowers/plans/2026-06-02-task-610-follower-202-retry.md +0 -372
- package/payload/platform/docs/superpowers/plans/2026-06-04-public-agent-knowledge-delivery.md +0 -230
- package/payload/platform/docs/superpowers/plans/2026-06-23-account-filesystem-schema.md +0 -544
- package/payload/platform/docs/superpowers/plans/2026-07-11-task-1557-operator-on-behalf-preference-attribution.md +0 -542
- package/payload/platform/docs/superpowers/plans/2026-07-13-account-schema-ontology-projection.md +0 -547
- package/payload/platform/docs/superpowers/plans/2026-07-14-graph-top-level-labels-ontology-single-source.md +0 -458
- package/payload/platform/docs/superpowers/plans/2026-07-17-task-1736-retire-mcp-stderr-tee.md +0 -397
- package/payload/platform/docs/superpowers/plans/2026-07-18-graph-native-ledger.md +0 -807
- package/payload/platform/docs/superpowers/plans/2026-07-18-ledger-write-path-fix.md +0 -109
- package/payload/platform/docs/superpowers/plans/2026-07-20-storage-pages-create.md +0 -82
- package/payload/platform/docs/superpowers/plans/2026-07-20-task-1704-data-portal-standing-audit.md +0 -673
- package/payload/platform/docs/superpowers/plans/2026-07-20-task-1789-reseat-channel-row-fork.md +0 -1244
- package/payload/platform/docs/superpowers/plans/2026-07-20-task-1818-loop-gate-app-routes.md +0 -462
- package/payload/platform/docs/superpowers/plans/2026-07-20-task-1819-top-level-label-allowlist.md +0 -321
- package/payload/platform/docs/superpowers/plans/2026-07-20-task-1829-platform-ui-typecheck.md +0 -830
- package/payload/platform/docs/superpowers/plans/2026-07-20-task-1831-data-portal-class-derived-allowlist.md +0 -2177
- package/payload/platform/docs/superpowers/plans/2026-07-21-graph-caption-resolver.md +0 -124
- package/payload/platform/docs/superpowers/plans/2026-07-21-task-1877-bash-schema-enforcement.md +0 -107
- package/payload/platform/docs/superpowers/plans/2026-07-21-task-1887-reconcile-allowed-top-level.md +0 -205
- package/payload/platform/docs/superpowers/plans/2026-07-22-task-1899-reconcile-report-only.md +0 -748
- package/payload/platform/docs/superpowers/plans/2026-07-22-task-1910-two-way-portal-exchange.md +0 -1716
- package/payload/platform/docs/superpowers/plans/2026-07-23-task-1930-adherence-enforcement.md +0 -422
- package/payload/platform/docs/superpowers/plans/2026-07-24-task-1942-subaccount-switcher-brand-head.md +0 -327
- package/payload/platform/docs/superpowers/plans/2026-07-25-task-1974-uploads-intake-inbox.md +0 -235
- package/payload/platform/docs/superpowers/plans/2026-07-25-task-1976-intra-folder-hygiene.md +0 -215
- package/payload/platform/docs/superpowers/plans/2026-07-26-task-1902-account-owned-entry-declarations.md +0 -555
- package/payload/platform/docs/superpowers/plans/2026-07-26-task-1926-portal-push-concurrency-guard.md +0 -482
- package/payload/platform/docs/superpowers/plans/2026-07-26-task-2023-sidebar-sessions-async-reads.md +0 -394
- package/payload/platform/docs/superpowers/plans/2026-07-27-task-2016-disabled-agent-routing.md +0 -624
- package/payload/platform/docs/superpowers/plans/2026-07-27-task-2028-declared-file-write-deny.md +0 -303
- package/payload/platform/docs/superpowers/plans/2026-07-27-task-2052-account-machinery-write-fence.md +0 -250
- package/payload/platform/docs/superpowers/plans/2026-07-28-task-2097-email-signature-set.md +0 -65
- package/payload/platform/docs/superpowers/specs/2026-06-02-task-610-follower-202-retry-design.md +0 -116
- package/payload/platform/docs/superpowers/specs/2026-06-23-account-filesystem-schema-design.md +0 -170
- package/payload/platform/docs/superpowers/specs/2026-07-11-task-1557-operator-on-behalf-preference-attribution-design.md +0 -90
- package/payload/platform/docs/superpowers/specs/2026-07-13-account-schema-ontology-projection-design.md +0 -178
- package/payload/platform/docs/superpowers/specs/2026-07-14-graph-top-level-labels-ontology-single-source-design.md +0 -119
- package/payload/platform/docs/superpowers/specs/2026-07-17-task-1736-retire-mcp-stderr-tee-design.md +0 -128
- package/payload/platform/docs/superpowers/specs/2026-07-18-graph-native-ledger-design.md +0 -241
- package/payload/platform/docs/superpowers/specs/2026-07-20-task-1704-data-portal-standing-audit-design.md +0 -177
- package/payload/platform/docs/superpowers/specs/2026-07-20-task-1789-reseat-channel-row-fork-design.md +0 -201
- package/payload/platform/docs/superpowers/specs/2026-07-20-task-1818-loop-gate-app-routes-design.md +0 -217
- package/payload/platform/docs/superpowers/specs/2026-07-20-task-1819-top-level-label-allowlist-design.md +0 -80
- package/payload/platform/docs/superpowers/specs/2026-07-20-task-1820-cpu-triage-admin-tools-design.md +0 -97
- package/payload/platform/docs/superpowers/specs/2026-07-20-task-1829-platform-ui-typecheck-design.md +0 -163
- package/payload/platform/docs/superpowers/specs/2026-07-20-task-1831-data-portal-class-derived-allowlist-design.md +0 -163
- package/payload/platform/docs/superpowers/specs/2026-07-22-task-1899-reconcile-report-only-design.md +0 -121
- package/payload/platform/docs/superpowers/specs/2026-07-22-task-1910-two-way-portal-exchange-design.md +0 -103
- package/payload/platform/docs/superpowers/specs/2026-07-23-task-1930-adherence-enforcement-design.md +0 -81
- package/payload/platform/docs/superpowers/specs/2026-07-24-task-1942-subaccount-switcher-brand-head-design.md +0 -35
- package/payload/platform/docs/superpowers/specs/2026-07-26-task-1902-account-owned-entry-declarations-design.md +0 -232
- package/payload/platform/docs/superpowers/specs/2026-07-26-task-1926-portal-push-concurrency-guard-design.md +0 -200
- package/payload/platform/docs/superpowers/specs/2026-07-26-task-2014-ui-suite-nondeterminism-design.md +0 -169
- package/payload/platform/docs/superpowers/specs/2026-07-27-task-2016-disabled-agent-routing-design.md +0 -139
- package/payload/platform/docs/superpowers/specs/2026-07-27-task-2028-declared-file-write-deny-design.md +0 -127
- package/payload/platform/docs/superpowers/specs/2026-07-27-task-2052-account-machinery-write-fence-design.md +0 -150
- package/payload/platform/docs/superpowers/specs/2026-07-28-task-2097-email-signature-set-design.md +0 -155
|
@@ -3,6 +3,7 @@ import { embed } from "../lib/embeddings.js";
|
|
|
3
3
|
import { buildTextRepresentation } from "./memory-write.js";
|
|
4
4
|
import { checkGraphWriteGate, checkLabelWriteGate, checkPropertyWriteGate, } from "../lib/graph-write-gate.js";
|
|
5
5
|
import { withWriteEvent, pickName } from "../lib/log-ingest.js";
|
|
6
|
+
import { compileTypePreservingSet, typePreserveRejection, } from "../lib/temporal-type-preserve.js";
|
|
6
7
|
import { REVISION_CYPHER_FRAGMENT_UNWIND, } from "../lib/compiled-truth-revision.js";
|
|
7
8
|
/** Stripped silently — operator can't update these via the agent. */
|
|
8
9
|
const RESTRICTED_KEYS = new Set(["embedding", "accountId", "createdAt", "createdOn"]);
|
|
@@ -24,6 +25,35 @@ const SYSTEM_MANAGED_KEYS = new Set([
|
|
|
24
25
|
function isCompiledTruthRewriter() {
|
|
25
26
|
return process.env.MAXY_SPECIALIST === "compiled-truth-rewriter";
|
|
26
27
|
}
|
|
28
|
+
/** The write-time stamp. It is type-preserved like any other property: nodes
|
|
29
|
+
* written by `memory-write` hold it as an ISO string, :Meeting nodes hold it as
|
|
30
|
+
* a ZONED DATETIME, and this tool must not convert either into the other. */
|
|
31
|
+
const UPDATED_AT_KEY = "updatedAt";
|
|
32
|
+
/**
|
|
33
|
+
* Vet each temporal value with Neo4j's own constructor before the update runs.
|
|
34
|
+
* A probe is a read — nothing is written — so a refusal here leaves every
|
|
35
|
+
* property, including the ones that would have succeeded, untouched.
|
|
36
|
+
*/
|
|
37
|
+
async function probeTemporalValues(session, probes) {
|
|
38
|
+
for (const probe of probes) {
|
|
39
|
+
try {
|
|
40
|
+
await session.run(`RETURN ${probe.constructorName}($${probe.paramName}) AS probe`, {
|
|
41
|
+
[probe.paramName]: probe.value,
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
catch (err) {
|
|
45
|
+
// Only a client error is a verdict on the value. A disconnect, an auth
|
|
46
|
+
// failure or a timeout says nothing about it, and reporting one as
|
|
47
|
+
// "not a valid ZONED DATETIME" would send the agent to reword a
|
|
48
|
+
// timestamp that was correct all along. Those propagate unchanged.
|
|
49
|
+
const code = err?.code;
|
|
50
|
+
if (typeof code === "string" && code.startsWith("Neo.ClientError.")) {
|
|
51
|
+
throw typePreserveRejection(probe.key, probe.existingType, probe.value);
|
|
52
|
+
}
|
|
53
|
+
throw err;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
27
57
|
export async function memoryUpdate(params) {
|
|
28
58
|
const nameHint = pickName(params.properties);
|
|
29
59
|
return withWriteEvent({ tool: "memory-update", accountId: params.accountId, name: nameHint }, () => memoryUpdateImpl(params), (r) => ({ elementId: r.nodeId, labels: r.labels, name: nameHint }));
|
|
@@ -60,15 +90,57 @@ async function memoryUpdateImpl(params) {
|
|
|
60
90
|
if (Object.keys(safeProps).length === 0) {
|
|
61
91
|
throw new Error("All provided properties are restricted and cannot be updated.");
|
|
62
92
|
}
|
|
93
|
+
// When the compiled-truth-rewriter specialist writes a compiledTruth /
|
|
94
|
+
// compiledTruthPublic field, stamp the matching *UpdatedAt + *Source values
|
|
95
|
+
// automatically so the audit trail stays consistent — the specialist
|
|
96
|
+
// shouldn't have to remember the housekeeping fields.
|
|
97
|
+
//
|
|
98
|
+
// Task 2148 — built before the session opens, because the pre-read has to ask
|
|
99
|
+
// for the existing type of every key that will actually be written, and the
|
|
100
|
+
// rewriter's housekeeping keys are part of that set.
|
|
101
|
+
const stamped = { ...safeProps };
|
|
102
|
+
const revisionRows = [];
|
|
103
|
+
if (rewriterCaller) {
|
|
104
|
+
const now = new Date().toISOString();
|
|
105
|
+
if ("compiledTruth" in stamped) {
|
|
106
|
+
stamped.compiledTruthUpdatedAt = now;
|
|
107
|
+
if (!("compiledTruthSource" in stamped))
|
|
108
|
+
stamped.compiledTruthSource = "rewriter";
|
|
109
|
+
revisionRows.push({
|
|
110
|
+
truth: String(stamped.compiledTruth ?? ""),
|
|
111
|
+
twin: "compiledTruth",
|
|
112
|
+
source: stamped.compiledTruthSource === "operator" ? "operator" : "rewriter",
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
if ("compiledTruthPublic" in stamped) {
|
|
116
|
+
stamped.compiledTruthPublicUpdatedAt = now;
|
|
117
|
+
if (!("compiledTruthPublicSource" in stamped))
|
|
118
|
+
stamped.compiledTruthPublicSource = "rewriter";
|
|
119
|
+
revisionRows.push({
|
|
120
|
+
truth: String(stamped.compiledTruthPublic ?? ""),
|
|
121
|
+
twin: "compiledTruthPublic",
|
|
122
|
+
source: stamped.compiledTruthPublicSource === "operator" ? "operator" : "rewriter",
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
const propKeys = [...Object.keys(stamped), UPDATED_AT_KEY];
|
|
63
127
|
const session = getSession();
|
|
64
128
|
try {
|
|
129
|
+
// Task 2148 — `propTypes` is the node's own `valueType()` per incoming key.
|
|
130
|
+
// Without it the SET below has no way to tell a ZONED DATETIME `startsAt`
|
|
131
|
+
// from a STRING `title`, and `n += $props` retypes the former to the latter.
|
|
65
132
|
const labelResult = await session.run(`MATCH (n) WHERE elementId(n) = $nodeId AND n.accountId = $accountId
|
|
66
|
-
RETURN labels(n) AS nodeLabels, n.name AS name, n.sliceToken AS sliceToken
|
|
133
|
+
RETURN labels(n) AS nodeLabels, n.name AS name, n.sliceToken AS sliceToken,
|
|
134
|
+
[k IN $propKeys WHERE n[k] IS NOT NULL | [k, valueType(n[k])]] AS propTypes`, { nodeId, accountId, propKeys });
|
|
67
135
|
if (labelResult.records.length === 0) {
|
|
68
136
|
throw new Error(`Node not found or not owned by this account (ID: ${nodeId}).`);
|
|
69
137
|
}
|
|
70
138
|
const targetLabels = labelResult.records[0].get("nodeLabels");
|
|
71
139
|
const targetSliceToken = labelResult.records[0].get("sliceToken");
|
|
140
|
+
const existingTypes = {};
|
|
141
|
+
for (const pair of (labelResult.records[0].get("propTypes") ?? [])) {
|
|
142
|
+
existingTypes[pair[0]] = pair[1];
|
|
143
|
+
}
|
|
72
144
|
// Task 485 — when the caller runs under a reviewer dispatch, refuse any
|
|
73
145
|
// update whose target sliceToken does not match the env var. The check
|
|
74
146
|
// is loud (throws) and logs every refusal — every occurrence is a
|
|
@@ -106,35 +178,6 @@ async function memoryUpdateImpl(params) {
|
|
|
106
178
|
if (!gate.ok) {
|
|
107
179
|
throw new Error(`Update blocked (${gate.reason}): ${gate.message}`);
|
|
108
180
|
}
|
|
109
|
-
// When the compiled-truth-rewriter specialist writes a compiledTruth /
|
|
110
|
-
// compiledTruthPublic field, stamp the matching *UpdatedAt + *Source values
|
|
111
|
-
// automatically so the audit trail stays consistent — the specialist
|
|
112
|
-
// shouldn't have to remember the housekeeping fields.
|
|
113
|
-
const stamped = { ...safeProps };
|
|
114
|
-
const revisionRows = [];
|
|
115
|
-
if (rewriterCaller) {
|
|
116
|
-
const now = new Date().toISOString();
|
|
117
|
-
if ("compiledTruth" in stamped) {
|
|
118
|
-
stamped.compiledTruthUpdatedAt = now;
|
|
119
|
-
if (!("compiledTruthSource" in stamped))
|
|
120
|
-
stamped.compiledTruthSource = "rewriter";
|
|
121
|
-
revisionRows.push({
|
|
122
|
-
truth: String(stamped.compiledTruth ?? ""),
|
|
123
|
-
twin: "compiledTruth",
|
|
124
|
-
source: stamped.compiledTruthSource === "operator" ? "operator" : "rewriter",
|
|
125
|
-
});
|
|
126
|
-
}
|
|
127
|
-
if ("compiledTruthPublic" in stamped) {
|
|
128
|
-
stamped.compiledTruthPublicUpdatedAt = now;
|
|
129
|
-
if (!("compiledTruthPublicSource" in stamped))
|
|
130
|
-
stamped.compiledTruthPublicSource = "rewriter";
|
|
131
|
-
revisionRows.push({
|
|
132
|
-
truth: String(stamped.compiledTruthPublic ?? ""),
|
|
133
|
-
twin: "compiledTruthPublic",
|
|
134
|
-
source: stamped.compiledTruthPublicSource === "operator" ? "operator" : "rewriter",
|
|
135
|
-
});
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
181
|
// Task 436: when the rewriter writes a twin, the `:CompiledTruthRevision`
|
|
139
182
|
// CREATE rides in the same `session.run` as the live SET so revision
|
|
140
183
|
// history can never desync from the live property. UNWIND-on-empty is a
|
|
@@ -147,19 +190,32 @@ async function memoryUpdateImpl(params) {
|
|
|
147
190
|
WITH DISTINCT n
|
|
148
191
|
`
|
|
149
192
|
: "";
|
|
193
|
+
// Task 2148 — the SET clause is compiled against the node's own property
|
|
194
|
+
// types, so a temporal property is rebuilt with its constructor rather than
|
|
195
|
+
// overwritten verbatim by `n += $props`.
|
|
196
|
+
const compiled = compileTypePreservingSet({
|
|
197
|
+
alias: "n",
|
|
198
|
+
existingTypes,
|
|
199
|
+
props: stamped,
|
|
200
|
+
now: { key: UPDATED_AT_KEY, isoValue: new Date().toISOString() },
|
|
201
|
+
});
|
|
202
|
+
// Every temporal value is vetted by Neo4j's own parser first. Validating
|
|
203
|
+
// here rather than reimplementing Neo4j's temporal grammar in JS keeps this
|
|
204
|
+
// from being stricter than the database and rejecting values it accepts,
|
|
205
|
+
// and running it before the SET is what makes a refusal all-or-nothing.
|
|
206
|
+
await probeTemporalValues(session, compiled.probes);
|
|
150
207
|
const updateQuery = `
|
|
151
208
|
MATCH (n)
|
|
152
209
|
WHERE elementId(n) = $nodeId AND n.accountId = $accountId
|
|
153
|
-
SET
|
|
210
|
+
SET ${compiled.setClause}
|
|
154
211
|
${revisionClause}
|
|
155
212
|
RETURN elementId(n) AS nodeId, labels(n) AS nodeLabels, properties(n) AS allProps
|
|
156
213
|
`;
|
|
157
214
|
const result = await session.run(updateQuery, {
|
|
158
215
|
nodeId,
|
|
159
216
|
accountId,
|
|
160
|
-
updatedAt: new Date().toISOString(),
|
|
161
|
-
props: stamped,
|
|
162
217
|
revisions: revisionRows,
|
|
218
|
+
...compiled.params,
|
|
163
219
|
});
|
|
164
220
|
if (result.records.length === 0) {
|
|
165
221
|
throw new Error(`Node not found or not owned by this account (ID: ${nodeId}).`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"memory-update.js","sourceRoot":"","sources":["../../src/tools/memory-update.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,KAAK,EAAE,MAAM,sBAAsB,CAAC;AAC7C,OAAO,EAAE,uBAAuB,EAAE,MAAM,mBAAmB,CAAC;AAC5D,OAAO,EACL,mBAAmB,EACnB,mBAAmB,EACnB,sBAAsB,GACvB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAChE,OAAO,EACL,+BAA+B,GAGhC,MAAM,mCAAmC,CAAC;AAiB3C,qEAAqE;AACrE,MAAM,eAAe,GAAG,IAAI,GAAG,CAAC,CAAC,WAAW,EAAE,WAAW,EAAE,WAAW,EAAE,WAAW,CAAC,CAAC,CAAC;AAEtF;;;;;;GAMG;AACH,MAAM,mBAAmB,GAAG,IAAI,GAAG,CAAC;IAClC,eAAe;IACf,wBAAwB;IACxB,qBAAqB;IACrB,qBAAqB;IACrB,8BAA8B;IAC9B,2BAA2B;CAC5B,CAAC,CAAC;AAEH,SAAS,uBAAuB;IAC9B,OAAO,OAAO,CAAC,GAAG,CAAC,eAAe,KAAK,yBAAyB,CAAC;AACnE,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,MAAoB;IACrD,MAAM,QAAQ,GAAG,QAAQ,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;IAC7C,OAAO,cAAc,CACnB,EAAE,IAAI,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,CAAC,SAAS,EAAE,IAAI,EAAE,QAAQ,EAAE,EACtE,GAAG,EAAE,CAAC,gBAAgB,CAAC,MAAM,CAAC,EAC9B,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CACnE,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,gBAAgB,CAAC,MAAoB;IAClD,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,GAAG,MAAM,CAAC;IAEjD,kFAAkF;IAClF,gFAAgF;IAChF,qDAAqD;IACrD,MAAM,cAAc,GAAG,uBAAuB,EAAE,CAAC;IACjD,IAAI,CAAC,cAAc,EAAE,CAAC;QACpB,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC;YAC1C,IAAI,mBAAmB,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;gBACjC,MAAM,IAAI,KAAK,CACb,yCAAyC,GAAG,0CAA0C;oBACpF,qGAAqG,CACxG,CAAC;YACJ,CAAC;QACH,CAAC;IACH,CAAC;IAED,IAAI,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACzC,MAAM,IAAI,KAAK,CAAC,0DAA0D,CAAC,CAAC;IAC9E,CAAC;IAED,4EAA4E;IAC5E,8DAA8D;IAC9D,MAAM,QAAQ,GAAG,sBAAsB,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC;IACxD,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QACjB,MAAM,IAAI,KAAK,CAAC,mBAAmB,QAAQ,CAAC,MAAM,MAAM,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC;IAC9E,CAAC;IAED,mEAAmE;IACnE,MAAM,SAAS,GAA4B,EAAE,CAAC;IAC9C,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC;QACtD,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,GAAG,CAAC;YAAE,SAAS,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;IACxD,CAAC;IAED,IAAI,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACxC,MAAM,IAAI,KAAK,CAAC,+DAA+D,CAAC,CAAC;IACnF,CAAC;IAED,MAAM,OAAO,GAAG,UAAU,EAAE,CAAC;IAE7B,IAAI,CAAC;QACH,MAAM,WAAW,GAAG,MAAM,OAAO,CAAC,GAAG,CACnC
|
|
1
|
+
{"version":3,"file":"memory-update.js","sourceRoot":"","sources":["../../src/tools/memory-update.ts"],"names":[],"mappings":"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"}
|
|
@@ -49,6 +49,8 @@ export default defineConfig({
|
|
|
49
49
|
"src/lib/__tests__/compiled-truth-revision.test.ts",
|
|
50
50
|
// Vertical relationship-pattern projector + warn-only edge check.
|
|
51
51
|
"src/lib/__tests__/relationship-patterns.test.ts",
|
|
52
|
+
// Task 2148 — type-preserving SET compiler for memory-update.
|
|
53
|
+
"src/lib/__tests__/temporal-type-preserve.test.ts",
|
|
52
54
|
// Task 1944 — scheduled dream-cycle sweep throttle policy (vitest).
|
|
53
55
|
"src/scripts/__tests__/**/*.test.ts",
|
|
54
56
|
],
|
|
@@ -276,6 +276,12 @@ Env: `PLATFORM_ROOT`, `NEO4J_URI` (and `NEO4J_PASSWORD` or `config/.neo4j-passwo
|
|
|
276
276
|
|
|
277
277
|
Observability: one `[calendar-booking]` line per step keyed by `bookingId` (`reconcile-claim`, `meeting-write`, `notify`, `booked`), and one `[calendar-reconcile] account=… eligibleExamined=… pendingUnreconciled=… pendingOldestAgeMin=… orphanMeetings=…` audit line per account per run. `eligibleExamined` separates "nothing to do" from "verified clean". A `pendingUnreconciled` that persists across runs means those rows are failing to become meetings rather than merely lagging — the `attempt=` count on the claim and failure lines says how many times each has been tried. `orphanMeetings` means a booking meeting has no backing eligible D1 row. `pendingOldestAgeMin` ages that backlog: a count cannot separate a short lag from a nine-hour one. The companion `[calendar-reconcile] op=liveness lastRunAgeMin=… lastAuditAgeMin=… lastSkipReason=… stale=<bool>` line is emitted every ten minutes by the platform/ui server rather than by this script, because the failure it detects is this script not reporting at all. `op=liveness-write-failed` is the one case where that record could not be written; it carries the error body and never stops the run, because a run that worked must not be reported as failed for losing its own bookkeeping.
|
|
278
278
|
|
|
279
|
+
Two further lines print per account on every tick whether or not anything is wrong. `[calendar-availability] op=meeting-retype account=… scanned=… repaired=… unparseable=… failed=…` is the timestamp type census: it matches `:Meeting` rows whose `startsAt` or `endsAt` is stored as a `STRING` and rebuilds each with `datetime()`. It answers "is anything in this calendar stored with the wrong type right now?" without reproducing the failure and without waiting for a customer to hit a bad slot. A repaired row stops matching, so a steady install reads `scanned=0 repaired=0` and this stays a standing repair rather than a migration to remove. A non-zero `repaired` on a steady install means something is still writing strings and names the account. The two failure counts are deliberately separate: `unparseable` is a value Neo4j's own parser rejects and needs a human, while `failed` is the write not landing (a timeout, a disconnect) and retries on the next tick. Neo4j's error code decides which, so a transient fault is never reported as a corrupt value. No JS pre-check stands in for that parser — `Date.parse` rejects the zone-id form `2026-07-29T13:30:00[Europe/London]` that `datetime()` accepts, and would report a repairable row as needing a human.
|
|
280
|
+
|
|
281
|
+
`[calendar-availability] op=cal-drift account=… outcome=… published=… busyMeetings=… busyConnector=… busyUnusable=… conflicts=…` re-reads what was published and reconciles it against both labels the public free/busy page subtracts, `:Meeting` and `:ConnectorBusy`. It read `:ConnectorBusy` alone before this, so any meeting conflict was outside what it could measure, and it reported `outcome=verified conflicts=0` throughout an incident where five meetings were invisible. The census is split into named counts because one total cannot distinguish "3 connector intervals, no meetings" from "3 meetings, no connector" — the exact ambiguity that made `busy=3 conflicts=0` read as healthy. A meeting with no `endsAt` (nullable by schema) is given `start + durationMins`, the same substitution the free/busy route makes, rather than dropped; `busyUnusable` counts the rows that had no resolvable bound even so, because an interval excluded without a count is the silent drop this whole signal exists to remove. Read together the two lines discriminate three states: a conflict with `repaired=0` is a slot-math or publish fault, a conflict alongside `repaired>0` is corruption caught mid-repair, and `conflicts=0` with `busyMeetings>0` is evidence the meeting path was checked at all.
|
|
282
|
+
|
|
283
|
+
The **audit** widened; what the **blocking** step acts on did not. `planBlockWrites` still reads `:ConnectorBusy` alone, because its empty-set rule is a liveness test for the connector sync: a set padded with meetings would report a deauthorised connector as healthy on any account that has ever taken a booking, and every held `kind='block'` row would be deleted, putting genuinely busy times back on sale.
|
|
284
|
+
|
|
279
285
|
## Ingesting calendar archives (.ics → graph)
|
|
280
286
|
|
|
281
287
|
`schedule-archive-ics` is the bulk-ingest path: it reads an `.ics` export from any calendar app (Google, Apple, Outlook, Fastmail, etc.) and writes one `:Meeting` per VEVENT into the graph, with attendees resolved to `:Person` by lowercased email. Distinct from `schedule-import-ics`, which only parses + returns events for the operator to recreate via `schedule-event` one at a time.
|
package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/meeting-retype.test.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"meeting-retype.test.d.ts","sourceRoot":"","sources":["../../../src/lib/__tests__/meeting-retype.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
// Task 2148 — two halves of the same blindness.
|
|
2
|
+
//
|
|
3
|
+
// `memory-update` retyped five :Meeting timestamps to strings on one account.
|
|
4
|
+
// A STRING-to-DATETIME comparison in Neo4j is NULL, so every calendar reader
|
|
5
|
+
// dropped those rows silently and the booking page published a golf afternoon
|
|
6
|
+
// as open time. The standing drift audit that exists to catch exactly that read
|
|
7
|
+
// `MATCH (b:ConnectorBusy ...)` and nothing else, so it reported
|
|
8
|
+
// `busy=3 conflicts=0 outcome=verified` throughout — an all-clear that was
|
|
9
|
+
// structurally incapable of seeing a meeting.
|
|
10
|
+
//
|
|
11
|
+
// `classifyMeetingRetype` decides which corrupted rows the standing repair can
|
|
12
|
+
// restore. `censusBusyIntervals` splits the busy census by source, so one total
|
|
13
|
+
// can no longer read as healthy when the meeting leg is empty.
|
|
14
|
+
import { describe, it, expect } from "vitest";
|
|
15
|
+
import { classifyRetypeError, censusBusyIntervals, classifyPublishedDrift, planBlockWrites, MEETING_RETYPE_SELECT, MEETING_RETYPE_APPLY, BUSY_UNION_SELECT, } from "../booking-reconcile.js";
|
|
16
|
+
describe("classifyRetypeError", () => {
|
|
17
|
+
it("calls a Neo4j client error a verdict on the value", () => {
|
|
18
|
+
const err = Object.assign(new Error("Text cannot be parsed to a DateTime"), {
|
|
19
|
+
code: "Neo.ClientError.Statement.ArgumentError",
|
|
20
|
+
});
|
|
21
|
+
expect(classifyRetypeError(err)).toBe("unparseable");
|
|
22
|
+
});
|
|
23
|
+
it("calls anything else a failed write, not a bad value", () => {
|
|
24
|
+
// A timeout says nothing about the timestamp. Counting it as unparseable
|
|
25
|
+
// would tell the operator a row needs a human when it needs a retry.
|
|
26
|
+
const transient = Object.assign(new Error("Connection was closed"), {
|
|
27
|
+
code: "Neo.TransientError.General.DatabaseUnavailable",
|
|
28
|
+
});
|
|
29
|
+
expect(classifyRetypeError(transient)).toBe("failed");
|
|
30
|
+
expect(classifyRetypeError(new Error("socket hang up"))).toBe("failed");
|
|
31
|
+
expect(classifyRetypeError(null)).toBe("failed");
|
|
32
|
+
});
|
|
33
|
+
});
|
|
34
|
+
describe("the retype Cypher", () => {
|
|
35
|
+
it("selects only meetings whose bounds are stored as strings", () => {
|
|
36
|
+
// A repaired row stops matching, which is what keeps this a standing repair
|
|
37
|
+
// rather than a migration someone has to remember to delete.
|
|
38
|
+
expect(MEETING_RETYPE_SELECT).toContain("MATCH (m:Meeting {accountId: $accountId})");
|
|
39
|
+
expect(MEETING_RETYPE_SELECT).toContain("valueType(m.startsAt) STARTS WITH 'STRING'");
|
|
40
|
+
expect(MEETING_RETYPE_SELECT).toContain("valueType(m.endsAt) STARTS WITH 'STRING'");
|
|
41
|
+
});
|
|
42
|
+
it("rebuilds each string bound with datetime() and leaves a null bound alone", () => {
|
|
43
|
+
expect(MEETING_RETYPE_APPLY).toContain("datetime($startsAt)");
|
|
44
|
+
expect(MEETING_RETYPE_APPLY).toContain("datetime($endsAt)");
|
|
45
|
+
expect(MEETING_RETYPE_APPLY).toContain("$startsAt IS NULL");
|
|
46
|
+
expect(MEETING_RETYPE_APPLY).toContain("$endsAt IS NULL");
|
|
47
|
+
});
|
|
48
|
+
it("re-asserts the label and account on the write, not just on the select", () => {
|
|
49
|
+
// Account scope is a property; a write carrying none cannot enforce it.
|
|
50
|
+
expect(MEETING_RETYPE_APPLY).toContain("MATCH (m:Meeting {accountId: $accountId})");
|
|
51
|
+
});
|
|
52
|
+
});
|
|
53
|
+
describe("censusBusyIntervals", () => {
|
|
54
|
+
const meeting = (start, end) => ({ start, end, src: "meeting" });
|
|
55
|
+
const connector = (start, end) => ({ start, end, src: "connector" });
|
|
56
|
+
it("splits the census by source so one total cannot hide an empty meeting leg", () => {
|
|
57
|
+
const census = censusBusyIntervals([
|
|
58
|
+
meeting("2026-07-29T13:30:00Z", "2026-07-29T17:30:00Z"),
|
|
59
|
+
connector("2026-07-30T09:00:00Z", "2026-07-30T10:00:00Z"),
|
|
60
|
+
connector("2026-07-31T09:00:00Z", "2026-07-31T10:00:00Z"),
|
|
61
|
+
]);
|
|
62
|
+
expect(census.busyMeetings).toBe(1);
|
|
63
|
+
expect(census.busyConnector).toBe(2);
|
|
64
|
+
expect(census.unusable).toBe(0);
|
|
65
|
+
expect(census.usable).toHaveLength(3);
|
|
66
|
+
});
|
|
67
|
+
it("distinguishes three connector intervals from three meetings", () => {
|
|
68
|
+
// `busy=3` could mean either, which is exactly why the old line read as
|
|
69
|
+
// healthy while five meetings were invisible.
|
|
70
|
+
const connectorsOnly = censusBusyIntervals([
|
|
71
|
+
connector("2026-07-29T09:00:00Z", "2026-07-29T10:00:00Z"),
|
|
72
|
+
connector("2026-07-29T11:00:00Z", "2026-07-29T12:00:00Z"),
|
|
73
|
+
connector("2026-07-29T13:00:00Z", "2026-07-29T14:00:00Z"),
|
|
74
|
+
]);
|
|
75
|
+
expect(connectorsOnly.busyMeetings).toBe(0);
|
|
76
|
+
expect(connectorsOnly.busyConnector).toBe(3);
|
|
77
|
+
});
|
|
78
|
+
it("excludes a row with an unparseable start and counts it", () => {
|
|
79
|
+
const census = censusBusyIntervals([
|
|
80
|
+
meeting("not-a-time", "2026-07-29T17:30:00Z"),
|
|
81
|
+
meeting("2026-07-29T13:30:00Z", "2026-07-29T17:30:00Z"),
|
|
82
|
+
]);
|
|
83
|
+
expect(census.usable).toEqual([
|
|
84
|
+
{ start: "2026-07-29T13:30:00Z", end: "2026-07-29T17:30:00Z" },
|
|
85
|
+
]);
|
|
86
|
+
expect(census.busyMeetings).toBe(1);
|
|
87
|
+
expect(census.unusable).toBe(1);
|
|
88
|
+
});
|
|
89
|
+
it("gives a meeting with no end the same end the public page gives it", () => {
|
|
90
|
+
// `:Meeting.endsAt` is nullable by schema and the free/busy route substitutes
|
|
91
|
+
// start + durationMins. Dropping the row instead would make a real conflict
|
|
92
|
+
// unreportable — this task's own failure shape.
|
|
93
|
+
const census = censusBusyIntervals([{ start: "2026-07-29T13:30:00Z", end: null, src: "meeting" }], 30);
|
|
94
|
+
expect(census.usable).toEqual([
|
|
95
|
+
{ start: "2026-07-29T13:30:00Z", end: "2026-07-29T14:00:00.000Z" },
|
|
96
|
+
]);
|
|
97
|
+
expect(census.busyMeetings).toBe(1);
|
|
98
|
+
expect(census.unusable).toBe(0);
|
|
99
|
+
});
|
|
100
|
+
it("counts a no-end meeting as unusable only when no duration is configured", () => {
|
|
101
|
+
const census = censusBusyIntervals([{ start: "2026-07-29T13:30:00Z", end: null, src: "meeting" }]);
|
|
102
|
+
expect(census.usable).toEqual([]);
|
|
103
|
+
expect(census.unusable).toBe(1);
|
|
104
|
+
});
|
|
105
|
+
it("reads UNION ALL so two meetings sharing bounds are counted twice", () => {
|
|
106
|
+
// Plain UNION de-duplicates the whole result, so a double booking or a
|
|
107
|
+
// re-ingested export would collapse and the census would undercount.
|
|
108
|
+
expect(BUSY_UNION_SELECT).toContain("UNION ALL");
|
|
109
|
+
});
|
|
110
|
+
it("keeps the connector leg separate, because block-writing depends on it alone", () => {
|
|
111
|
+
// planBlockWrites treats a non-empty busy set as proof the connector sync is
|
|
112
|
+
// alive. Handed the widened set, a deauthorised connector on an account with
|
|
113
|
+
// any meeting reads as healthy and every held block row is deleted.
|
|
114
|
+
const census = censusBusyIntervals([
|
|
115
|
+
meeting("2026-07-29T13:30:00Z", "2026-07-29T17:30:00Z"),
|
|
116
|
+
]);
|
|
117
|
+
expect(census.connectorOnly).toEqual([]);
|
|
118
|
+
expect(census.usable).toHaveLength(1);
|
|
119
|
+
const plan = planBlockWrites({
|
|
120
|
+
publishedReadable: true,
|
|
121
|
+
busyReadable: true,
|
|
122
|
+
published: [{ start: "2026-07-29T14:00:00Z", end: "2026-07-29T14:30:00Z" }],
|
|
123
|
+
busy: census.connectorOnly,
|
|
124
|
+
taken: new Set(),
|
|
125
|
+
current: [{ bookingId: "blk-1", slotStart: "2026-07-29T14:00:00Z" }],
|
|
126
|
+
nowMs: Date.parse("2026-07-29T09:00:00Z"),
|
|
127
|
+
});
|
|
128
|
+
expect(plan.outcome).toBe("no-busy-data");
|
|
129
|
+
expect(plan.diff).toEqual({ toInsert: [], toDelete: [] });
|
|
130
|
+
});
|
|
131
|
+
it("makes a meeting-only conflict visible to the unchanged classifier", () => {
|
|
132
|
+
// The reported symptom, reduced: Adam's golf afternoon is a :Meeting with no
|
|
133
|
+
// :ConnectorBusy row, and the page published a slot inside it. Against the
|
|
134
|
+
// ConnectorBusy-only read the busy list was empty and conflicts was 0.
|
|
135
|
+
const published = [{ start: "2026-07-29T14:00:00Z", end: "2026-07-29T14:30:00Z" }];
|
|
136
|
+
const census = censusBusyIntervals([meeting("2026-07-29T13:30:00Z", "2026-07-29T17:30:00Z")]);
|
|
137
|
+
expect(classifyPublishedDrift(published, census.usable).conflicts).toBe(1);
|
|
138
|
+
expect(classifyPublishedDrift(published, []).conflicts).toBe(0);
|
|
139
|
+
});
|
|
140
|
+
it("reads both labels in one statement, tagged by source", () => {
|
|
141
|
+
expect(BUSY_UNION_SELECT).toContain("MATCH (m:Meeting {accountId: $accountId})");
|
|
142
|
+
expect(BUSY_UNION_SELECT).toContain("MATCH (b:ConnectorBusy {accountId: $accountId})");
|
|
143
|
+
expect(BUSY_UNION_SELECT).toContain("UNION");
|
|
144
|
+
expect(BUSY_UNION_SELECT).toContain("'meeting' AS src");
|
|
145
|
+
expect(BUSY_UNION_SELECT).toContain("'connector' AS src");
|
|
146
|
+
});
|
|
147
|
+
});
|
|
148
|
+
//# sourceMappingURL=meeting-retype.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"meeting-retype.test.js","sourceRoot":"","sources":["../../../src/lib/__tests__/meeting-retype.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -140,20 +140,97 @@ export interface PublishedDrift {
|
|
|
140
140
|
outcome: PublishedDriftOutcome;
|
|
141
141
|
/** Size of the published-open set the comparison ran against. */
|
|
142
142
|
published: number;
|
|
143
|
-
/** Size of the
|
|
143
|
+
/** Size of the busy set the comparison ran against, both labels together.
|
|
144
|
+
* Task 2148 split the reported census into `busyMeetings` / `busyConnector`
|
|
145
|
+
* at the call site: one total cannot distinguish "3 connector intervals, no
|
|
146
|
+
* meetings" from "3 meetings, no connector", and that ambiguity is what made
|
|
147
|
+
* `busy=3 conflicts=0` read as healthy while five meetings were invisible. */
|
|
144
148
|
busy: number;
|
|
145
149
|
/** Published-open slots overlapping any busy interval. Necessarily 0 on the
|
|
146
150
|
* two degraded outcomes, which is why the outcome token has to be read. */
|
|
147
151
|
conflicts: number;
|
|
148
152
|
}
|
|
149
153
|
/**
|
|
150
|
-
* Classify published-open booking slots against the
|
|
151
|
-
*
|
|
152
|
-
* `
|
|
153
|
-
*
|
|
154
|
-
*
|
|
154
|
+
* Classify published-open booking slots against the busy set — the drift the
|
|
155
|
+
* standing audit reports. The busy set is both labels the public free/busy page
|
|
156
|
+
* subtracts, `:Meeting` and `:ConnectorBusy`, so `outcome: "verified"` with a
|
|
157
|
+
* nonzero `conflicts` means the booking page is currently offering a slot that
|
|
158
|
+
* is genuinely taken, whether by a meeting or by a connector block. An empty
|
|
159
|
+
* published set reports `no-published-slots` even when the busy set is also
|
|
160
|
+
* empty: the site never publishing is the upstream condition. `no-busy-data`
|
|
161
|
+
* now means neither label held a usable interval.
|
|
155
162
|
*/
|
|
156
163
|
export declare function classifyPublishedDrift(published: BusyInterval[], busy: BusyInterval[]): PublishedDrift;
|
|
164
|
+
/** A `:Meeting` with at least one string-typed bound. A null member means that
|
|
165
|
+
* bound already carries a temporal type and must be left alone. */
|
|
166
|
+
export interface MeetingRetypeRow {
|
|
167
|
+
meetingId: string;
|
|
168
|
+
startsAt: string | null;
|
|
169
|
+
endsAt: string | null;
|
|
170
|
+
}
|
|
171
|
+
/** Meetings still holding a string bound. A repaired row stops matching, which
|
|
172
|
+
* is what lets this stay a standing repair rather than a one-off migration. */
|
|
173
|
+
export declare const MEETING_RETYPE_SELECT = "\n MATCH (m:Meeting {accountId: $accountId})\n WHERE valueType(m.startsAt) STARTS WITH 'STRING' OR valueType(m.endsAt) STARTS WITH 'STRING'\n RETURN elementId(m) AS meetingId,\n CASE WHEN valueType(m.startsAt) STARTS WITH 'STRING' THEN m.startsAt ELSE null END AS startsAt,\n CASE WHEN valueType(m.endsAt) STARTS WITH 'STRING' THEN m.endsAt ELSE null END AS endsAt\n";
|
|
174
|
+
/** Rebuild each string bound as a ZONED DATETIME. A null param leaves that
|
|
175
|
+
* bound exactly as it is, so a half-corrupted row is half-repaired and its
|
|
176
|
+
* correctly-typed bound is never rewritten. The label and `accountId` are
|
|
177
|
+
* re-asserted here rather than trusted from the select: account scope is a
|
|
178
|
+
* property, and a write that carries no property cannot enforce it. */
|
|
179
|
+
export declare const MEETING_RETYPE_APPLY = "\n MATCH (m:Meeting {accountId: $accountId}) WHERE elementId(m) = $meetingId\n SET m.startsAt = CASE WHEN $startsAt IS NULL THEN m.startsAt ELSE datetime($startsAt) END,\n m.endsAt = CASE WHEN $endsAt IS NULL THEN m.endsAt ELSE datetime($endsAt) END\n";
|
|
180
|
+
/** Why a scanned row was not repaired. `unparseable` is a value no `datetime()`
|
|
181
|
+
* can rebuild and needs a human; `failed` is the write not landing — a driver
|
|
182
|
+
* timeout, a disconnect — which says nothing about the value and will be
|
|
183
|
+
* retried on the next tick. Neo4j names the difference in the error code, so
|
|
184
|
+
* the two are never reported under one count. */
|
|
185
|
+
export type RetypeFailure = "unparseable" | "failed";
|
|
186
|
+
export declare function classifyRetypeError(err: unknown): RetypeFailure;
|
|
187
|
+
/** A raw busy row, tagged with the label it came from. `end` is nullable here
|
|
188
|
+
* and nowhere downstream: `:Meeting.endsAt` is null when the event carries no
|
|
189
|
+
* end, and `censusBusyIntervals` resolves that before any comparison. */
|
|
190
|
+
export interface BusySourceRow {
|
|
191
|
+
start: string;
|
|
192
|
+
end: string | null;
|
|
193
|
+
src: "meeting" | "connector";
|
|
194
|
+
}
|
|
195
|
+
/** The busy set the public free/busy page computes from: meetings AND connector
|
|
196
|
+
* blocks. The old audit read only the second, so any meeting conflict was
|
|
197
|
+
* outside what it could measure.
|
|
198
|
+
*
|
|
199
|
+
* `UNION ALL`, not `UNION`: plain `UNION` de-duplicates the whole result, so two
|
|
200
|
+
* distinct meetings sharing bounds (a double booking, a re-ingested export)
|
|
201
|
+
* would collapse and be counted once. The census only earns its keep if the
|
|
202
|
+
* count is trustworthy, and the `src` column alone prevents cross-leg collapse,
|
|
203
|
+
* not collapse within a leg. */
|
|
204
|
+
export declare const BUSY_UNION_SELECT = "\n MATCH (m:Meeting {accountId: $accountId})\n RETURN toString(m.startsAt) AS start, toString(m.endsAt) AS end, 'meeting' AS src\n UNION ALL\n MATCH (b:ConnectorBusy {accountId: $accountId})\n RETURN toString(b.startsAt) AS start, toString(b.endsAt) AS end, 'connector' AS src\n";
|
|
205
|
+
export interface BusyCensus {
|
|
206
|
+
/** Every usable interval, both legs — what `classifyPublishedDrift` compares. */
|
|
207
|
+
usable: BusyInterval[];
|
|
208
|
+
/** The connector leg alone. `planBlockWrites` must keep reading this and not
|
|
209
|
+
* `usable`: its empty-set rule is a liveness test for the connector sync, and
|
|
210
|
+
* a set widened with meetings would report a deauthorised connector as live
|
|
211
|
+
* and delete every held block row. */
|
|
212
|
+
connectorOnly: BusyInterval[];
|
|
213
|
+
/** Counts are over `usable` only: a count that included rows the comparison
|
|
214
|
+
* ignored would be the same unqualified number this audit exists to remove. */
|
|
215
|
+
busyMeetings: number;
|
|
216
|
+
busyConnector: number;
|
|
217
|
+
/** Rows excluded for a bound no substitution could resolve. Reported on the
|
|
218
|
+
* audit line — an interval dropped without a count is the silent drop this
|
|
219
|
+
* task exists to remove. */
|
|
220
|
+
unusable: number;
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* Reduce the raw busy rows to the intervals the comparison can run against.
|
|
224
|
+
*
|
|
225
|
+
* `:Meeting.endsAt` is nullable by schema — `writeMeeting` stores null when an
|
|
226
|
+
* event carries no end — and the public free/busy route substitutes
|
|
227
|
+
* `start + durationMins` for those rows rather than ignoring them. This mirrors
|
|
228
|
+
* that substitution, because a no-end meeting IS busy on the page: dropping it
|
|
229
|
+
* would make a real conflict unreportable, which is this task's own failure
|
|
230
|
+
* shape. `durationMins` comes from the same `calendar-availability.json` the
|
|
231
|
+
* page reads; when it is absent the row has no resolvable end and is counted.
|
|
232
|
+
*/
|
|
233
|
+
export declare function censusBusyIntervals(rows: BusySourceRow[], durationMins?: number): BusyCensus;
|
|
157
234
|
/** A slot as it appears in the published `availability_snapshot` payload. */
|
|
158
235
|
export interface PublishedSlot {
|
|
159
236
|
start: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"booking-reconcile.d.ts","sourceRoot":"","sources":["../../src/lib/booking-reconcile.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAE5C,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,+BAA+B,CAAC;AAEzE,MAAM,WAAW,UAAU;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,wBAAgB,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAEpD;AAED,wBAAsB,YAAY,CAChC,OAAO,EAAE,OAAO,EAChB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,UAAU,GAClB,OAAO,CAAC,eAAe,CAAC,CAqD1B;AAMD;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,0BAA0B,yCAAyC,CAAC;AAEjF;8EAC8E;AAC9E,eAAO,MAAM,uBAAuB,sJAC0G,CAAC;AAE/I;yDACyD;AACzD,wBAAsB,uBAAuB,CAAC,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAMpG;AAED;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAClE,IAAI,EAAE,CAAC,EAAE,EACT,WAAW,EAAE,GAAG,CAAC,MAAM,CAAC,GACvB,CAAC,EAAE,CAEL;AAED;;gFAEgF;AAChF,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,WAAW;IAC1B;;qFAEiF;IACjF,gBAAgB,EAAE,MAAM,CAAC;IACzB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,cAAc,EAAE,MAAM,CAAC;IACvB;;;;;;;;;;;;;;;;OAgBG;IACH,mBAAmB,EAAE,MAAM,GAAG,SAAS,CAAC;CACzC;AAED;;;;;;;;GAQG;AACH,wBAAgB,WAAW,CACzB,QAAQ,EAAE,eAAe,EAAE,EAC3B,WAAW,EAAE,MAAM,EAAE,EACrB,KAAK,EAAE,MAAM,GACZ,WAAW,CAiBb;AAMD;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,wBAAwB,EAAE,MAAM,EAI5C,CAAC;AAEF;+CAC+C;AAC/C,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAE7D;AAED;;4DAE4D;AAC5D,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAE/D;AAMD;;qFAEqF;AACrF,eAAO,MAAM,qBAAqB,QAMmB,CAAC;AAEtD;;;;;;;;;;GAUG;AACH,wBAAsB,wBAAwB,CAC5C,OAAO,EAAE,OAAO,EAChB,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,mBAAmB,GAC5B,OAAO,CAAC,aAAa,GAAG,qBAAqB,CAAC,CA4ChD;AAED,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;CACb;AAcD;;8DAE8D;AAC9D,MAAM,MAAM,qBAAqB,GAAG,UAAU,GAAG,cAAc,GAAG,oBAAoB,CAAC;AAEvF,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,qBAAqB,CAAC;IAC/B,iEAAiE;IACjE,SAAS,EAAE,MAAM,CAAC;IAClB
|
|
1
|
+
{"version":3,"file":"booking-reconcile.d.ts","sourceRoot":"","sources":["../../src/lib/booking-reconcile.ts"],"names":[],"mappings":"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"}
|