@rubytech/create-maxy-code 0.1.472 → 0.1.474
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__/google-client-id-env.test.js +15 -12
- package/dist/index.js +6 -29
- package/dist/port-resolution.js +5 -5
- package/package.json +1 -1
- package/payload/platform/config/brand.json +1 -0
- package/payload/platform/docs/superpowers/plans/2026-07-18-ledger-write-path-fix.md +109 -0
- package/payload/platform/lib/ledger-core/dist/reconcile.d.ts +7 -0
- package/payload/platform/lib/ledger-core/dist/reconcile.d.ts.map +1 -1
- package/payload/platform/lib/ledger-core/dist/reconcile.js +5 -2
- package/payload/platform/lib/ledger-core/dist/reconcile.js.map +1 -1
- package/payload/platform/lib/ledger-core/src/__tests__/reconcile.test.ts +20 -0
- package/payload/platform/lib/ledger-core/src/reconcile.ts +12 -2
- package/payload/platform/neo4j/schema.cypher +4 -1
- package/payload/platform/plugins/admin/skills/platform-architecture/SKILL.md +37 -14
- package/payload/platform/plugins/docs/references/admin-ui.md +1 -1
- package/payload/platform/plugins/docs/references/google-guide.md +20 -9
- package/payload/platform/plugins/docs/references/ledger.md +9 -1
- package/payload/platform/plugins/docs/references/troubleshooting.md +4 -0
- package/payload/platform/plugins/docs/references/voice-mirror-guide.md +2 -2
- package/payload/platform/plugins/google/.claude-plugin/plugin.json +1 -1
- package/payload/platform/plugins/google/PLUGIN.md +28 -14
- package/payload/platform/plugins/google/mcp/dist/__tests__/account-register.test.js +79 -28
- package/payload/platform/plugins/google/mcp/dist/__tests__/account-register.test.js.map +1 -1
- package/payload/platform/plugins/google/mcp/dist/__tests__/boot.test.d.ts +2 -0
- package/payload/platform/plugins/google/mcp/dist/__tests__/boot.test.d.ts.map +1 -0
- package/payload/platform/plugins/google/mcp/dist/__tests__/boot.test.js +54 -0
- package/payload/platform/plugins/google/mcp/dist/__tests__/boot.test.js.map +1 -0
- package/payload/platform/plugins/google/mcp/dist/__tests__/google-client.test.js +26 -1
- package/payload/platform/plugins/google/mcp/dist/__tests__/google-client.test.js.map +1 -1
- package/payload/platform/plugins/google/mcp/dist/__tests__/index-registration.test.js +3 -2
- package/payload/platform/plugins/google/mcp/dist/__tests__/index-registration.test.js.map +1 -1
- package/payload/platform/plugins/google/mcp/dist/index.d.ts +9 -5
- package/payload/platform/plugins/google/mcp/dist/index.d.ts.map +1 -1
- package/payload/platform/plugins/google/mcp/dist/index.js +38 -37
- package/payload/platform/plugins/google/mcp/dist/index.js.map +1 -1
- package/payload/platform/plugins/google/mcp/dist/lib/google-client.d.ts +10 -7
- package/payload/platform/plugins/google/mcp/dist/lib/google-client.d.ts.map +1 -1
- package/payload/platform/plugins/google/mcp/dist/lib/google-client.js +25 -13
- package/payload/platform/plugins/google/mcp/dist/lib/google-client.js.map +1 -1
- package/payload/platform/plugins/google/mcp/dist/tools/account-register.d.ts +58 -17
- package/payload/platform/plugins/google/mcp/dist/tools/account-register.d.ts.map +1 -1
- package/payload/platform/plugins/google/mcp/dist/tools/account-register.js +143 -37
- package/payload/platform/plugins/google/mcp/dist/tools/account-register.js.map +1 -1
- package/payload/platform/plugins/google/references/auth.md +264 -362
- package/payload/platform/plugins/ledger/PLUGIN.md +13 -1
- package/payload/platform/plugins/ledger/mcp/dist/index.js +23 -15
- package/payload/platform/plugins/ledger/mcp/dist/index.js.map +1 -1
- package/payload/platform/plugins/ledger/mcp/dist/lib/read.d.ts +11 -1
- package/payload/platform/plugins/ledger/mcp/dist/lib/read.d.ts.map +1 -1
- package/payload/platform/plugins/ledger/mcp/dist/lib/read.js +20 -1
- package/payload/platform/plugins/ledger/mcp/dist/lib/read.js.map +1 -1
- package/payload/platform/plugins/ledger/mcp/dist/lib/types.d.ts +14 -11
- package/payload/platform/plugins/ledger/mcp/dist/lib/types.d.ts.map +1 -1
- package/payload/platform/plugins/ledger/mcp/dist/lib/types.js.map +1 -1
- package/payload/platform/plugins/ledger/mcp/dist/lib/write-rejects.d.ts +12 -0
- package/payload/platform/plugins/ledger/mcp/dist/lib/write-rejects.d.ts.map +1 -0
- package/payload/platform/plugins/ledger/mcp/dist/lib/write-rejects.js +50 -0
- package/payload/platform/plugins/ledger/mcp/dist/lib/write-rejects.js.map +1 -0
- package/payload/platform/plugins/ledger/mcp/dist/tools/cash-record.d.ts +5 -5
- package/payload/platform/plugins/ledger/mcp/dist/tools/cash-record.d.ts.map +1 -1
- package/payload/platform/plugins/ledger/mcp/dist/tools/cash-record.js +11 -11
- package/payload/platform/plugins/ledger/mcp/dist/tools/cash-record.js.map +1 -1
- package/payload/platform/plugins/ledger/mcp/dist/tools/invoice-record.d.ts +7 -2
- package/payload/platform/plugins/ledger/mcp/dist/tools/invoice-record.d.ts.map +1 -1
- package/payload/platform/plugins/ledger/mcp/dist/tools/invoice-record.js +9 -3
- package/payload/platform/plugins/ledger/mcp/dist/tools/invoice-record.js.map +1 -1
- package/payload/platform/plugins/ledger/mcp/dist/tools/payment-record.d.ts +7 -0
- package/payload/platform/plugins/ledger/mcp/dist/tools/payment-record.d.ts.map +1 -1
- package/payload/platform/plugins/ledger/mcp/dist/tools/payment-record.js +3 -4
- package/payload/platform/plugins/ledger/mcp/dist/tools/payment-record.js.map +1 -1
- package/payload/platform/plugins/ledger/mcp/dist/tools/reconcile.d.ts +1 -1
- package/payload/platform/plugins/ledger/mcp/dist/tools/reconcile.d.ts.map +1 -1
- package/payload/platform/plugins/ledger/mcp/dist/tools/reconcile.js +4 -1
- package/payload/platform/plugins/ledger/mcp/dist/tools/reconcile.js.map +1 -1
- package/payload/platform/plugins/voice-mirror/PLUGIN.md +1 -1
- package/payload/platform/plugins/voice-mirror/mcp/dist/index.js +3 -3
- package/payload/platform/plugins/voice-mirror/mcp/dist/index.js.map +1 -1
- package/payload/platform/plugins/voice-mirror/mcp/dist/lib/voice-corpus.d.ts +14 -1
- package/payload/platform/plugins/voice-mirror/mcp/dist/lib/voice-corpus.d.ts.map +1 -1
- package/payload/platform/plugins/voice-mirror/mcp/dist/lib/voice-corpus.js +15 -0
- package/payload/platform/plugins/voice-mirror/mcp/dist/lib/voice-corpus.js.map +1 -1
- package/payload/platform/plugins/voice-mirror/mcp/dist/tools/voice-distil-profile.d.ts.map +1 -1
- package/payload/platform/plugins/voice-mirror/mcp/dist/tools/voice-distil-profile.js +3 -1
- package/payload/platform/plugins/voice-mirror/mcp/dist/tools/voice-distil-profile.js.map +1 -1
- package/payload/platform/plugins/voice-mirror/mcp/scripts/smoke.mjs +51 -4
- package/payload/platform/plugins/voice-mirror/skills/voice-mirror/SKILL.md +4 -0
- package/payload/platform/scripts/backfill-task-ids.sh +206 -0
- package/payload/platform/services/claude-session-manager/dist/activity-rows.d.ts +27 -2
- package/payload/platform/services/claude-session-manager/dist/activity-rows.d.ts.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/activity-rows.js +33 -2
- package/payload/platform/services/claude-session-manager/dist/activity-rows.js.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.d.ts.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.js +1 -0
- package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.js.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/http-server.d.ts.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/http-server.js +3 -0
- package/payload/platform/services/claude-session-manager/dist/http-server.js.map +1 -1
- package/payload/platform/templates/specialists/agents/personal-assistant.md +1 -1
- package/payload/server/{chunk-BSTIQX52.js → chunk-Y6V45R6M.js} +1 -12
- package/payload/server/maxy-edge.js +1 -1
- package/payload/server/public/activity.html +6 -6
- package/payload/server/public/assets/{AdminLoginScreens-BfamGqS7.js → AdminLoginScreens-B44KbEuC.js} +1 -1
- package/payload/server/public/assets/{AdminShell-5nHOAzXO.js → AdminShell-BjxV2qkb.js} +2 -2
- package/payload/server/public/assets/{Checkbox-CD6aHwac.js → Checkbox-DSeZNGNA.js} +1 -1
- package/payload/server/public/assets/activity-CdipMTDp.js +1 -0
- package/payload/server/public/assets/{admin-Cpcw_YE-.js → admin-B4LpTCur.js} +1 -1
- package/payload/server/public/assets/{browser-0znOwk1W.js → browser-CEFvaWwI.js} +1 -1
- package/payload/server/public/assets/{calendar-CykigHdg.js → calendar-B3zo6V34.js} +1 -1
- package/payload/server/public/assets/chat-5tJdo9i_.js +1 -0
- package/payload/server/public/assets/chevron-left-BJllrPBj.js +1 -0
- package/payload/server/public/assets/data-Du79EgR-.js +1 -0
- package/payload/server/public/assets/{graph-JV5_xF3V.js → graph-RaOrnSf2.js} +1 -1
- package/payload/server/public/assets/{graph-labels-DPYORjBH.js → graph-labels-GlTEIYJj.js} +1 -1
- package/payload/server/public/assets/{maximize-2-8vKr3h21.js → maximize-2-CHDa8p5h.js} +1 -1
- package/payload/server/public/assets/{operator-Liul1QEq.js → operator-DtqHY4jV.js} +1 -1
- package/payload/server/public/assets/{page-CYRA87CB.js → page-CkhFj8GQ.js} +1 -1
- package/payload/server/public/assets/{page-Cg7B1RQx.js → page-DxnWgPtd.js} +1 -1
- package/payload/server/public/assets/{public-B4HMtpjt.js → public-D5TUfQ3I.js} +1 -1
- package/payload/server/public/assets/{rotate-ccw-sz5IQSnr.js → rotate-ccw-BJjVAQQY.js} +1 -1
- package/payload/server/public/assets/tasks-CM9pYYG1.js +1 -0
- package/payload/server/public/assets/{time-entry-format-CSuCexpM.js → time-entry-format-C5RYEYjM.js} +1 -1
- package/payload/server/public/assets/{triangle-alert-ClS81-CU.js → triangle-alert-DLfIsuo_.js} +1 -1
- package/payload/server/public/assets/{useCopyFeedback-Cn6YgeNx.js → useCopyFeedback-7yKeiAzV.js} +1 -1
- package/payload/server/public/assets/{useSelectionMode-BaD-ZZRk.js → useSelectionMode-CWlh6AEq.js} +1 -1
- package/payload/server/public/assets/{useSubAccountSwitcher-CNZL3PKn.css → useSubAccountSwitcher-B2n9QPVI.css} +1 -1
- package/payload/server/public/assets/{useVoiceRecorder-BOzHrDAU.js → useVoiceRecorder-j3ZArZ2H.js} +1 -1
- package/payload/server/public/browser.html +5 -5
- package/payload/server/public/calendar.html +6 -6
- package/payload/server/public/chat.html +12 -12
- package/payload/server/public/data.html +11 -11
- package/payload/server/public/graph.html +11 -11
- package/payload/server/public/index.html +14 -14
- package/payload/server/public/operator.html +14 -14
- package/payload/server/public/public.html +12 -12
- package/payload/server/public/tasks.html +5 -5
- package/payload/server/server.js +1837 -1695
- package/payload/server/public/assets/activity-Dj2nJzPw.js +0 -1
- package/payload/server/public/assets/chat-DIOJZ411.js +0 -1
- package/payload/server/public/assets/chevron-left-Cq7UvOI0.js +0 -1
- package/payload/server/public/assets/data-lHgqlhmu.js +0 -1
- package/payload/server/public/assets/tasks-D9oYgEzs.js +0 -1
- /package/payload/server/public/assets/{useSubAccountSwitcher-CvjWJSGv.js → useSubAccountSwitcher-CBlKgwms.js} +0 -0
|
@@ -63,6 +63,16 @@ An `InvoicePayment` reached from an `Invoice` is money received. The same label
|
|
|
63
63
|
|
|
64
64
|
`CashEntry` does carry `direction`, because it has no parent invoice to derive one from.
|
|
65
65
|
|
|
66
|
+
## The counterparty is passed by id, never by name
|
|
67
|
+
|
|
68
|
+
`ledger-invoice-record` and `ledger-cash-record` take the element id of an existing `Organization` or `Person`, and nothing else about them. The ledger never creates or matches them: look the counterparty up first with `memory-search` or `contact-lookup` and pass the id you find.
|
|
69
|
+
|
|
70
|
+
The display name stored on the invoice is read from that node, not passed as a second argument. One lookup feeds both the stored name and the link, so an invoice cannot read as one company while pointing at another. An id that does not exist on this account is refused with `reason=unknown-counterparty` before anything is written.
|
|
71
|
+
|
|
72
|
+
This is a deliberate boundary, not a convenience gap. The ledger records money; deciding whether "Beagle Direct Ltd" is the same company as an existing "Beagle Direct" is entity resolution, and doing it badly inside a write tool creates duplicate organisations that then split a payment history in two.
|
|
73
|
+
|
|
74
|
+
A `CashEntry` must have a counterparty for a second reason: graph-write refuses a write with no relationship at all, so an unlinked entry cannot be stored.
|
|
75
|
+
|
|
66
76
|
## Over-application is refused
|
|
67
77
|
|
|
68
78
|
A payment that would take applied-to-date above the invoice total is rejected. It is never clamped to the remaining amount and never recorded anyway. The refusal names the figure that would settle the invoice, so the operator can correct it in one step.
|
|
@@ -75,7 +85,9 @@ After writing a payment, the tool re-reads the invoice from the graph and compar
|
|
|
75
85
|
|
|
76
86
|
Four ways this can fail emit no event at all: a write narrated but never landed, a payment with no parent invoice, a stored balance property that has reappeared, and a duplicate payment created under a second id. None of them can be caught by logging an action, because no action occurs.
|
|
77
87
|
|
|
78
|
-
A `[ledger-census]` line is emitted every 15 minutes by the UI server, carrying counts for each, plus any ledger index declared in `schema.cypher` but absent from this database
|
|
88
|
+
A `[ledger-census]` line is emitted every 15 minutes by the UI server, carrying counts for each, plus any ledger index declared in `schema.cypher` but absent from this database, plus `writeRejects24h`.
|
|
89
|
+
|
|
90
|
+
That last counter exists because of a real failure. On 2026-07-18 every ledger write was rejected for a full day while the census reported `invoices=0 payments=0`, which is byte-identical to a healthy ledger nobody has used yet. A rejected write leaves nothing in the graph by definition, so the count is read from the plugin's own log rather than from Neo4j. `alarm=true` on that line means one of them has happened. `ledger-reconcile` is the same check on demand, sharing the same reconcile and the same line formatter.
|
|
79
91
|
|
|
80
92
|
Registration drift between `PLUGIN.md`, the generated canonical-tool-names artifact and the specialist templates is **not** a census signal. It is caught at build time by `platform/scripts/check-canonical-tool-names.mjs` and `check-specialist-tool-surface.mjs`. A runtime counter for it was removed after review: the census runs in the UI server, which has no view of MCP spawns, so the counter could only ever have compared a constant against itself and reported healthy.
|
|
81
93
|
|
|
@@ -4,7 +4,7 @@ import { eagerTool } from "../../../../lib/mcp-eager/dist/index.js";
|
|
|
4
4
|
import { writeNodeWithEdges } from "../../../../lib/graph-write/dist/index.js";
|
|
5
5
|
import { z } from "zod";
|
|
6
6
|
import { closeDriver, getSession } from "./lib/neo4j.js";
|
|
7
|
-
import { readCensus, readInvoice, readStatement, setPaymentStatus, verifyOutstanding, } from "./lib/read.js";
|
|
7
|
+
import { readCensus, readCounterpartyName, readInvoice, readStatement, setPaymentStatus, verifyOutstanding, } from "./lib/read.js";
|
|
8
8
|
import { invoiceRecord } from "./tools/invoice-record.js";
|
|
9
9
|
import { paymentRecord } from "./tools/payment-record.js";
|
|
10
10
|
import { cashRecord } from "./tools/cash-record.js";
|
|
@@ -32,15 +32,21 @@ function refuseNoAccount(toolName) {
|
|
|
32
32
|
isError: true,
|
|
33
33
|
};
|
|
34
34
|
}
|
|
35
|
+
// `agent` stays undefined when AGENT_SLUG is unset rather than defaulting to
|
|
36
|
+
// "". graph-write resolves `agent ?? source ?? "unknown"`, and an empty string
|
|
37
|
+
// is not nullish, so the old default printed a blank `agent=` on every reject
|
|
38
|
+
// and defeated the fallback entirely.
|
|
35
39
|
const createdBy = (tool) => ({
|
|
36
|
-
agent: agentSlug
|
|
37
|
-
session: sessionId
|
|
40
|
+
agent: agentSlug,
|
|
41
|
+
session: sessionId,
|
|
38
42
|
tool,
|
|
43
|
+
source: "ledger",
|
|
39
44
|
});
|
|
40
|
-
//
|
|
41
|
-
//
|
|
42
|
-
//
|
|
43
|
-
|
|
45
|
+
// No cast. Task 1788: the previous version cast writeNodeWithEdges to accept
|
|
46
|
+
// this plugin's own relationship shape, under a comment claiming the params
|
|
47
|
+
// were structurally identical. They were not, and the cast is what let a dead
|
|
48
|
+
// write path ship.
|
|
49
|
+
const write = writeNodeWithEdges;
|
|
44
50
|
async function withSession(fn) {
|
|
45
51
|
const session = getSession();
|
|
46
52
|
try {
|
|
@@ -55,7 +61,10 @@ eagerTool(server, "ledger-invoice-record", "Record an invoice you raised (direct
|
|
|
55
61
|
.enum(["receivable", "payable"])
|
|
56
62
|
.describe("'receivable' is money owed to you; 'payable' is money you owe"),
|
|
57
63
|
confirmationNumber: z.string().min(1).describe("Invoice or bill reference, e.g. INV-2026-014"),
|
|
58
|
-
|
|
64
|
+
counterpartyNodeId: z
|
|
65
|
+
.string()
|
|
66
|
+
.min(1)
|
|
67
|
+
.describe("Element id of the existing Organization. Look it up first (memory-search or contact-lookup) — this tool never creates or matches organisations, so passing a name alone will not work"),
|
|
59
68
|
totalPaymentDue: z.number().positive().describe("Face value of the whole bill"),
|
|
60
69
|
dueDate: z.string().describe("ISO date the payment falls due, e.g. 2026-08-01"),
|
|
61
70
|
description: z.string().optional().describe("What the invoice is for"),
|
|
@@ -65,6 +74,7 @@ eagerTool(server, "ledger-invoice-record", "Record an invoice you raised (direct
|
|
|
65
74
|
return withSession((session) => invoiceRecord({
|
|
66
75
|
session,
|
|
67
76
|
write,
|
|
77
|
+
readName: readCounterpartyName,
|
|
68
78
|
accountId,
|
|
69
79
|
createdBy: createdBy("ledger-invoice-record"),
|
|
70
80
|
...args,
|
|
@@ -98,7 +108,6 @@ eagerTool(server, "ledger-credit-record", "Apply a credit note to an invoice you
|
|
|
98
108
|
}, async (args) => {
|
|
99
109
|
if (accountId === null)
|
|
100
110
|
return refuseNoAccount("ledger-credit-record");
|
|
101
|
-
const { reason: _reason, ...rest } = args;
|
|
102
111
|
return withSession((session) => paymentRecord({
|
|
103
112
|
session,
|
|
104
113
|
read: readInvoice,
|
|
@@ -108,7 +117,7 @@ eagerTool(server, "ledger-credit-record", "Apply a credit note to an invoice you
|
|
|
108
117
|
accountId,
|
|
109
118
|
createdBy: createdBy("ledger-credit-record"),
|
|
110
119
|
kind: "credit",
|
|
111
|
-
...
|
|
120
|
+
...args,
|
|
112
121
|
// After the spread: the credit schema exposes no paymentType, so this
|
|
113
122
|
// is the only source of it and must not be overwritten by the cast.
|
|
114
123
|
paymentType: "credit",
|
|
@@ -119,11 +128,10 @@ eagerTool(server, "ledger-cash-record", "Record money in or out that is not atta
|
|
|
119
128
|
amount: z.number().positive().describe("Amount — always positive; direction carries the sign"),
|
|
120
129
|
date: z.string().describe("ISO date of the movement"),
|
|
121
130
|
description: z.string().min(1).describe("What it was for"),
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
.
|
|
125
|
-
.
|
|
126
|
-
.describe("Whether the counterparty is a person or a business; defaults to organization"),
|
|
131
|
+
counterpartyNodeId: z
|
|
132
|
+
.string()
|
|
133
|
+
.min(1)
|
|
134
|
+
.describe("Element id of the person or organisation this movement was with. Required — an entry linked to nothing cannot be stored"),
|
|
127
135
|
}, async (args) => {
|
|
128
136
|
if (accountId === null)
|
|
129
137
|
return refuseNoAccount("ledger-cash-record");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,kBAAkB,EAAE,MAAM,2CAA2C,CAAC;AAC/E,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AACzD,OAAO,EACL,UAAU,EACV,WAAW,EACX,aAAa,EACb,gBAAgB,EAChB,iBAAiB,GAClB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC1D,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC1D,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACpD,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAC7C,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACjD,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -10,6 +10,16 @@ import type { Session } from "neo4j-driver";
|
|
|
10
10
|
import type { InvoiceRead } from "../tools/payment-record.js";
|
|
11
11
|
import type { StatementRows } from "../tools/statement.js";
|
|
12
12
|
import type { LedgerCensusRows } from "../../../../../lib/ledger-core/dist/index.js";
|
|
13
|
+
/**
|
|
14
|
+
* The display name of a counterparty node, or null if that element id does not
|
|
15
|
+
* exist on this account.
|
|
16
|
+
*
|
|
17
|
+
* The invoice stores this name AND links to this node, so both must come from
|
|
18
|
+
* one lookup. Taking the name from a separate argument would let an invoice
|
|
19
|
+
* read as one company while pointing at another, and the account filter is
|
|
20
|
+
* what stops an id from a neighbouring account resolving at all.
|
|
21
|
+
*/
|
|
22
|
+
export declare function readCounterpartyName(session: Session, accountId: string, nodeId: string): Promise<string | null>;
|
|
13
23
|
export declare function readInvoice(session: Session, accountId: string, ref: string): Promise<InvoiceRead | null>;
|
|
14
24
|
/** The op=verify re-read. Deliberately goes back to the graph rather than
|
|
15
25
|
* trusting the figure the write path just computed. */
|
|
@@ -25,5 +35,5 @@ export declare function readStatement(session: Session, accountId: string): Prom
|
|
|
25
35
|
* invoice, payments that look like accidental duplicates, and ledger indexes
|
|
26
36
|
* that are declared in schema.cypher but absent from this database.
|
|
27
37
|
*/
|
|
28
|
-
export declare function readCensus(session: Session, accountId: string): Promise<LedgerCensusRows>;
|
|
38
|
+
export declare function readCensus(session: Session, accountId: string, now: number): Promise<LedgerCensusRows>;
|
|
29
39
|
//# sourceMappingURL=read.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"read.d.ts","sourceRoot":"","sources":["../../src/lib/read.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAC9D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,8CAA8C,CAAC;
|
|
1
|
+
{"version":3,"file":"read.d.ts","sourceRoot":"","sources":["../../src/lib/read.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAC9D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,8CAA8C,CAAC;AAgBrF;;;;;;;;GAQG;AACH,wBAAsB,oBAAoB,CACxC,OAAO,EAAE,OAAO,EAChB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAQxB;AAED,wBAAsB,WAAW,CAC/B,OAAO,EAAE,OAAO,EAChB,SAAS,EAAE,MAAM,EACjB,GAAG,EAAE,MAAM,GACV,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,CAkC7B;AAED;wDACwD;AACxD,wBAAsB,iBAAiB,CACrC,OAAO,EAAE,OAAO,EAChB,SAAS,EAAE,MAAM,EACjB,GAAG,EAAE,MAAM,GACV,OAAO,CAAC,MAAM,CAAC,CAIjB;AAED;;4BAE4B;AAC5B,wBAAsB,gBAAgB,CACpC,OAAO,EAAE,OAAO,EAChB,SAAS,EAAE,MAAM,EACjB,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,MAAM,GAAG,WAAW,GAAG,MAAM,GACpC,OAAO,CAAC,IAAI,CAAC,CAMf;AAED,wBAAsB,aAAa,CACjC,OAAO,EAAE,OAAO,EAChB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,aAAa,CAAC,CA6CxB;AAED;;;;;GAKG;AACH,wBAAsB,UAAU,CAC9B,OAAO,EAAE,OAAO,EAChB,SAAS,EAAE,MAAM,EACjB,GAAG,EAAE,MAAM,GACV,OAAO,CAAC,gBAAgB,CAAC,CAsD3B"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { LEDGER_INDEX_NAMES, computeOutstanding, } from "../../../../../lib/ledger-core/dist/index.js";
|
|
2
|
+
import { countWriteRejects24h } from "./write-rejects.js";
|
|
2
3
|
/** neo4j-driver returns Integer objects for counts; numbers pass through. */
|
|
3
4
|
function toNum(v) {
|
|
4
5
|
if (typeof v === "number")
|
|
@@ -8,6 +9,21 @@ function toNum(v) {
|
|
|
8
9
|
}
|
|
9
10
|
return 0;
|
|
10
11
|
}
|
|
12
|
+
/**
|
|
13
|
+
* The display name of a counterparty node, or null if that element id does not
|
|
14
|
+
* exist on this account.
|
|
15
|
+
*
|
|
16
|
+
* The invoice stores this name AND links to this node, so both must come from
|
|
17
|
+
* one lookup. Taking the name from a separate argument would let an invoice
|
|
18
|
+
* read as one company while pointing at another, and the account filter is
|
|
19
|
+
* what stops an id from a neighbouring account resolving at all.
|
|
20
|
+
*/
|
|
21
|
+
export async function readCounterpartyName(session, accountId, nodeId) {
|
|
22
|
+
const res = await session.run(`MATCH (o) WHERE elementId(o) = $nodeId AND o.accountId = $accountId
|
|
23
|
+
RETURN coalesce(o.name, trim(coalesce(o.givenName, "") + " " + coalesce(o.familyName, ""))) AS name`, { accountId, nodeId });
|
|
24
|
+
const name = res.records[0]?.get("name");
|
|
25
|
+
return typeof name === "string" && name.trim() !== "" ? name.trim() : null;
|
|
26
|
+
}
|
|
11
27
|
export async function readInvoice(session, accountId, ref) {
|
|
12
28
|
// Staged WITH: payments collapse to one row before the credit match expands
|
|
13
29
|
// again, so the two OPTIONAL MATCHes never form a cartesian product that
|
|
@@ -18,6 +34,7 @@ export async function readInvoice(session, accountId, ref) {
|
|
|
18
34
|
OPTIONAL MATCH (i)-[:HAS_CREDIT]->(c:Credit)
|
|
19
35
|
WITH i, ps, collect(DISTINCT c) AS cs
|
|
20
36
|
RETURN labels(i) AS labels,
|
|
37
|
+
elementId(i) AS nodeId,
|
|
21
38
|
i.confirmationNumber AS invoiceId,
|
|
22
39
|
i.totalPaymentDue AS totalPaymentDue,
|
|
23
40
|
i.dueDate AS dueDate,
|
|
@@ -30,6 +47,7 @@ export async function readInvoice(session, accountId, ref) {
|
|
|
30
47
|
const labels = rec.get("labels");
|
|
31
48
|
return {
|
|
32
49
|
label: labels.includes("InboundInvoice") ? "InboundInvoice" : "Invoice",
|
|
50
|
+
nodeId: rec.get("nodeId"),
|
|
33
51
|
invoiceId: rec.get("invoiceId"),
|
|
34
52
|
totalPaymentDue: toNum(rec.get("totalPaymentDue")),
|
|
35
53
|
dueDateMs: Date.parse(rec.get("dueDate") ?? "") || 0,
|
|
@@ -97,7 +115,7 @@ export async function readStatement(session, accountId) {
|
|
|
97
115
|
* invoice, payments that look like accidental duplicates, and ledger indexes
|
|
98
116
|
* that are declared in schema.cypher but absent from this database.
|
|
99
117
|
*/
|
|
100
|
-
export async function readCensus(session, accountId) {
|
|
118
|
+
export async function readCensus(session, accountId, now) {
|
|
101
119
|
const counts = await session.run(
|
|
102
120
|
// OPTIONAL MATCH, not MATCH: with no payments a plain MATCH eliminates the
|
|
103
121
|
// row, so records[0] is undefined and invoices reports 0 as well. That is
|
|
@@ -133,6 +151,7 @@ export async function readCensus(session, accountId) {
|
|
|
133
151
|
date: r.get("date") ?? "",
|
|
134
152
|
})),
|
|
135
153
|
declaredNotLive,
|
|
154
|
+
writeRejects24h: countWriteRejects24h(process.env.LOG_DIR ?? "", now),
|
|
136
155
|
};
|
|
137
156
|
}
|
|
138
157
|
//# sourceMappingURL=read.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"read.js","sourceRoot":"","sources":["../../src/lib/read.ts"],"names":[],"mappings":"AAYA,OAAO,EACL,kBAAkB,EAClB,kBAAkB,GACnB,MAAM,8CAA8C,CAAC;
|
|
1
|
+
{"version":3,"file":"read.js","sourceRoot":"","sources":["../../src/lib/read.ts"],"names":[],"mappings":"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"}
|
|
@@ -6,17 +6,20 @@
|
|
|
6
6
|
* driver. `index.ts` passes the real `writeNodeWithEdges` and the real reads.
|
|
7
7
|
*/
|
|
8
8
|
import type { Session } from "neo4j-driver";
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
9
|
+
/**
|
|
10
|
+
* Task 1788 — the real graph-write contracts, imported rather than redeclared.
|
|
11
|
+
*
|
|
12
|
+
* This file used to declare its own `GraphRelationship` with
|
|
13
|
+
* `targetLabel`/`targetProps`, and `index.ts` forced it past the type checker
|
|
14
|
+
* with a cast. The real shape needs `targetNodeId`, an element id, so at
|
|
15
|
+
* runtime every relationship carried `undefined` and graph-write rejected every
|
|
16
|
+
* create with `reason=unresolved-target requested=1 found=0`. The whole write
|
|
17
|
+
* path was dead from the day it shipped. Importing the real types is what makes
|
|
18
|
+
* that a compile error instead of a silent runtime rejection, so the redeclared
|
|
19
|
+
* shape must never come back.
|
|
20
|
+
*/
|
|
21
|
+
import type { CreatedBy, GraphRelationship } from "../../../../../lib/graph-write/dist/index.js";
|
|
22
|
+
export type { CreatedBy, GraphRelationship };
|
|
20
23
|
export interface WriteParams {
|
|
21
24
|
session: Session;
|
|
22
25
|
labels: string[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/lib/types.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/lib/types.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAC5C;;;;;;;;;;;GAWG;AACH,OAAO,KAAK,EACV,SAAS,EACT,iBAAiB,EAClB,MAAM,8CAA8C,CAAC;AAEtD,YAAY,EAAE,SAAS,EAAE,iBAAiB,EAAE,CAAC;AAE7C,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,aAAa,EAAE,iBAAiB,EAAE,CAAC;IACnC,SAAS,EAAE,SAAS,CAAC;CACtB;AAED,MAAM,WAAW,WAAW;IAC1B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,MAAM,OAAO,GAAG,CAAC,MAAM,EAAE,WAAW,KAAK,OAAO,CAAC,WAAW,CAAC,CAAC;AAEpE,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC/C,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,wBAAgB,EAAE,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,CAE3C;AAED,wBAAgB,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,CAE7C;AAED,6DAA6D;AAC7D,wBAAgB,KAAK,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAEvC;AAED;mEACmE;AACnE,MAAM,MAAM,gBAAgB,GAAG,YAAY,GAAG,SAAS,CAAC;AAExD,wBAAgB,QAAQ,CAAC,SAAS,EAAE,gBAAgB,GAAG,SAAS,GAAG,gBAAgB,CAElF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/lib/types.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/lib/types.ts"],"names":[],"mappings":"AA+CA,MAAM,UAAU,EAAE,CAAC,IAAY;IAC7B,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;AAC/C,CAAC;AAED,MAAM,UAAU,IAAI,CAAC,IAAY;IAC/B,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;AAC9D,CAAC;AAED,6DAA6D;AAC7D,MAAM,UAAU,KAAK,CAAC,CAAS;IAC7B,OAAO,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;AACtB,CAAC;AAMD,MAAM,UAAU,QAAQ,CAAC,SAA2B;IAClD,OAAO,SAAS,KAAK,YAAY,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,gBAAgB,CAAC;AACnE,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Counts `[graph-write] reject` lines across the ledger MCP tee logs modified
|
|
3
|
+
* within the trailing 24 hours.
|
|
4
|
+
*
|
|
5
|
+
* Uses file mtime rather than parsing per-line timestamps: the tee log carries
|
|
6
|
+
* no timestamp of its own, and a file untouched for a day cannot hold a reject
|
|
7
|
+
* from the last one. Best-effort — an unreadable log directory yields 0 rather
|
|
8
|
+
* than throwing, because a census that dies on a missing directory tells the
|
|
9
|
+
* operator nothing at all.
|
|
10
|
+
*/
|
|
11
|
+
export declare function countWriteRejects24h(logDir: string, now: number): number;
|
|
12
|
+
//# sourceMappingURL=write-rejects.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"write-rejects.d.ts","sourceRoot":"","sources":["../../src/lib/write-rejects.ts"],"names":[],"mappings":"AAeA;;;;;;;;;GASG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAwBxE"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Task 1788 — count recent write rejections from the ledger's own MCP logs.
|
|
3
|
+
*
|
|
4
|
+
* A rejected write cannot record its own failure in the graph, because the
|
|
5
|
+
* whole point is that nothing was written. The only durable trace is the
|
|
6
|
+
* stderr line graph-write emits, which `mcp-spawn-tee` captures per session.
|
|
7
|
+
* Counting those lines is what lets the census distinguish a healthy empty
|
|
8
|
+
* ledger from one whose write path is dead — on 2026-07-18 those two states
|
|
9
|
+
* printed identically for a full day.
|
|
10
|
+
*/
|
|
11
|
+
import { readdirSync, readFileSync, statSync } from "node:fs";
|
|
12
|
+
import { join } from "node:path";
|
|
13
|
+
const DAY_MS = 86_400_000;
|
|
14
|
+
/**
|
|
15
|
+
* Counts `[graph-write] reject` lines across the ledger MCP tee logs modified
|
|
16
|
+
* within the trailing 24 hours.
|
|
17
|
+
*
|
|
18
|
+
* Uses file mtime rather than parsing per-line timestamps: the tee log carries
|
|
19
|
+
* no timestamp of its own, and a file untouched for a day cannot hold a reject
|
|
20
|
+
* from the last one. Best-effort — an unreadable log directory yields 0 rather
|
|
21
|
+
* than throwing, because a census that dies on a missing directory tells the
|
|
22
|
+
* operator nothing at all.
|
|
23
|
+
*/
|
|
24
|
+
export function countWriteRejects24h(logDir, now) {
|
|
25
|
+
let entries;
|
|
26
|
+
try {
|
|
27
|
+
entries = readdirSync(logDir).filter((f) => f.startsWith("mcp-ledger-") && f.endsWith(".log"));
|
|
28
|
+
}
|
|
29
|
+
catch {
|
|
30
|
+
return 0;
|
|
31
|
+
}
|
|
32
|
+
let total = 0;
|
|
33
|
+
for (const name of entries) {
|
|
34
|
+
const path = join(logDir, name);
|
|
35
|
+
try {
|
|
36
|
+
if (now - statSync(path).mtimeMs > DAY_MS)
|
|
37
|
+
continue;
|
|
38
|
+
for (const line of readFileSync(path, "utf8").split("\n")) {
|
|
39
|
+
if (line.includes("[graph-write] reject"))
|
|
40
|
+
total += 1;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
catch {
|
|
44
|
+
// A log rotated away mid-read is not a census failure.
|
|
45
|
+
continue;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
return total;
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=write-rejects.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"write-rejects.js","sourceRoot":"","sources":["../../src/lib/write-rejects.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAC9D,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,MAAM,MAAM,GAAG,UAAU,CAAC;AAE1B;;;;;;;;;GASG;AACH,MAAM,UAAU,oBAAoB,CAAC,MAAc,EAAE,GAAW;IAC9D,IAAI,OAAiB,CAAC;IACtB,IAAI,CAAC;QACH,OAAO,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC,MAAM,CAClC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CACzD,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,CAAC,CAAC;IACX,CAAC;IAED,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,KAAK,MAAM,IAAI,IAAI,OAAO,EAAE,CAAC;QAC3B,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;QAChC,IAAI,CAAC;YACH,IAAI,GAAG,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,OAAO,GAAG,MAAM;gBAAE,SAAS;YACpD,KAAK,MAAM,IAAI,IAAI,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;gBAC1D,IAAI,IAAI,CAAC,QAAQ,CAAC,sBAAsB,CAAC;oBAAE,KAAK,IAAI,CAAC,CAAC;YACxD,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,uDAAuD;YACvD,SAAS;QACX,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC"}
|
|
@@ -16,11 +16,11 @@ export interface CashRecordParams {
|
|
|
16
16
|
amount: number;
|
|
17
17
|
date: string;
|
|
18
18
|
description: string;
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
|
|
19
|
+
/** Element id of the existing :Person or :Organization this movement was
|
|
20
|
+
* with. Required: graph-write rejects edgeless writes, so a CashEntry with
|
|
21
|
+
* no relationship cannot be stored at all. The label is whatever the
|
|
22
|
+
* resolved node already carries, so no counterpartyType is needed. */
|
|
23
|
+
counterpartyNodeId: string;
|
|
24
24
|
}
|
|
25
25
|
export declare function cashRecord(params: CashRecordParams): Promise<ToolResult>;
|
|
26
26
|
//# sourceMappingURL=cash-record.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cash-record.d.ts","sourceRoot":"","sources":["../../src/tools/cash-record.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAE5C,OAAO,EACL,KAAK,SAAS,EAEd,KAAK,UAAU,EACf,KAAK,OAAO,EAIb,MAAM,iBAAiB,CAAC;AAEzB,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,OAAO,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,SAAS,CAAC;IACrB,SAAS,EAAE,IAAI,GAAG,KAAK,CAAC;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,
|
|
1
|
+
{"version":3,"file":"cash-record.d.ts","sourceRoot":"","sources":["../../src/tools/cash-record.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAE5C,OAAO,EACL,KAAK,SAAS,EAEd,KAAK,UAAU,EACf,KAAK,OAAO,EAIb,MAAM,iBAAiB,CAAC;AAEzB,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,OAAO,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,SAAS,CAAC;IACrB,SAAS,EAAE,IAAI,GAAG,KAAK,CAAC;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB;;;2EAGuE;IACvE,kBAAkB,EAAE,MAAM,CAAC;CAC5B;AAED,wBAAsB,UAAU,CAAC,MAAM,EAAE,gBAAgB,GAAG,OAAO,CAAC,UAAU,CAAC,CAwD9E"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { cashEntryIdFor } from "../lib/ids.js";
|
|
2
2
|
import { fail, money, ok, } from "../lib/types.js";
|
|
3
3
|
export async function cashRecord(params) {
|
|
4
|
-
const { session, write, accountId, createdBy, direction, amount, date, description,
|
|
4
|
+
const { session, write, accountId, createdBy, direction, amount, date, description, counterpartyNodeId, } = params;
|
|
5
5
|
const text = description.trim();
|
|
6
6
|
if (text === "") {
|
|
7
7
|
return fail("[ledger] op=reject reason=blank-description — a cash entry with no description is unauditable later. Nothing was written.");
|
|
@@ -9,17 +9,17 @@ export async function cashRecord(params) {
|
|
|
9
9
|
if (!(amount > 0)) {
|
|
10
10
|
return fail(`[ledger] op=reject reason=non-positive-amount amount=${amount} — direction carries the sign, so the amount is always positive. Nothing was written.`);
|
|
11
11
|
}
|
|
12
|
+
if (counterpartyNodeId.trim() === "") {
|
|
13
|
+
return fail("[ledger] op=reject reason=missing-counterparty — a cash entry needs the element id of who it was with. graph-write rejects a write with no relationship, so an unlinked entry cannot be stored. Nothing was written.");
|
|
14
|
+
}
|
|
12
15
|
const entryId = cashEntryIdFor(accountId, direction, amount, date, text);
|
|
13
|
-
const relationships =
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
targetProps: { accountId, name: counterparty.trim() },
|
|
21
|
-
},
|
|
22
|
-
];
|
|
16
|
+
const relationships = [
|
|
17
|
+
{
|
|
18
|
+
type: "COUNTERPARTY",
|
|
19
|
+
direction: "outgoing",
|
|
20
|
+
targetNodeId: counterpartyNodeId.trim(),
|
|
21
|
+
},
|
|
22
|
+
];
|
|
23
23
|
const result = await write({
|
|
24
24
|
session,
|
|
25
25
|
labels: ["CashEntry"],
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cash-record.js","sourceRoot":"","sources":["../../src/tools/cash-record.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,EAKL,IAAI,EACJ,KAAK,EACL,EAAE,GACH,MAAM,iBAAiB,CAAC;AAkBzB,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,MAAwB;IACvD,MAAM,EACJ,OAAO,EACP,KAAK,EACL,SAAS,EACT,SAAS,EACT,SAAS,EACT,MAAM,EACN,IAAI,EACJ,WAAW,EACX,
|
|
1
|
+
{"version":3,"file":"cash-record.js","sourceRoot":"","sources":["../../src/tools/cash-record.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,EAKL,IAAI,EACJ,KAAK,EACL,EAAE,GACH,MAAM,iBAAiB,CAAC;AAkBzB,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,MAAwB;IACvD,MAAM,EACJ,OAAO,EACP,KAAK,EACL,SAAS,EACT,SAAS,EACT,SAAS,EACT,MAAM,EACN,IAAI,EACJ,WAAW,EACX,kBAAkB,GACnB,GAAG,MAAM,CAAC;IAEX,MAAM,IAAI,GAAG,WAAW,CAAC,IAAI,EAAE,CAAC;IAChC,IAAI,IAAI,KAAK,EAAE,EAAE,CAAC;QAChB,OAAO,IAAI,CACT,2HAA2H,CAC5H,CAAC;IACJ,CAAC;IACD,IAAI,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,EAAE,CAAC;QAClB,OAAO,IAAI,CACT,wDAAwD,MAAM,uFAAuF,CACtJ,CAAC;IACJ,CAAC;IAED,IAAI,kBAAkB,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;QACrC,OAAO,IAAI,CACT,sNAAsN,CACvN,CAAC;IACJ,CAAC;IAED,MAAM,OAAO,GAAG,cAAc,CAAC,SAAS,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;IAEzE,MAAM,aAAa,GAAwB;QACzC;YACE,IAAI,EAAE,cAAc;YACpB,SAAS,EAAE,UAAU;YACrB,YAAY,EAAE,kBAAkB,CAAC,IAAI,EAAE;SACxC;KACF,CAAC;IAEF,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC;QACzB,OAAO;QACP,MAAM,EAAE,CAAC,WAAW,CAAC;QACrB,KAAK,EAAE,EAAE,SAAS,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE;QACzE,aAAa;QACb,SAAS;KACV,CAAC,CAAC;IAEH,OAAO,CAAC,KAAK,CACX,8CAA8C,OAAO,cAAc,SAAS,WAAW,KAAK,CAAC,MAAM,CAAC,iBAAiB,MAAM,CAAC,YAAY,IAAI,CAAC,iBAAiB,MAAM,CAAC,YAAY,IAAI,CAAC,EAAE,CACzL,CAAC;IAEF,OAAO,EAAE,CACP,YAAY,KAAK,CAAC,MAAM,CAAC,IAAI,SAAS,KAAK,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,UAAU,OAAO,IAAI,KAAK,IAAI,GAAG,CACjG,CAAC;AACJ,CAAC"}
|
|
@@ -9,16 +9,21 @@
|
|
|
9
9
|
*/
|
|
10
10
|
import type { Session } from "neo4j-driver";
|
|
11
11
|
import { type CreatedBy, type InvoiceDirection, type ToolResult, type WriteFn } from "../lib/types.js";
|
|
12
|
+
export type ReadCounterpartyNameFn = (session: Session, accountId: string, nodeId: string) => Promise<string | null>;
|
|
12
13
|
export interface InvoiceRecordParams {
|
|
13
14
|
session: Session;
|
|
14
15
|
write: WriteFn;
|
|
16
|
+
readName: ReadCounterpartyNameFn;
|
|
15
17
|
accountId: string;
|
|
16
18
|
createdBy: CreatedBy;
|
|
17
19
|
direction: InvoiceDirection;
|
|
18
20
|
/** The invoice or bill reference. Natural key with accountId. */
|
|
19
21
|
confirmationNumber: string;
|
|
20
|
-
/**
|
|
21
|
-
|
|
22
|
+
/** Element id of the existing :Organization or :Person. The tool never
|
|
23
|
+
* creates or matches them; the caller resolves this first. The display name
|
|
24
|
+
* is read from this node rather than passed alongside, so the name stored on
|
|
25
|
+
* the invoice and the node it links to cannot disagree. */
|
|
26
|
+
counterpartyNodeId: string;
|
|
22
27
|
totalPaymentDue: number;
|
|
23
28
|
dueDate: string;
|
|
24
29
|
description?: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"invoice-record.d.ts","sourceRoot":"","sources":["../../src/tools/invoice-record.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EACL,KAAK,SAAS,EAEd,KAAK,gBAAgB,EACrB,KAAK,UAAU,EACf,KAAK,OAAO,EAKb,MAAM,iBAAiB,CAAC;AAEzB,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,OAAO,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,SAAS,CAAC;IACrB,SAAS,EAAE,gBAAgB,CAAC;IAC5B,iEAAiE;IACjE,kBAAkB,EAAE,MAAM,CAAC;IAC3B
|
|
1
|
+
{"version":3,"file":"invoice-record.d.ts","sourceRoot":"","sources":["../../src/tools/invoice-record.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EACL,KAAK,SAAS,EAEd,KAAK,gBAAgB,EACrB,KAAK,UAAU,EACf,KAAK,OAAO,EAKb,MAAM,iBAAiB,CAAC;AAEzB,MAAM,MAAM,sBAAsB,GAAG,CACnC,OAAO,EAAE,OAAO,EAChB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,KACX,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;AAE5B,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,OAAO,CAAC;IACf,QAAQ,EAAE,sBAAsB,CAAC;IACjC,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,SAAS,CAAC;IACrB,SAAS,EAAE,gBAAgB,CAAC;IAC5B,iEAAiE;IACjE,kBAAkB,EAAE,MAAM,CAAC;IAC3B;;;gEAG4D;IAC5D,kBAAkB,EAAE,MAAM,CAAC;IAC3B,eAAe,EAAE,MAAM,CAAC;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,wBAAsB,aAAa,CAAC,MAAM,EAAE,mBAAmB,GAAG,OAAO,CAAC,UAAU,CAAC,CAyEpF"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { fail, labelFor, money, ok, } from "../lib/types.js";
|
|
2
2
|
export async function invoiceRecord(params) {
|
|
3
|
-
const { session, write, accountId, createdBy, direction, confirmationNumber,
|
|
3
|
+
const { session, write, readName, accountId, createdBy, direction, confirmationNumber, counterpartyNodeId, totalPaymentDue, dueDate, description, } = params;
|
|
4
4
|
const ref = confirmationNumber.trim();
|
|
5
5
|
if (ref === "") {
|
|
6
6
|
return fail("[ledger] op=reject reason=blank-reference — an invoice needs a reference to be found by later.");
|
|
@@ -8,6 +8,13 @@ export async function invoiceRecord(params) {
|
|
|
8
8
|
if (!(totalPaymentDue > 0)) {
|
|
9
9
|
return fail(`[ledger] op=reject reason=non-positive-total total=${totalPaymentDue} — an invoice for nothing is not an invoice. Nothing was written.`);
|
|
10
10
|
}
|
|
11
|
+
if (counterpartyNodeId.trim() === "") {
|
|
12
|
+
return fail("[ledger] op=reject reason=missing-counterparty — look the organisation up first and pass its element id. The ledger does not create or match organisations. Nothing was written.");
|
|
13
|
+
}
|
|
14
|
+
const counterparty = await readName(session, accountId, counterpartyNodeId.trim());
|
|
15
|
+
if (counterparty === null) {
|
|
16
|
+
return fail(`[ledger] op=reject reason=unknown-counterparty nodeId=${counterpartyNodeId.trim()} — no organisation or person with that element id on this account. Nothing was written.`);
|
|
17
|
+
}
|
|
11
18
|
const label = labelFor(direction);
|
|
12
19
|
const isPayable = direction === "payable";
|
|
13
20
|
const props = {
|
|
@@ -29,8 +36,7 @@ export async function invoiceRecord(params) {
|
|
|
29
36
|
{
|
|
30
37
|
type: isPayable ? "FROM_SUPPLIER" : "BILLED_TO",
|
|
31
38
|
direction: "outgoing",
|
|
32
|
-
|
|
33
|
-
targetProps: { accountId, name: counterparty },
|
|
39
|
+
targetNodeId: counterpartyNodeId.trim(),
|
|
34
40
|
},
|
|
35
41
|
];
|
|
36
42
|
const result = await write({ session, labels: [label], props, relationships, createdBy });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"invoice-record.js","sourceRoot":"","sources":["../../src/tools/invoice-record.ts"],"names":[],"mappings":"AAUA,OAAO,EAML,IAAI,EACJ,QAAQ,EACR,KAAK,EACL,EAAE,GACH,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"invoice-record.js","sourceRoot":"","sources":["../../src/tools/invoice-record.ts"],"names":[],"mappings":"AAUA,OAAO,EAML,IAAI,EACJ,QAAQ,EACR,KAAK,EACL,EAAE,GACH,MAAM,iBAAiB,CAAC;AA2BzB,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,MAA2B;IAC7D,MAAM,EACJ,OAAO,EACP,KAAK,EACL,QAAQ,EACR,SAAS,EACT,SAAS,EACT,SAAS,EACT,kBAAkB,EAClB,kBAAkB,EAClB,eAAe,EACf,OAAO,EACP,WAAW,GACZ,GAAG,MAAM,CAAC;IAEX,MAAM,GAAG,GAAG,kBAAkB,CAAC,IAAI,EAAE,CAAC;IACtC,IAAI,GAAG,KAAK,EAAE,EAAE,CAAC;QACf,OAAO,IAAI,CACT,gGAAgG,CACjG,CAAC;IACJ,CAAC;IACD,IAAI,CAAC,CAAC,eAAe,GAAG,CAAC,CAAC,EAAE,CAAC;QAC3B,OAAO,IAAI,CACT,sDAAsD,eAAe,mEAAmE,CACzI,CAAC;IACJ,CAAC;IAED,IAAI,kBAAkB,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;QACrC,OAAO,IAAI,CACT,kLAAkL,CACnL,CAAC;IACJ,CAAC;IAED,MAAM,YAAY,GAAG,MAAM,QAAQ,CAAC,OAAO,EAAE,SAAS,EAAE,kBAAkB,CAAC,IAAI,EAAE,CAAC,CAAC;IACnF,IAAI,YAAY,KAAK,IAAI,EAAE,CAAC;QAC1B,OAAO,IAAI,CACT,yDAAyD,kBAAkB,CAAC,IAAI,EAAE,yFAAyF,CAC5K,CAAC;IACJ,CAAC;IAED,MAAM,KAAK,GAAG,QAAQ,CAAC,SAAS,CAAC,CAAC;IAClC,MAAM,SAAS,GAAG,SAAS,KAAK,SAAS,CAAC;IAE1C,MAAM,KAAK,GAA4B;QACrC,SAAS;QACT,kBAAkB,EAAE,GAAG;QACvB,eAAe;QACf,aAAa,EAAE,MAAM;QACrB,OAAO;KACR,CAAC;IACF,8EAA8E;IAC9E,0DAA0D;IAC1D,IAAI,SAAS;QAAE,KAAK,CAAC,QAAQ,GAAG,YAAY,CAAC;;QACxC,KAAK,CAAC,QAAQ,GAAG,YAAY,CAAC;IACnC,IAAI,WAAW,KAAK,SAAS;QAAE,KAAK,CAAC,WAAW,GAAG,WAAW,CAAC;IAE/D,MAAM,aAAa,GAAwB;QACzC;YACE,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,WAAW;YAC/C,SAAS,EAAE,UAAU;YACrB,YAAY,EAAE,kBAAkB,CAAC,IAAI,EAAE;SACxC;KACF,CAAC;IAEF,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,KAAK,CAAC,EAAE,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,CAAC,CAAC;IAE1F,OAAO,CAAC,KAAK,CACX,6CAA6C,GAAG,UAAU,KAAK,UAAU,KAAK,CAAC,eAAe,CAAC,iBAAiB,MAAM,CAAC,YAAY,IAAI,CAAC,iBAAiB,MAAM,CAAC,YAAY,IAAI,CAAC,EAAE,CACpL,CAAC;IAEF,OAAO,EAAE,CACP,YAAY,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,IAAI,GAAG,QAAQ,YAAY,KAAK,KAAK,CAAC,eAAe,CAAC,QAAQ,OAAO,sDAAsD,CAChL,CAAC;AACJ,CAAC"}
|
|
@@ -16,6 +16,9 @@ import { type CreatedBy, type ToolResult, type WriteFn } from "../lib/types.js";
|
|
|
16
16
|
/** What a resolved invoice looks like to this tool. */
|
|
17
17
|
export interface InvoiceRead {
|
|
18
18
|
label: "Invoice" | "InboundInvoice";
|
|
19
|
+
/** Element id of the invoice node, used as the payment's relationship
|
|
20
|
+
* target. Read alongside the invoice so no second lookup is needed. */
|
|
21
|
+
nodeId: string;
|
|
19
22
|
invoiceId: string;
|
|
20
23
|
totalPaymentDue: number;
|
|
21
24
|
dueDateMs: number;
|
|
@@ -41,6 +44,10 @@ export interface PaymentRecordParams {
|
|
|
41
44
|
date: string;
|
|
42
45
|
paymentType: string;
|
|
43
46
|
kind: "payment" | "credit";
|
|
47
|
+
/** Why the credit was issued. Ignored for a payment. Stored rather than
|
|
48
|
+
* discarded: the operator typed it expecting it to be recorded, and a
|
|
49
|
+
* credit note without its reason is not much of a record. */
|
|
50
|
+
reason?: string;
|
|
44
51
|
}
|
|
45
52
|
export declare function paymentRecord(params: PaymentRecordParams): Promise<ToolResult>;
|
|
46
53
|
//# sourceMappingURL=payment-record.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"payment-record.d.ts","sourceRoot":"","sources":["../../src/tools/payment-record.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAG5C,OAAO,EACL,KAAK,SAAS,EACd,KAAK,UAAU,EACf,KAAK,OAAO,EAIb,MAAM,iBAAiB,CAAC;AAEzB,uDAAuD;AACvD,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,SAAS,GAAG,gBAAgB,CAAC;IACpC,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,EAAE,MAAM,CAAC;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,UAAU,EAAE,MAAM,EAAE,CAAC;CACtB;AAED,MAAM,MAAM,MAAM,GAAG,CACnB,OAAO,EAAE,OAAO,EAChB,SAAS,EAAE,MAAM,EACjB,GAAG,EAAE,MAAM,KACR,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC;AAEjC,oEAAoE;AACpE,MAAM,MAAM,QAAQ,GAAG,CACrB,OAAO,EAAE,OAAO,EAChB,SAAS,EAAE,MAAM,EACjB,GAAG,EAAE,MAAM,KACR,OAAO,CAAC,MAAM,CAAC,CAAC;AAErB,4EAA4E;AAC5E,MAAM,MAAM,WAAW,GAAG,CACxB,OAAO,EAAE,OAAO,EAChB,SAAS,EAAE,MAAM,EACjB,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,MAAM,GAAG,WAAW,GAAG,MAAM,KAClC,OAAO,CAAC,IAAI,CAAC,CAAC;AAEnB,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,QAAQ,CAAC;IACjB,SAAS,EAAE,WAAW,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,SAAS,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,SAAS,GAAG,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"payment-record.d.ts","sourceRoot":"","sources":["../../src/tools/payment-record.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAG5C,OAAO,EACL,KAAK,SAAS,EACd,KAAK,UAAU,EACf,KAAK,OAAO,EAIb,MAAM,iBAAiB,CAAC;AAEzB,uDAAuD;AACvD,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,SAAS,GAAG,gBAAgB,CAAC;IACpC;4EACwE;IACxE,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,EAAE,MAAM,CAAC;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,UAAU,EAAE,MAAM,EAAE,CAAC;CACtB;AAED,MAAM,MAAM,MAAM,GAAG,CACnB,OAAO,EAAE,OAAO,EAChB,SAAS,EAAE,MAAM,EACjB,GAAG,EAAE,MAAM,KACR,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC;AAEjC,oEAAoE;AACpE,MAAM,MAAM,QAAQ,GAAG,CACrB,OAAO,EAAE,OAAO,EAChB,SAAS,EAAE,MAAM,EACjB,GAAG,EAAE,MAAM,KACR,OAAO,CAAC,MAAM,CAAC,CAAC;AAErB,4EAA4E;AAC5E,MAAM,MAAM,WAAW,GAAG,CACxB,OAAO,EAAE,OAAO,EAChB,SAAS,EAAE,MAAM,EACjB,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,MAAM,GAAG,WAAW,GAAG,MAAM,KAClC,OAAO,CAAC,IAAI,CAAC,CAAC;AAEnB,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,QAAQ,CAAC;IACjB,SAAS,EAAE,WAAW,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,SAAS,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,SAAS,GAAG,QAAQ,CAAC;IAC3B;;kEAE8D;IAC9D,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,wBAAsB,aAAa,CAAC,MAAM,EAAE,mBAAmB,GAAG,OAAO,CAAC,UAAU,CAAC,CA8HpF"}
|
|
@@ -2,7 +2,7 @@ import { applyPayment, computeOutstanding } from "../../../../../lib/ledger-core
|
|
|
2
2
|
import { creditIdFor, paymentIdFor } from "../lib/ids.js";
|
|
3
3
|
import { fail, money, ok, } from "../lib/types.js";
|
|
4
4
|
export async function paymentRecord(params) {
|
|
5
|
-
const { session, read, write, verify, setStatus, accountId, createdBy, invoiceRef, amount, date, paymentType, kind, } = params;
|
|
5
|
+
const { session, read, write, verify, setStatus, accountId, createdBy, invoiceRef, amount, date, paymentType, kind, reason, } = params;
|
|
6
6
|
const started = Date.now();
|
|
7
7
|
const isCredit = kind === "credit";
|
|
8
8
|
const invoice = await read(session, accountId, invoiceRef);
|
|
@@ -31,7 +31,7 @@ export async function paymentRecord(params) {
|
|
|
31
31
|
// Direction is NOT stored. Which of the two parent labels this hangs from is
|
|
32
32
|
// what says whether the money came in or went out.
|
|
33
33
|
const props = isCredit
|
|
34
|
-
? { accountId, creditId: childId, amount, date }
|
|
34
|
+
? { accountId, creditId: childId, amount, date, ...(reason ? { reason } : {}) }
|
|
35
35
|
: { accountId, invoiceId: invoice.invoiceId, paymentId: childId, amount, date, paymentType };
|
|
36
36
|
const result = await write({
|
|
37
37
|
session,
|
|
@@ -41,8 +41,7 @@ export async function paymentRecord(params) {
|
|
|
41
41
|
{
|
|
42
42
|
type: isCredit ? "HAS_CREDIT" : "HAS_PAYMENT",
|
|
43
43
|
direction: "incoming",
|
|
44
|
-
|
|
45
|
-
targetProps: { accountId, confirmationNumber: invoice.invoiceId },
|
|
44
|
+
targetNodeId: invoice.nodeId,
|
|
46
45
|
},
|
|
47
46
|
],
|
|
48
47
|
createdBy,
|