@rubytech/create-maxy-code 0.1.603 → 0.1.605
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__/email-sampler-unit.test.js +22 -0
- package/dist/index.js +3 -0
- package/dist/port-resolution.js +9 -1
- package/package.json +1 -1
- package/payload/platform/lib/routine-templates/dist/roster.d.ts +46 -2
- package/payload/platform/lib/routine-templates/dist/roster.d.ts.map +1 -1
- package/payload/platform/lib/routine-templates/dist/roster.js +84 -32
- package/payload/platform/lib/routine-templates/dist/roster.js.map +1 -1
- package/payload/platform/lib/routine-templates/src/__tests__/roster.test.ts +0 -0
- package/payload/platform/lib/routine-templates/src/__tests__/seed.test.ts +48 -2
- package/payload/platform/lib/routine-templates/src/roster.ts +133 -35
- package/payload/platform/lib/telegram-store-read/dist/index.d.ts +59 -0
- package/payload/platform/lib/telegram-store-read/dist/index.d.ts.map +1 -0
- package/payload/platform/lib/telegram-store-read/dist/index.js +219 -0
- package/payload/platform/lib/telegram-store-read/dist/index.js.map +1 -0
- package/payload/platform/lib/telegram-store-read/src/__tests__/fold.test.ts +124 -0
- package/payload/platform/lib/telegram-store-read/src/index.ts +262 -0
- package/payload/platform/lib/telegram-store-read/tsconfig.json +9 -0
- package/payload/platform/lib/telegram-store-read/vitest.config.ts +9 -0
- package/payload/platform/package.json +2 -2
- package/payload/platform/plugins/admin/skills/platform-architecture/SKILL.md +39 -6
- package/payload/platform/plugins/admin/skills/whats-new/SKILL.md +11 -0
- package/payload/platform/plugins/connector/PLUGIN.md +9 -1
- package/payload/platform/plugins/connector/mcp/dist/__tests__/queue-descriptor.test.d.ts +2 -0
- package/payload/platform/plugins/connector/mcp/dist/__tests__/queue-descriptor.test.d.ts.map +1 -0
- package/payload/platform/plugins/connector/mcp/dist/__tests__/queue-descriptor.test.js +67 -0
- package/payload/platform/plugins/connector/mcp/dist/__tests__/queue-descriptor.test.js.map +1 -0
- package/payload/platform/plugins/connector/mcp/dist/index.js +36 -5
- package/payload/platform/plugins/connector/mcp/dist/index.js.map +1 -1
- package/payload/platform/plugins/connector/mcp/dist/lib/store.d.ts +35 -0
- package/payload/platform/plugins/connector/mcp/dist/lib/store.d.ts.map +1 -1
- package/payload/platform/plugins/connector/mcp/dist/lib/store.js +33 -0
- package/payload/platform/plugins/connector/mcp/dist/lib/store.js.map +1 -1
- package/payload/platform/plugins/connector/mcp/package.json +4 -2
- package/payload/platform/plugins/connector/mcp/vitest.config.ts +8 -0
- package/payload/platform/plugins/docs/references/admin-ui.md +2 -2
- package/payload/platform/plugins/docs/references/outlook-guide.md +21 -2
- package/payload/platform/plugins/docs/references/telegram-guide.md +15 -1
- package/payload/platform/plugins/email/PLUGIN.md +14 -1
- package/payload/platform/plugins/email/mcp/dist/sampler/__tests__/retention.test.d.ts +2 -0
- package/payload/platform/plugins/email/mcp/dist/sampler/__tests__/retention.test.d.ts.map +1 -0
- package/payload/platform/plugins/email/mcp/dist/sampler/__tests__/retention.test.js +233 -0
- package/payload/platform/plugins/email/mcp/dist/sampler/__tests__/retention.test.js.map +1 -0
- package/payload/platform/plugins/email/mcp/dist/sampler/__tests__/sample-mailbox.test.js +30 -0
- package/payload/platform/plugins/email/mcp/dist/sampler/__tests__/sample-mailbox.test.js.map +1 -1
- package/payload/platform/plugins/email/mcp/dist/sampler/main.js +68 -3
- package/payload/platform/plugins/email/mcp/dist/sampler/main.js.map +1 -1
- package/payload/platform/plugins/email/mcp/dist/sampler/retention-sources.d.ts +3 -0
- package/payload/platform/plugins/email/mcp/dist/sampler/retention-sources.d.ts.map +1 -0
- package/payload/platform/plugins/email/mcp/dist/sampler/retention-sources.js +146 -0
- package/payload/platform/plugins/email/mcp/dist/sampler/retention-sources.js.map +1 -0
- package/payload/platform/plugins/email/mcp/dist/sampler/retention.d.ts +150 -0
- package/payload/platform/plugins/email/mcp/dist/sampler/retention.d.ts.map +1 -0
- package/payload/platform/plugins/email/mcp/dist/sampler/retention.js +199 -0
- package/payload/platform/plugins/email/mcp/dist/sampler/retention.js.map +1 -0
- package/payload/platform/plugins/email/mcp/dist/sampler/sample-mailbox.d.ts +5 -0
- package/payload/platform/plugins/email/mcp/dist/sampler/sample-mailbox.d.ts.map +1 -1
- package/payload/platform/plugins/email/mcp/dist/sampler/sample-mailbox.js +10 -5
- package/payload/platform/plugins/email/mcp/dist/sampler/sample-mailbox.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-ingest-section-properties-strip.test.js +11 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-ingest-section-properties-strip.test.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-ingest.d.ts.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-ingest.js +8 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-ingest.js.map +1 -1
- package/payload/platform/plugins/outlook/mcp/dist/__tests__/sample-outlook-mailbox.test.d.ts +2 -0
- package/payload/platform/plugins/outlook/mcp/dist/__tests__/sample-outlook-mailbox.test.d.ts.map +1 -0
- package/payload/platform/plugins/outlook/mcp/dist/__tests__/sample-outlook-mailbox.test.js +324 -0
- package/payload/platform/plugins/outlook/mcp/dist/__tests__/sample-outlook-mailbox.test.js.map +1 -0
- package/payload/platform/plugins/outlook/mcp/dist/__tests__/sampler-cursor.test.d.ts +2 -0
- package/payload/platform/plugins/outlook/mcp/dist/__tests__/sampler-cursor.test.d.ts.map +1 -0
- package/payload/platform/plugins/outlook/mcp/dist/__tests__/sampler-cursor.test.js +102 -0
- package/payload/platform/plugins/outlook/mcp/dist/__tests__/sampler-cursor.test.js.map +1 -0
- package/payload/platform/plugins/outlook/mcp/dist/__tests__/sampler-enumerate.test.d.ts +2 -0
- package/payload/platform/plugins/outlook/mcp/dist/__tests__/sampler-enumerate.test.d.ts.map +1 -0
- package/payload/platform/plugins/outlook/mcp/dist/__tests__/sampler-enumerate.test.js +125 -0
- package/payload/platform/plugins/outlook/mcp/dist/__tests__/sampler-enumerate.test.js.map +1 -0
- package/payload/platform/plugins/outlook/mcp/dist/sampler/arm.d.ts +2 -0
- package/payload/platform/plugins/outlook/mcp/dist/sampler/arm.d.ts.map +1 -0
- package/payload/platform/plugins/outlook/mcp/dist/sampler/arm.js +109 -0
- package/payload/platform/plugins/outlook/mcp/dist/sampler/arm.js.map +1 -0
- package/payload/platform/plugins/outlook/mcp/dist/sampler/cursor.d.ts +25 -0
- package/payload/platform/plugins/outlook/mcp/dist/sampler/cursor.d.ts.map +1 -0
- package/payload/platform/plugins/outlook/mcp/dist/sampler/cursor.js +94 -0
- package/payload/platform/plugins/outlook/mcp/dist/sampler/cursor.js.map +1 -0
- package/payload/platform/plugins/outlook/mcp/dist/sampler/enumerate.d.ts +41 -0
- package/payload/platform/plugins/outlook/mcp/dist/sampler/enumerate.d.ts.map +1 -0
- package/payload/platform/plugins/outlook/mcp/dist/sampler/enumerate.js +122 -0
- package/payload/platform/plugins/outlook/mcp/dist/sampler/enumerate.js.map +1 -0
- package/payload/platform/plugins/outlook/mcp/dist/sampler/sample-outlook-mailbox.d.ts +73 -0
- package/payload/platform/plugins/outlook/mcp/dist/sampler/sample-outlook-mailbox.d.ts.map +1 -0
- package/payload/platform/plugins/outlook/mcp/dist/sampler/sample-outlook-mailbox.js +162 -0
- package/payload/platform/plugins/outlook/mcp/dist/sampler/sample-outlook-mailbox.js.map +1 -0
- package/payload/platform/plugins/scheduling/PLUGIN.md +8 -1
- package/payload/platform/plugins/scheduling/mcp/dist/index.js +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/index.js.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/gate-flag.test.d.ts +2 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/gate-flag.test.d.ts.map +1 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/gate-flag.test.js +90 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/gate-flag.test.js.map +1 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/gate.test.js +26 -4
- package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/gate.test.js.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/lib/gate-flag.d.ts +78 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/gate-flag.d.ts.map +1 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/gate-flag.js +76 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/gate-flag.js.map +1 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/gate.d.ts +8 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/gate.d.ts.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/lib/gate.js +9 -1
- package/payload/platform/plugins/scheduling/mcp/dist/lib/gate.js.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/__tests__/gate-dispatch-wiring.test.js +15 -0
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/__tests__/gate-dispatch-wiring.test.js.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/agent-turn-dispatch.d.ts +12 -1
- 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 +34 -1
- 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 +9 -1
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/check-due-events.js.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/tools/__tests__/schedule-gate-write.test.js +40 -0
- package/payload/platform/plugins/scheduling/mcp/dist/tools/__tests__/schedule-gate-write.test.js.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/tools/__tests__/scheduling-gate.test.js +435 -5
- package/payload/platform/plugins/scheduling/mcp/dist/tools/__tests__/scheduling-gate.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 +21 -1
- package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-event.js.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/tools/scheduling-gate.d.ts +294 -6
- package/payload/platform/plugins/scheduling/mcp/dist/tools/scheduling-gate.d.ts.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/tools/scheduling-gate.js +553 -11
- package/payload/platform/plugins/scheduling/mcp/dist/tools/scheduling-gate.js.map +1 -1
- package/payload/platform/plugins/telegram/PLUGIN.md +1 -1
- package/payload/platform/plugins/telegram/mcp/dist/__tests__/messages.test.d.ts +2 -0
- package/payload/platform/plugins/telegram/mcp/dist/__tests__/messages.test.d.ts.map +1 -0
- package/payload/platform/plugins/telegram/mcp/dist/__tests__/messages.test.js +157 -0
- package/payload/platform/plugins/telegram/mcp/dist/__tests__/messages.test.js.map +1 -0
- package/payload/platform/plugins/telegram/mcp/dist/__tests__/public-pin.test.js +2 -2
- package/payload/platform/plugins/telegram/mcp/dist/__tests__/public-pin.test.js.map +1 -1
- package/payload/platform/plugins/telegram/mcp/dist/index.js +32 -34
- package/payload/platform/plugins/telegram/mcp/dist/index.js.map +1 -1
- package/payload/platform/plugins/telegram/mcp/dist/lib/public-pin.js +1 -1
- package/payload/platform/plugins/telegram/mcp/dist/lib/public-pin.js.map +1 -1
- package/payload/platform/plugins/telegram/mcp/dist/tools/messages.d.ts +27 -0
- package/payload/platform/plugins/telegram/mcp/dist/tools/messages.d.ts.map +1 -0
- package/payload/platform/plugins/telegram/mcp/dist/tools/messages.js +152 -0
- package/payload/platform/plugins/telegram/mcp/dist/tools/messages.js.map +1 -0
- package/payload/platform/plugins/telegram/skills/build/SKILL.md +1 -1
- package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.js +1 -1
- package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.js.map +1 -1
- package/payload/platform/templates/specialists/agents/personal-assistant.md +1 -1
- package/payload/server/public/operator.html +1 -1
- package/payload/server/server.js +69 -5
- package/payload/platform/plugins/telegram/mcp/dist/tools/message-history.d.ts +0 -16
- package/payload/platform/plugins/telegram/mcp/dist/tools/message-history.d.ts.map +0 -1
- package/payload/platform/plugins/telegram/mcp/dist/tools/message-history.js +0 -68
- package/payload/platform/plugins/telegram/mcp/dist/tools/message-history.js.map +0 -1
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
import { describe, it, expect, vi } from "vitest";
|
|
2
|
+
import { resolveRetentionDays, cutoffIso, interestedSets, partitionAged, runRetention, sweepAccount, RETENTION_CANDIDATE_CAP, RETENTION_MAX_DAYS, } from "../retention.js";
|
|
3
|
+
describe("resolveRetentionDays", () => {
|
|
4
|
+
it("returns null when unset", () => {
|
|
5
|
+
expect(resolveRetentionDays({})).toBeNull();
|
|
6
|
+
});
|
|
7
|
+
it("returns null for zero, negative, fractional and unparseable values", () => {
|
|
8
|
+
for (const v of ["0", "-1", "30.5", "abc", "", " "]) {
|
|
9
|
+
expect(resolveRetentionDays({ EMAIL_RETENTION_DAYS: v })).toBeNull();
|
|
10
|
+
}
|
|
11
|
+
});
|
|
12
|
+
it("returns the positive integer day count", () => {
|
|
13
|
+
expect(resolveRetentionDays({ EMAIL_RETENTION_DAYS: "30" })).toBe(30);
|
|
14
|
+
});
|
|
15
|
+
it("refuses a period large enough to overflow the cutoff date", () => {
|
|
16
|
+
expect(resolveRetentionDays({ EMAIL_RETENTION_DAYS: "100000000000" })).toBeNull();
|
|
17
|
+
expect(resolveRetentionDays({ EMAIL_RETENTION_DAYS: String(RETENTION_MAX_DAYS + 1) })).toBeNull();
|
|
18
|
+
expect(resolveRetentionDays({ EMAIL_RETENTION_DAYS: String(RETENTION_MAX_DAYS) })).toBe(RETENTION_MAX_DAYS);
|
|
19
|
+
});
|
|
20
|
+
it("keeps every accepted period inside the range cutoffIso can express", () => {
|
|
21
|
+
expect(() => cutoffIso(new Date("2026-08-13T09:00:00.000Z"), RETENTION_MAX_DAYS)).not.toThrow();
|
|
22
|
+
});
|
|
23
|
+
});
|
|
24
|
+
describe("cutoffIso", () => {
|
|
25
|
+
it("subtracts whole days from the clock in the ISO shape createdAt uses", () => {
|
|
26
|
+
expect(cutoffIso(new Date("2026-08-13T09:00:00.000Z"), 30)).toBe("2026-07-14T09:00:00.000Z");
|
|
27
|
+
});
|
|
28
|
+
});
|
|
29
|
+
describe("interestedSets", () => {
|
|
30
|
+
const args = (checks) => JSON.stringify({ eventId: "ignored", checks });
|
|
31
|
+
it("splits routines by the label their graph-unflagged check names", () => {
|
|
32
|
+
const rows = [
|
|
33
|
+
{ eventId: "ev-sec", gateArgs: args([{ type: "graph-unflagged", label: "Section" }]) },
|
|
34
|
+
{ eventId: "ev-arc", gateArgs: args([{ type: "graph-unflagged", label: "ConversationArchive" }]) },
|
|
35
|
+
];
|
|
36
|
+
expect(interestedSets(rows)).toEqual({ section: ["ev-sec"], archive: ["ev-arc"] });
|
|
37
|
+
});
|
|
38
|
+
it("puts a routine holding both checks in both sets", () => {
|
|
39
|
+
const rows = [
|
|
40
|
+
{
|
|
41
|
+
eventId: "ev-both",
|
|
42
|
+
gateArgs: args([
|
|
43
|
+
{ type: "graph-unflagged", label: "Section" },
|
|
44
|
+
{ type: "graph-unflagged", label: "ConversationArchive" },
|
|
45
|
+
]),
|
|
46
|
+
},
|
|
47
|
+
];
|
|
48
|
+
expect(interestedSets(rows)).toEqual({ section: ["ev-both"], archive: ["ev-both"] });
|
|
49
|
+
});
|
|
50
|
+
it("ignores checks of other types and labels outside the accepted pair", () => {
|
|
51
|
+
const rows = [
|
|
52
|
+
{ eventId: "ev-mail", gateArgs: args([{ type: "mail", mailbox: "a@b.c" }]) },
|
|
53
|
+
{ eventId: "ev-odd", gateArgs: args([{ type: "graph-unflagged", label: "Person" }]) },
|
|
54
|
+
];
|
|
55
|
+
expect(interestedSets(rows)).toEqual({ section: [], archive: [] });
|
|
56
|
+
});
|
|
57
|
+
it("contributes nothing and does not throw on absent or malformed gateArgs", () => {
|
|
58
|
+
const rows = [
|
|
59
|
+
{ eventId: "ev-null", gateArgs: null },
|
|
60
|
+
{ eventId: "ev-bad", gateArgs: "{not json" },
|
|
61
|
+
{ eventId: "ev-nochecks", gateArgs: JSON.stringify({ eventId: "x" }) },
|
|
62
|
+
{ eventId: "ev-checksnotarray", gateArgs: JSON.stringify({ checks: "Section" }) },
|
|
63
|
+
];
|
|
64
|
+
expect(interestedSets(rows)).toEqual({ section: [], archive: [] });
|
|
65
|
+
});
|
|
66
|
+
it("names a routine once per set even when it repeats the same check", () => {
|
|
67
|
+
const rows = [
|
|
68
|
+
{
|
|
69
|
+
eventId: "ev-dup",
|
|
70
|
+
gateArgs: args([
|
|
71
|
+
{ type: "graph-unflagged", label: "Section" },
|
|
72
|
+
{ type: "graph-unflagged", label: "Section" },
|
|
73
|
+
]),
|
|
74
|
+
},
|
|
75
|
+
];
|
|
76
|
+
expect(interestedSets(rows)).toEqual({ section: ["ev-dup"], archive: [] });
|
|
77
|
+
});
|
|
78
|
+
});
|
|
79
|
+
describe("partitionAged", () => {
|
|
80
|
+
const aged = (over = {}) => ({
|
|
81
|
+
id: "s1",
|
|
82
|
+
processedBy: [],
|
|
83
|
+
parentProcessedBy: [],
|
|
84
|
+
...over,
|
|
85
|
+
});
|
|
86
|
+
it("prunes a section every interested routine has flagged", () => {
|
|
87
|
+
const rows = [aged({ processedBy: ["ev-a", "ev-b"], parentProcessedBy: ["ev-c"] })];
|
|
88
|
+
expect(partitionAged(rows, { section: ["ev-a", "ev-b"], archive: ["ev-c"] })).toEqual({
|
|
89
|
+
prunable: ["s1"],
|
|
90
|
+
keptOutstanding: 0,
|
|
91
|
+
});
|
|
92
|
+
});
|
|
93
|
+
it("keeps a section with one section-gated routine still outstanding", () => {
|
|
94
|
+
const rows = [aged({ processedBy: ["ev-a"] })];
|
|
95
|
+
expect(partitionAged(rows, { section: ["ev-a", "ev-b"], archive: [] })).toEqual({
|
|
96
|
+
prunable: [],
|
|
97
|
+
keptOutstanding: 1,
|
|
98
|
+
});
|
|
99
|
+
});
|
|
100
|
+
it("keeps a fully section-flagged node whose parent archive is outstanding", () => {
|
|
101
|
+
const rows = [aged({ processedBy: ["ev-a"], parentProcessedBy: [] })];
|
|
102
|
+
expect(partitionAged(rows, { section: ["ev-a"], archive: ["ev-c"] })).toEqual({
|
|
103
|
+
prunable: [],
|
|
104
|
+
keptOutstanding: 1,
|
|
105
|
+
});
|
|
106
|
+
});
|
|
107
|
+
it("keeps a section that has no parent archive", () => {
|
|
108
|
+
const rows = [aged({ processedBy: ["ev-a"], parentProcessedBy: null })];
|
|
109
|
+
expect(partitionAged(rows, { section: ["ev-a"], archive: [] })).toEqual({
|
|
110
|
+
prunable: [],
|
|
111
|
+
keptOutstanding: 1,
|
|
112
|
+
});
|
|
113
|
+
});
|
|
114
|
+
it("ignores a flag from a routine that is not interested", () => {
|
|
115
|
+
const rows = [aged({ processedBy: ["ev-a", "ev-stale"] })];
|
|
116
|
+
expect(partitionAged(rows, { section: ["ev-a"], archive: [] })).toEqual({
|
|
117
|
+
prunable: ["s1"],
|
|
118
|
+
keptOutstanding: 0,
|
|
119
|
+
});
|
|
120
|
+
});
|
|
121
|
+
});
|
|
122
|
+
const NOW = new Date("2026-08-13T09:00:00.000Z");
|
|
123
|
+
function deps(over = {}) {
|
|
124
|
+
return {
|
|
125
|
+
listEmailAccountIds: vi.fn(async () => ["acc-1"]),
|
|
126
|
+
listGateArgs: vi.fn(async () => []),
|
|
127
|
+
listAgedSections: vi.fn(async () => []),
|
|
128
|
+
pruneSections: vi.fn(async () => ({ repaired: 0, pruned: 0 })),
|
|
129
|
+
now: () => NOW,
|
|
130
|
+
log: vi.fn(),
|
|
131
|
+
...over,
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
const lines = (d) => d.log.mock.calls.map((c) => c[0]);
|
|
135
|
+
const sectionGate = (eventId) => ({
|
|
136
|
+
eventId,
|
|
137
|
+
gateArgs: JSON.stringify({ checks: [{ type: "graph-unflagged", label: "Section" }] }),
|
|
138
|
+
});
|
|
139
|
+
describe("runRetention", () => {
|
|
140
|
+
it("prunes nothing and names the period unset when EMAIL_RETENTION_DAYS is absent", async () => {
|
|
141
|
+
const d = deps();
|
|
142
|
+
await runRetention(d, {});
|
|
143
|
+
expect(d.listEmailAccountIds).not.toHaveBeenCalled();
|
|
144
|
+
expect(lines(d)).toEqual([
|
|
145
|
+
"op=email-retention account=- interested=0 pruned=0 kept-outstanding=0 repaired=0 ageDays=unset",
|
|
146
|
+
]);
|
|
147
|
+
});
|
|
148
|
+
it("sweeps every account holding email sections when a period is set", async () => {
|
|
149
|
+
const d = deps({ listEmailAccountIds: vi.fn(async () => ["acc-1", "acc-2"]) });
|
|
150
|
+
await runRetention(d, { EMAIL_RETENTION_DAYS: "30" });
|
|
151
|
+
expect(d.listGateArgs).toHaveBeenCalledTimes(2);
|
|
152
|
+
});
|
|
153
|
+
it("reports one account's failure and continues to the next", async () => {
|
|
154
|
+
const d = deps({
|
|
155
|
+
listEmailAccountIds: vi.fn(async () => ["acc-1", "acc-2"]),
|
|
156
|
+
listGateArgs: vi.fn(async (accountId) => {
|
|
157
|
+
if (accountId === "acc-1")
|
|
158
|
+
throw new Error("neo4j down");
|
|
159
|
+
return [];
|
|
160
|
+
}),
|
|
161
|
+
});
|
|
162
|
+
await runRetention(d, { EMAIL_RETENTION_DAYS: "30" });
|
|
163
|
+
expect(lines(d)[0]).toBe("op=email-retention-error account=acc-1 detail=neo4j down");
|
|
164
|
+
expect(lines(d)[1]).toBe("op=email-retention account=acc-2 interested=0 pruned=0 kept-outstanding=0 repaired=0 ageDays=30");
|
|
165
|
+
});
|
|
166
|
+
});
|
|
167
|
+
describe("sweepAccount", () => {
|
|
168
|
+
it("deletes nothing and reports interested=0 when no routine holds the check", async () => {
|
|
169
|
+
const d = deps({ listGateArgs: vi.fn(async () => [{ eventId: "ev-1", gateArgs: null }]) });
|
|
170
|
+
await sweepAccount(d, "acc-1", 30);
|
|
171
|
+
expect(d.listAgedSections).not.toHaveBeenCalled();
|
|
172
|
+
expect(d.pruneSections).not.toHaveBeenCalled();
|
|
173
|
+
expect(lines(d)).toEqual([
|
|
174
|
+
"op=email-retention account=acc-1 interested=0 pruned=0 kept-outstanding=0 repaired=0 ageDays=30",
|
|
175
|
+
]);
|
|
176
|
+
});
|
|
177
|
+
it("prunes only the flagged section and reports every count", async () => {
|
|
178
|
+
const d = deps({
|
|
179
|
+
listGateArgs: vi.fn(async () => [sectionGate("ev-a")]),
|
|
180
|
+
listAgedSections: vi.fn(async () => [
|
|
181
|
+
{ id: "s1", processedBy: ["ev-a"], parentProcessedBy: [] },
|
|
182
|
+
{ id: "s2", processedBy: [], parentProcessedBy: [] },
|
|
183
|
+
]),
|
|
184
|
+
pruneSections: vi.fn(async () => ({ repaired: 2, pruned: 1 })),
|
|
185
|
+
});
|
|
186
|
+
await sweepAccount(d, "acc-1", 30);
|
|
187
|
+
expect(d.listAgedSections.mock.calls[0]).toEqual([
|
|
188
|
+
"acc-1",
|
|
189
|
+
"2026-07-14T09:00:00.000Z",
|
|
190
|
+
RETENTION_CANDIDATE_CAP,
|
|
191
|
+
]);
|
|
192
|
+
expect(d.pruneSections).toHaveBeenCalledWith("acc-1", ["s1"]);
|
|
193
|
+
expect(lines(d)).toEqual([
|
|
194
|
+
"op=email-retention account=acc-1 interested=1 pruned=1 kept-outstanding=1 repaired=2 ageDays=30",
|
|
195
|
+
]);
|
|
196
|
+
});
|
|
197
|
+
it("reports repaired=0 beside a non-zero prune, the broken-chain signature", async () => {
|
|
198
|
+
const d = deps({
|
|
199
|
+
listGateArgs: vi.fn(async () => [sectionGate("ev-a")]),
|
|
200
|
+
listAgedSections: vi.fn(async () => [
|
|
201
|
+
{ id: "s1", processedBy: ["ev-a"], parentProcessedBy: [] },
|
|
202
|
+
]),
|
|
203
|
+
pruneSections: vi.fn(async () => ({ repaired: 0, pruned: 1 })),
|
|
204
|
+
});
|
|
205
|
+
await sweepAccount(d, "acc-1", 30);
|
|
206
|
+
expect(lines(d)[0]).toContain("pruned=1 kept-outstanding=0 repaired=0");
|
|
207
|
+
});
|
|
208
|
+
it("skips the repair and the delete when nothing is prunable", async () => {
|
|
209
|
+
const d = deps({
|
|
210
|
+
listGateArgs: vi.fn(async () => [sectionGate("ev-a")]),
|
|
211
|
+
listAgedSections: vi.fn(async () => [{ id: "s1", processedBy: [], parentProcessedBy: [] }]),
|
|
212
|
+
});
|
|
213
|
+
await sweepAccount(d, "acc-1", 30);
|
|
214
|
+
expect(d.pruneSections).not.toHaveBeenCalled();
|
|
215
|
+
expect(lines(d)).toEqual([
|
|
216
|
+
"op=email-retention account=acc-1 interested=1 pruned=0 kept-outstanding=1 repaired=0 ageDays=30",
|
|
217
|
+
]);
|
|
218
|
+
});
|
|
219
|
+
it("names a capped candidate batch so a truncated sweep is never silent", async () => {
|
|
220
|
+
const rows = Array.from({ length: RETENTION_CANDIDATE_CAP }, (_, i) => ({
|
|
221
|
+
id: `s${i}`,
|
|
222
|
+
processedBy: [],
|
|
223
|
+
parentProcessedBy: [],
|
|
224
|
+
}));
|
|
225
|
+
const d = deps({
|
|
226
|
+
listGateArgs: vi.fn(async () => [sectionGate("ev-a")]),
|
|
227
|
+
listAgedSections: vi.fn(async () => rows),
|
|
228
|
+
});
|
|
229
|
+
await sweepAccount(d, "acc-1", 30);
|
|
230
|
+
expect(lines(d)[0]).toContain("capped=true");
|
|
231
|
+
});
|
|
232
|
+
});
|
|
233
|
+
//# sourceMappingURL=retention.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"retention.test.js","sourceRoot":"","sources":["../../../src/sampler/__tests__/retention.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -93,4 +93,34 @@ describe("sampleMailbox", () => {
|
|
|
93
93
|
expect(r).toMatchObject({ fetched: 0, cursor: 0 });
|
|
94
94
|
});
|
|
95
95
|
});
|
|
96
|
+
describe("provider label (Task 2683)", () => {
|
|
97
|
+
it("carries provider=imap on every emitted line, success and error", async () => {
|
|
98
|
+
const written = deps({
|
|
99
|
+
readCursor: vi.fn(async () => ({ cursorUid: 10, uidValidity: 100 })),
|
|
100
|
+
fetchSince: vi.fn(async () => ({ uidValidity: 100, emails: [email(11)], maxUid: 11 })),
|
|
101
|
+
});
|
|
102
|
+
await sampleMailbox(written, account);
|
|
103
|
+
const idle = deps({ readCursor: vi.fn(async () => ({ cursorUid: 10, uidValidity: 100 })) });
|
|
104
|
+
await sampleMailbox(idle, account);
|
|
105
|
+
const reset = deps({
|
|
106
|
+
readCursor: vi.fn(async () => ({ cursorUid: 10, uidValidity: 99 })),
|
|
107
|
+
fetchSince: vi.fn(async () => ({ uidValidity: 100, emails: [], maxUid: 0 })),
|
|
108
|
+
});
|
|
109
|
+
await sampleMailbox(reset, account);
|
|
110
|
+
const failed = deps({
|
|
111
|
+
fetchSince: vi.fn(async () => {
|
|
112
|
+
throw new Error("imap down");
|
|
113
|
+
}),
|
|
114
|
+
});
|
|
115
|
+
await sampleMailbox(failed, account);
|
|
116
|
+
// Without this label `provider=` is not a total filter once the Outlook arm
|
|
117
|
+
// shares the log: filtering on it would return zero IMAP rows.
|
|
118
|
+
for (const d of [written, idle, reset, failed]) {
|
|
119
|
+
const lines = d.log.mock.calls.map((c) => String(c[0]));
|
|
120
|
+
expect(lines.length).toBeGreaterThan(0);
|
|
121
|
+
for (const line of lines)
|
|
122
|
+
expect(line).toContain("provider=imap");
|
|
123
|
+
}
|
|
124
|
+
});
|
|
125
|
+
});
|
|
96
126
|
//# sourceMappingURL=sample-mailbox.test.js.map
|
package/payload/platform/plugins/email/mcp/dist/sampler/__tests__/sample-mailbox.test.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sample-mailbox.test.js","sourceRoot":"","sources":["../../../src/sampler/__tests__/sample-mailbox.test.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"sample-mailbox.test.js","sourceRoot":"","sources":["../../../src/sampler/__tests__/sample-mailbox.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
import { appendFileSync, statSync, readFileSync, writeFileSync, mkdirSync } from "node:fs";
|
|
2
|
-
import { dirname } from "node:path";
|
|
2
|
+
import { dirname, resolve } from "node:path";
|
|
3
|
+
import { pathToFileURL } from "node:url";
|
|
3
4
|
import { fetchSinceUid, resolveDefaultRecipients } from "../lib/imap.js";
|
|
4
5
|
import { dispatchEmailMessagesToConversationArchive } from "../lib/conversation-archive-dispatch.js";
|
|
5
6
|
import { listAllImapAccounts, readSamplerCursor, advanceSamplerCursor } from "../lib/credentials.js";
|
|
6
7
|
import { sampleMailbox } from "./sample-mailbox.js";
|
|
8
|
+
import { runRetention } from "./retention.js";
|
|
9
|
+
import { retentionSources } from "./retention-sources.js";
|
|
7
10
|
// The standing email-sampler (Task 2682): a per-brand systemd user unit that
|
|
8
11
|
// each cycle enumerates every IMAP mailbox on the install and writes new
|
|
9
12
|
// inbound messages to the graph via the plugin's own dispatch, independent of
|
|
@@ -43,12 +46,35 @@ const deps = {
|
|
|
43
46
|
log: logLine,
|
|
44
47
|
};
|
|
45
48
|
async function cycle() {
|
|
49
|
+
await imapArm();
|
|
50
|
+
await outlookArm();
|
|
51
|
+
await retentionPass();
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* The retention sweep (Task 2685). Runs AFTER both arms so a cycle never deletes
|
|
55
|
+
* before it has written, and in its own try for the reason each arm has one: a
|
|
56
|
+
* retention failure must cost no ingest.
|
|
57
|
+
*
|
|
58
|
+
* `runRetention` reads `EMAIL_RETENTION_DAYS` itself and prunes nothing when it
|
|
59
|
+
* is unset, which is every install until an operator sets it.
|
|
60
|
+
*/
|
|
61
|
+
async function retentionPass() {
|
|
62
|
+
try {
|
|
63
|
+
await runRetention(retentionSources(() => new Date(), logLine), process.env);
|
|
64
|
+
}
|
|
65
|
+
catch (e) {
|
|
66
|
+
logLine(`op=email-retention-error account=<sweep> detail=${e instanceof Error ? e.message : String(e)}`);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
/** The IMAP arm (Task 2682). An enumeration failure ends this arm only; the
|
|
70
|
+
* Outlook arm reads a different store and must still run. */
|
|
71
|
+
async function imapArm() {
|
|
46
72
|
let accounts;
|
|
47
73
|
try {
|
|
48
74
|
accounts = await listAllImapAccounts();
|
|
49
75
|
}
|
|
50
76
|
catch (e) {
|
|
51
|
-
logLine(`op=sample-error mailbox=<enumeration> detail=${e instanceof Error ? e.message : String(e)}`);
|
|
77
|
+
logLine(`op=sample-error mailbox=<enumeration> provider=imap detail=${e instanceof Error ? e.message : String(e)}`);
|
|
52
78
|
return;
|
|
53
79
|
}
|
|
54
80
|
for (const account of accounts) {
|
|
@@ -56,10 +82,49 @@ async function cycle() {
|
|
|
56
82
|
await sampleMailbox(deps, account);
|
|
57
83
|
}
|
|
58
84
|
catch (e) {
|
|
59
|
-
logLine(`op=sample-error mailbox=${account.config.email} detail=${e instanceof Error ? e.message : String(e)}`);
|
|
85
|
+
logLine(`op=sample-error mailbox=${account.config.email} provider=imap detail=${e instanceof Error ? e.message : String(e)}`);
|
|
60
86
|
}
|
|
61
87
|
}
|
|
62
88
|
}
|
|
89
|
+
/**
|
|
90
|
+
* The Outlook arm (Task 2683), resolved and imported at runtime rather than
|
|
91
|
+
* statically. This plugin does not depend on `@microsoft/microsoft-graph-client`
|
|
92
|
+
* and no plugin in this tree statically imports another plugin's source;
|
|
93
|
+
* reaching a sibling plugin's compiled dist through PLATFORM_ROOT is the
|
|
94
|
+
* established pattern (`scheduling/mcp/src/scripts/check-due-events.ts:761`).
|
|
95
|
+
*
|
|
96
|
+
* Both arms share this log because Task 2683's verification names
|
|
97
|
+
* `logs-read.sh --tail email-sampler` filtered on `provider=outlook`.
|
|
98
|
+
*
|
|
99
|
+
* An absent or unbuilt module is a logged skip, never fatal: an install whose
|
|
100
|
+
* outlook plugin was never built must not lose IMAP ingest.
|
|
101
|
+
*/
|
|
102
|
+
async function outlookArm() {
|
|
103
|
+
const platformRoot = process.env.PLATFORM_ROOT;
|
|
104
|
+
if (!platformRoot) {
|
|
105
|
+
logLine("op=sample-skip provider=outlook detail=PLATFORM_ROOT-unset");
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
const armPath = pathToFileURL(resolve(platformRoot, "plugins/outlook/mcp/dist/sampler/arm.js")).href;
|
|
109
|
+
let mod;
|
|
110
|
+
try {
|
|
111
|
+
mod = (await import(armPath));
|
|
112
|
+
}
|
|
113
|
+
catch (e) {
|
|
114
|
+
logLine(`op=sample-skip provider=outlook detail=arm-unavailable ${e instanceof Error ? e.message : String(e)}`);
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
if (typeof mod.runOutlookArm !== "function") {
|
|
118
|
+
logLine("op=sample-skip provider=outlook detail=arm-export-missing");
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
try {
|
|
122
|
+
await mod.runOutlookArm(logLine);
|
|
123
|
+
}
|
|
124
|
+
catch (e) {
|
|
125
|
+
logLine(`op=sample-error mailbox=<outlook-arm> provider=outlook detail=${e instanceof Error ? e.message : String(e)}`);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
63
128
|
async function main() {
|
|
64
129
|
logLine(`boot interval_sec=${INTERVAL_MS / 1000} log=${LOG_PATH}`);
|
|
65
130
|
// eslint-disable-next-line no-constant-condition
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"main.js","sourceRoot":"","sources":["../../src/sampler/main.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,QAAQ,EAAE,YAAY,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAC3F,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"main.js","sourceRoot":"","sources":["../../src/sampler/main.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"retention-sources.d.ts","sourceRoot":"","sources":["../../src/sampler/retention-sources.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAwB,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAuB1E,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,IAAI,EAAE,GAAG,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,GAAG,aAAa,CAkJ5F"}
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
import neo4j from "neo4j-driver";
|
|
2
|
+
import { getSession } from "../lib/neo4j.js";
|
|
3
|
+
// The real graph behind `RetentionDeps` (Task 2685). Split from `retention.ts`
|
|
4
|
+
// so the predicate, the parsing and the sweep stay testable without Neo4j —
|
|
5
|
+
// the same division `scheduling-gate.ts` draws between its probe and
|
|
6
|
+
// `REAL_SOURCES`.
|
|
7
|
+
/**
|
|
8
|
+
* The longest deleted span the chain repair walks. A bound rather than `*0..`
|
|
9
|
+
* because an unbounded variable-length match over a long conversation is the one
|
|
10
|
+
* statement here that can run away; a span longer than this leaves the chain
|
|
11
|
+
* broken, which costs a later ingest a wrong tail and never costs data.
|
|
12
|
+
*/
|
|
13
|
+
const RETENTION_CHAIN_HOPS = 500;
|
|
14
|
+
/** Neo4j returns list properties as-is; this narrows a `gateProcessedBy` value
|
|
15
|
+
* to the string list the predicate expects, treating an absent or wrong-typed
|
|
16
|
+
* property as "flagged by nobody". */
|
|
17
|
+
function flagList(value) {
|
|
18
|
+
return Array.isArray(value) ? value.filter((v) => typeof v === "string") : [];
|
|
19
|
+
}
|
|
20
|
+
export function retentionSources(now, log) {
|
|
21
|
+
return {
|
|
22
|
+
now,
|
|
23
|
+
log,
|
|
24
|
+
listEmailAccountIds: async () => {
|
|
25
|
+
const session = getSession();
|
|
26
|
+
try {
|
|
27
|
+
const res = await session.run(`MATCH (s:Section)
|
|
28
|
+
WHERE s.source = 'email' AND s.accountId IS NOT NULL
|
|
29
|
+
RETURN DISTINCT s.accountId AS accountId`);
|
|
30
|
+
return res.records.map((r) => r.get("accountId"));
|
|
31
|
+
}
|
|
32
|
+
finally {
|
|
33
|
+
await session.close();
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
// Every gate-bearing :Event on the account, enabled or suspended. A
|
|
37
|
+
// suspended routine counts as interested (operator decision 2026-08-13), so
|
|
38
|
+
// enabling a parked routine never finds its backlog already deleted — hence
|
|
39
|
+
// no `eventStatus` predicate here.
|
|
40
|
+
//
|
|
41
|
+
// `e.eventId`, never `elementId(e)`: the dispatcher passes the eventId
|
|
42
|
+
// PROPERTY as the flag key (agent-turn-dispatch.ts:506), so joining on the
|
|
43
|
+
// element id would compare against a value `gateProcessedBy` never holds and
|
|
44
|
+
// every section would look outstanding for ever.
|
|
45
|
+
listGateArgs: async (accountId) => {
|
|
46
|
+
const session = getSession();
|
|
47
|
+
try {
|
|
48
|
+
const res = await session.run(`MATCH (e:Event)
|
|
49
|
+
WHERE e.accountId = $accountId AND e.gateArgs IS NOT NULL
|
|
50
|
+
RETURN e.eventId AS eventId, e.gateArgs AS gateArgs`, { accountId });
|
|
51
|
+
return res.records
|
|
52
|
+
.filter((r) => typeof r.get("eventId") === "string")
|
|
53
|
+
.map((r) => ({
|
|
54
|
+
eventId: r.get("eventId"),
|
|
55
|
+
gateArgs: r.get("gateArgs") ?? null,
|
|
56
|
+
}));
|
|
57
|
+
}
|
|
58
|
+
finally {
|
|
59
|
+
await session.close();
|
|
60
|
+
}
|
|
61
|
+
},
|
|
62
|
+
// `s.createdAt < $cutoff` is lexical, which equals chronological because
|
|
63
|
+
// every value on both sides is a `toISOString()` string of fixed width. A
|
|
64
|
+
// createdAt of any other type compares as null in Cypher, so the row drops
|
|
65
|
+
// out of the candidate set and the section is KEPT.
|
|
66
|
+
listAgedSections: async (accountId, cutoff, limit) => {
|
|
67
|
+
const session = getSession();
|
|
68
|
+
try {
|
|
69
|
+
const res = await session.run(`MATCH (s:Section)
|
|
70
|
+
WHERE s.accountId = $accountId AND s.source = 'email'
|
|
71
|
+
AND s.createdAt < $cutoff
|
|
72
|
+
OPTIONAL MATCH (a:ConversationArchive)-[:HAS_SECTION]->(s)
|
|
73
|
+
RETURN elementId(s) AS id,
|
|
74
|
+
s.gateProcessedBy AS processedBy,
|
|
75
|
+
CASE WHEN a IS NULL THEN NULL ELSE coalesce(a.gateProcessedBy, []) END
|
|
76
|
+
AS parentProcessedBy
|
|
77
|
+
ORDER BY s.createdAt ASC
|
|
78
|
+
LIMIT $limit`, { accountId, cutoff, limit: neo4j.int(limit) });
|
|
79
|
+
return res.records.map((r) => {
|
|
80
|
+
const parent = r.get("parentProcessedBy");
|
|
81
|
+
return {
|
|
82
|
+
id: r.get("id"),
|
|
83
|
+
processedBy: flagList(r.get("processedBy")),
|
|
84
|
+
parentProcessedBy: parent === null || parent === undefined ? null : flagList(parent),
|
|
85
|
+
};
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
finally {
|
|
89
|
+
await session.close();
|
|
90
|
+
}
|
|
91
|
+
},
|
|
92
|
+
// The repair and the delete, in ONE write transaction.
|
|
93
|
+
//
|
|
94
|
+
// Sections are chained by :NEXT, and the next ingest finds the tail by
|
|
95
|
+
// looking for one with no outgoing :NEXT, LIMIT 1
|
|
96
|
+
// (memory-ingest.ts:1734-1742). Deleting from the middle of a chain leaves
|
|
97
|
+
// TWO such nodes, so a later ingest could chain new content onto a middle
|
|
98
|
+
// section. The repair connects each surviving predecessor to the first
|
|
99
|
+
// surviving section after the deleted span, shortest span first.
|
|
100
|
+
//
|
|
101
|
+
// It must run BEFORE the delete, because it walks the very edges the delete
|
|
102
|
+
// removes — and therefore inside the same transaction as the delete, because
|
|
103
|
+
// between the two the predecessor holds an edge to the doomed section AND
|
|
104
|
+
// its new edge to the target. A failure between them would leave that fork
|
|
105
|
+
// committed, and a routine added before the next cycle would make the
|
|
106
|
+
// sections outstanding again, so nothing would ever come back to repair it.
|
|
107
|
+
//
|
|
108
|
+
// Both statements carry `accountId` beside the element ids, the way
|
|
109
|
+
// `flagProcessedNodes` does (scheduling/mcp/src/lib/gate-flag.ts:100-104).
|
|
110
|
+
// The ids are already account-scoped by `listAgedSections`; the predicate is
|
|
111
|
+
// here so the scope is a property of the DELETE itself and not of the
|
|
112
|
+
// caller's discipline.
|
|
113
|
+
pruneSections: async (accountId, ids) => {
|
|
114
|
+
const session = getSession();
|
|
115
|
+
try {
|
|
116
|
+
return await session.executeWrite(async (tx) => {
|
|
117
|
+
const repair = await tx.run(`MATCH (p:Section)-[:NEXT]->(first:Section)
|
|
118
|
+
WHERE first.accountId = $accountId
|
|
119
|
+
AND elementId(first) IN $ids AND NOT elementId(p) IN $ids
|
|
120
|
+
MATCH path = (first)-[:NEXT*0..${RETENTION_CHAIN_HOPS}]->(q:Section)
|
|
121
|
+
WHERE NOT elementId(q) IN $ids
|
|
122
|
+
AND all(n IN nodes(path)[0..-1] WHERE elementId(n) IN $ids)
|
|
123
|
+
WITH p, q, length(path) AS len
|
|
124
|
+
ORDER BY len ASC
|
|
125
|
+
WITH p, head(collect(q)) AS target
|
|
126
|
+
MERGE (p)-[r:NEXT]->(target)
|
|
127
|
+
ON CREATE SET r.createdByAgent = 'email-retention', r.createdAt = $now
|
|
128
|
+
RETURN count(r) AS repaired`, { accountId, ids, now: now().toISOString() });
|
|
129
|
+
const del = await tx.run(`MATCH (s:Section)
|
|
130
|
+
WHERE s.accountId = $accountId AND s.source = 'email'
|
|
131
|
+
AND elementId(s) IN $ids
|
|
132
|
+
DETACH DELETE s
|
|
133
|
+
RETURN count(s) AS pruned`, { accountId, ids });
|
|
134
|
+
return {
|
|
135
|
+
repaired: repair.records[0]?.get("repaired")?.toNumber?.() ?? 0,
|
|
136
|
+
pruned: del.records[0]?.get("pruned")?.toNumber?.() ?? 0,
|
|
137
|
+
};
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
finally {
|
|
141
|
+
await session.close();
|
|
142
|
+
}
|
|
143
|
+
},
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
//# sourceMappingURL=retention-sources.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"retention-sources.js","sourceRoot":"","sources":["../../src/sampler/retention-sources.ts"],"names":[],"mappings":"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"}
|