@robbeverhelst/do 1.314.0 → 1.314.1
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/do.js +1216 -251
- package/package.json +1 -1
package/dist/do.js
CHANGED
|
@@ -27859,6 +27859,64 @@ var moneyBankSyncResultSchema = object({
|
|
|
27859
27859
|
}).extend({ accountTitle: string2() }))
|
|
27860
27860
|
});
|
|
27861
27861
|
|
|
27862
|
+
// ../../packages/schema/src/contracts/money-year.ts
|
|
27863
|
+
var amount6 = string2();
|
|
27864
|
+
var moneyYearQuerySchema = object({
|
|
27865
|
+
year: exports_coerce.number().int().min(2000).max(2100).optional(),
|
|
27866
|
+
scope: moneyBudgetScopeSchema.optional()
|
|
27867
|
+
});
|
|
27868
|
+
var moneyYearMonthSchema = object({
|
|
27869
|
+
month: moneyMonthSchema,
|
|
27870
|
+
income: amount6,
|
|
27871
|
+
spent: amount6
|
|
27872
|
+
});
|
|
27873
|
+
var moneyYearCategorySchema = object({
|
|
27874
|
+
categoryId: ulidSchema.nullable(),
|
|
27875
|
+
name: string2(),
|
|
27876
|
+
group: _enum2(["fixed", "flexible", "income"]).nullable(),
|
|
27877
|
+
amount: amount6,
|
|
27878
|
+
lastYear: amount6
|
|
27879
|
+
});
|
|
27880
|
+
var MONEY_YEAR_STREAM_CHANGES = ["new", "stopped", "up", "down", "same"];
|
|
27881
|
+
var moneyYearStreamChangeSchema = _enum2(MONEY_YEAR_STREAM_CHANGES);
|
|
27882
|
+
var moneyYearStreamSchema = object({
|
|
27883
|
+
id: ulidSchema,
|
|
27884
|
+
title: string2(),
|
|
27885
|
+
cadence: moneyCadenceSchema,
|
|
27886
|
+
visibility: _enum2(NODE_VISIBILITY_VALUES),
|
|
27887
|
+
thisYear: amount6,
|
|
27888
|
+
lastYear: amount6,
|
|
27889
|
+
change: moneyYearStreamChangeSchema
|
|
27890
|
+
});
|
|
27891
|
+
var moneyYearGoalSchema = object({
|
|
27892
|
+
id: ulidSchema,
|
|
27893
|
+
title: string2(),
|
|
27894
|
+
visibility: _enum2(NODE_VISIBILITY_VALUES),
|
|
27895
|
+
status: moneyGoalStatusSchema,
|
|
27896
|
+
projectTitle: string2().nullable(),
|
|
27897
|
+
thisYear: amount6,
|
|
27898
|
+
saved: amount6,
|
|
27899
|
+
target: amount6
|
|
27900
|
+
});
|
|
27901
|
+
var moneyYearTotalsSchema = object({
|
|
27902
|
+
income: amount6,
|
|
27903
|
+
spent: amount6,
|
|
27904
|
+
saved: amount6
|
|
27905
|
+
});
|
|
27906
|
+
var moneyYearSchema = object({
|
|
27907
|
+
year: number2().int(),
|
|
27908
|
+
scope: moneyBudgetScopeSchema,
|
|
27909
|
+
through: moneyMonthSchema,
|
|
27910
|
+
firstYear: number2().int().nullable(),
|
|
27911
|
+
totals: moneyYearTotalsSchema,
|
|
27912
|
+
lastYear: moneyYearTotalsSchema.nullable(),
|
|
27913
|
+
months: array(moneyYearMonthSchema),
|
|
27914
|
+
spending: array(moneyYearCategorySchema),
|
|
27915
|
+
income: array(moneyYearCategorySchema),
|
|
27916
|
+
recurring: array(moneyYearStreamSchema),
|
|
27917
|
+
goals: array(moneyYearGoalSchema)
|
|
27918
|
+
});
|
|
27919
|
+
|
|
27862
27920
|
// ../../packages/schema/src/contracts/family-tree.ts
|
|
27863
27921
|
var familyTreeRefSchema = string2().regex(/^[A-Za-z0-9_-]{1,40}$/, "expected a tree reference");
|
|
27864
27922
|
var familyTreeSideSchema = _enum2(["father", "mother"]);
|
|
@@ -31541,6 +31599,66 @@ var dayOperations = defineOperations({
|
|
|
31541
31599
|
}
|
|
31542
31600
|
});
|
|
31543
31601
|
|
|
31602
|
+
// ../../packages/schema/src/operations/files.ts
|
|
31603
|
+
var fileOperations = defineOperations({
|
|
31604
|
+
list: {
|
|
31605
|
+
method: "get",
|
|
31606
|
+
path: "/files",
|
|
31607
|
+
scopes: ["files:read"],
|
|
31608
|
+
tag: "Files",
|
|
31609
|
+
summary: "List a node's files",
|
|
31610
|
+
description: "A node's files, newest first (`?nodeId=`): name, type, size, sha256, source, pages, who uploaded it, whether it's sealed and whether it has text. Never the bytes.",
|
|
31611
|
+
query: [{ name: "nodeId", description: "The owner node's ULID." }],
|
|
31612
|
+
querySchema: object({ nodeId: ulidSchema }),
|
|
31613
|
+
status: 200,
|
|
31614
|
+
response: { description: "The node's files.", list: true },
|
|
31615
|
+
errors: {
|
|
31616
|
+
400: true,
|
|
31617
|
+
404: "No such file, or its owner node isn't visible to the key's member."
|
|
31618
|
+
}
|
|
31619
|
+
},
|
|
31620
|
+
get: {
|
|
31621
|
+
method: "get",
|
|
31622
|
+
path: "/files/{id}",
|
|
31623
|
+
scopes: ["files:read"],
|
|
31624
|
+
tag: "Files",
|
|
31625
|
+
summary: "Get a file",
|
|
31626
|
+
description: "One file with its `textExtract`.",
|
|
31627
|
+
pathParams: { id: "The file's ULID." },
|
|
31628
|
+
status: 200,
|
|
31629
|
+
response: { description: "The file." },
|
|
31630
|
+
errors: { 404: "No such file, or its owner node isn't visible to the key's member." }
|
|
31631
|
+
},
|
|
31632
|
+
viewUrl: {
|
|
31633
|
+
method: "post",
|
|
31634
|
+
path: "/files/{id}/view-url",
|
|
31635
|
+
scopes: ["files:read"],
|
|
31636
|
+
tag: "Files",
|
|
31637
|
+
summary: "Get a file's view link",
|
|
31638
|
+
description: "A short-lived signed link (`path`, on this API's origin, and `expiresAt`, ten minutes on) to the file's inline view, for a browser that holds no key: an `<iframe>` or an `<img>`. Minted behind the download's check; opening it checks again as this key, so a revoked key or a dropped `files:read` ends it.",
|
|
31639
|
+
pathParams: { id: "The file's ULID." },
|
|
31640
|
+
status: 200,
|
|
31641
|
+
response: { description: "The link." },
|
|
31642
|
+
errors: { 404: "No such file, or its owner node isn't visible to the key's member." },
|
|
31643
|
+
operationId: "get_file_view_link"
|
|
31644
|
+
},
|
|
31645
|
+
remove: {
|
|
31646
|
+
method: "delete",
|
|
31647
|
+
path: "/files/{id}",
|
|
31648
|
+
scopes: ["files:write"],
|
|
31649
|
+
tag: "Files",
|
|
31650
|
+
summary: "Delete a file",
|
|
31651
|
+
description: "Delete a file from a node the key's member may edit.",
|
|
31652
|
+
pathParams: { id: "The file's ULID." },
|
|
31653
|
+
status: 204,
|
|
31654
|
+
response: { description: "Deleted." },
|
|
31655
|
+
errors: {
|
|
31656
|
+
403: "The key's member can see the node but may not change it, or the key has no member.",
|
|
31657
|
+
404: "No such file, or its owner node isn't visible to the key's member."
|
|
31658
|
+
}
|
|
31659
|
+
}
|
|
31660
|
+
});
|
|
31661
|
+
|
|
31544
31662
|
// ../../packages/schema/src/operations/food-log.ts
|
|
31545
31663
|
var NO_MEMBER = "The key holds no health scope by name, or has no member behind it.";
|
|
31546
31664
|
var HIDDEN = "No such meal, or it isn't the key's member's.";
|
|
@@ -33091,98 +33209,885 @@ var memberOperations = defineOperations({
|
|
|
33091
33209
|
summary: "List members",
|
|
33092
33210
|
description: "The Space roster.",
|
|
33093
33211
|
status: 200,
|
|
33094
|
-
response: { description: "The members." }
|
|
33212
|
+
response: { description: "The members." }
|
|
33213
|
+
},
|
|
33214
|
+
setRole: {
|
|
33215
|
+
method: "patch",
|
|
33216
|
+
path: "/members/{id}/role",
|
|
33217
|
+
scopes: ["members:write"],
|
|
33218
|
+
tag: "Collaboration",
|
|
33219
|
+
summary: "Set a member's role",
|
|
33220
|
+
description: "Change a member's role; fires `member.role.updated`.",
|
|
33221
|
+
body: setMemberRoleInputSchema,
|
|
33222
|
+
status: 200,
|
|
33223
|
+
response: { description: "The updated member." },
|
|
33224
|
+
errors: { 400: true, 404: true },
|
|
33225
|
+
webhook: "member.role.updated"
|
|
33226
|
+
},
|
|
33227
|
+
remove: {
|
|
33228
|
+
method: "delete",
|
|
33229
|
+
path: "/members/{id}",
|
|
33230
|
+
scopes: ["members:write"],
|
|
33231
|
+
tag: "Collaboration",
|
|
33232
|
+
summary: "Remove a member",
|
|
33233
|
+
description: "Remove a member from the Space; fires `member.removed`.",
|
|
33234
|
+
status: 204,
|
|
33235
|
+
response: { description: "Removed." },
|
|
33236
|
+
errors: { 404: true },
|
|
33237
|
+
webhook: "member.removed"
|
|
33238
|
+
}
|
|
33239
|
+
});
|
|
33240
|
+
|
|
33241
|
+
// ../../packages/schema/src/operations/metrics.ts
|
|
33242
|
+
var NO_MEMBER2 = "The key acts for no member.";
|
|
33243
|
+
var metricOperations = defineOperations({
|
|
33244
|
+
list: {
|
|
33245
|
+
method: "get",
|
|
33246
|
+
path: "/metrics",
|
|
33247
|
+
scopes: ["habits:read"],
|
|
33248
|
+
tag: "Habits",
|
|
33249
|
+
summary: "List metrics",
|
|
33250
|
+
description: "Weight (kg), sleep (h), mood (1\u20135), the day rating, energy, bedtime, resting heart rate (bpm) and HRV (ms) as trend lines: one point per day in the member's timezone (that day's last value, hand-logged or from Google Fit or Google Health), oldest first, plus the latest. No target, no streak. The key must act for a member. Resting heart rate and HRV are health data: without `health:read` held by name their lines come back empty.",
|
|
33251
|
+
query: [
|
|
33252
|
+
{ name: "days", description: "How far back, 1\u2013730 days (default 90).", type: "integer" }
|
|
33253
|
+
],
|
|
33254
|
+
querySchema: metricsQuerySchema,
|
|
33255
|
+
status: 200,
|
|
33256
|
+
response: { description: "Every Metric with its points." },
|
|
33257
|
+
errors: { 403: NO_MEMBER2 }
|
|
33258
|
+
},
|
|
33259
|
+
sessions: {
|
|
33260
|
+
method: "get",
|
|
33261
|
+
path: "/metrics/sessions",
|
|
33262
|
+
scopes: ["habits:read"],
|
|
33263
|
+
tag: "Habits",
|
|
33264
|
+
summary: "List workout sessions",
|
|
33265
|
+
description: "The member's workouts from their connections (Google Fit workouts, Strava activities), newest first: when, the sport in words, its name and minutes. Read only; they come in through sync.",
|
|
33266
|
+
query: [
|
|
33267
|
+
{ name: "days", description: "How far back, 1\u2013365 days (default 14).", type: "integer" }
|
|
33268
|
+
],
|
|
33269
|
+
querySchema: sessionsQuerySchema,
|
|
33270
|
+
status: 200,
|
|
33271
|
+
response: { description: "The sessions." },
|
|
33272
|
+
errors: { 403: NO_MEMBER2 }
|
|
33273
|
+
},
|
|
33274
|
+
import: {
|
|
33275
|
+
method: "post",
|
|
33276
|
+
path: "/metrics/import",
|
|
33277
|
+
scopes: ["habits:write"],
|
|
33278
|
+
tag: "Habits",
|
|
33279
|
+
summary: "Import metrics from Health Connect",
|
|
33280
|
+
description: "A batch the Android app read off the phone's Health Connect: `weight` (kg), `sleep` (h) and `bedtime` (minutes after 18:00), at most 500, each with its Health Connect `recordId`. Each lands once on the member's line with source `health_connect`; a record already imported, out of its Metric's range or in the future is skipped, not refused. Returns `{ imported, skipped }`.",
|
|
33281
|
+
body: importMetricsInputSchema,
|
|
33282
|
+
status: 201,
|
|
33283
|
+
response: { description: "How many points landed and how many were skipped." },
|
|
33284
|
+
errors: { 400: true, 403: NO_MEMBER2 }
|
|
33285
|
+
},
|
|
33286
|
+
log: {
|
|
33287
|
+
method: "post",
|
|
33288
|
+
path: "/metrics/{key}",
|
|
33289
|
+
pathParams: {
|
|
33290
|
+
key: {
|
|
33291
|
+
description: "`weight` (kg), `sleep` (h), `mood` (1\u20135), `rating` (the day, 1\u201310), `energy` (1\u201310), `bedtime` (minutes after 18:00: 01:00 = 420), `resting_hr` (bpm) or `hrv` (ms). The last two are health data: logging one needs `health:write` too.",
|
|
33292
|
+
enum: metricKeySchema.options
|
|
33293
|
+
}
|
|
33294
|
+
},
|
|
33295
|
+
pathParamSchemas: { key: metricKeySchema },
|
|
33296
|
+
scopes: ["habits:write"],
|
|
33297
|
+
tag: "Habits",
|
|
33298
|
+
summary: "Log a metric",
|
|
33299
|
+
description: 'Log one value ("weighed 72.4"; "slept 7.5 hours"; "mood 4"; "today was a 7" \u2192 `rating`; "bed 01:00" \u2192 `bedtime` 420); `occurredAt` back-dates it, `source` says `manual` (default) or `device`. A bedtime lands on the night\'s wake day. Logging again the same day replaces that day\'s point. 400 outside the Metric\'s range. Returns the Metric\'s refreshed line.',
|
|
33300
|
+
body: logMetricInputSchema,
|
|
33301
|
+
status: 201,
|
|
33302
|
+
response: { description: "The Metric." },
|
|
33303
|
+
errors: { 400: true, 403: NO_MEMBER2 }
|
|
33304
|
+
}
|
|
33305
|
+
});
|
|
33306
|
+
|
|
33307
|
+
// ../../packages/schema/src/operations/money.ts
|
|
33308
|
+
var moneyOperations = defineOperations({
|
|
33309
|
+
listAccounts: {
|
|
33310
|
+
method: "get",
|
|
33311
|
+
path: "/money/accounts",
|
|
33312
|
+
scopes: ["finance:read"],
|
|
33313
|
+
tag: "Money",
|
|
33314
|
+
summary: "List money accounts",
|
|
33315
|
+
description: "The accounts the key may see: the household's and, for a member's key, that member's Only me ones. Each with its kind, masked IBAN, currency, opening and last reported balance. An account is the household's (`visibility: space`) or \"Only me\" (`owner`, the default for a new one); another member never sees an Only me account or anything on it.",
|
|
33316
|
+
status: 200,
|
|
33317
|
+
response: { description: "The accounts." }
|
|
33318
|
+
},
|
|
33319
|
+
createAccount: {
|
|
33320
|
+
method: "post",
|
|
33321
|
+
path: "/money/accounts",
|
|
33322
|
+
scopes: ["finance:write"],
|
|
33323
|
+
tag: "Money",
|
|
33324
|
+
summary: "Open a money account",
|
|
33325
|
+
description: 'Open an account: `id`, `title`, optional `kind` (current \xB7 savings \xB7 credit_card \xB7 cash \xB7 voucher \xB7 loan \xB7 investment \xB7 pension \xB7 asset_manual), `holder`, `iban` (stored only masked and hashed), `currency`, `openingBalance` (a decimal string), `includeInBudget`, `includeInNetWorth` and `visibility`. An account is the household\'s (`visibility: space`) or "Only me" (`owner`, the default for a new one); another member never sees an Only me account or anything on it.',
|
|
33326
|
+
body: createMoneyAccountInputSchema,
|
|
33327
|
+
status: 201,
|
|
33328
|
+
response: { description: "The account." },
|
|
33329
|
+
errors: { 400: true }
|
|
33330
|
+
},
|
|
33331
|
+
listConnections: {
|
|
33332
|
+
method: "get",
|
|
33333
|
+
path: "/money/connections",
|
|
33334
|
+
scopes: ["finance:read"],
|
|
33335
|
+
tag: "Money",
|
|
33336
|
+
summary: "List bank connections",
|
|
33337
|
+
description: "The bank links (Enable Banking) feeding the accounts the key may see: the bank, the account it feeds, its status (active \xB7 failing \xB7 expired \xB7 revoked), when the bank's consent ends, the last sync and its error, and `reconnectSoon` once the consent ends within 14 days. No credential or provider account id is ever returned. An account is the household's (`visibility: space`) or \"Only me\" (`owner`, the default for a new one); another member never sees an Only me account or anything on it.",
|
|
33338
|
+
status: 200,
|
|
33339
|
+
response: { description: "The connections." }
|
|
33340
|
+
},
|
|
33341
|
+
syncConnections: {
|
|
33342
|
+
method: "post",
|
|
33343
|
+
path: "/money/connections/sync",
|
|
33344
|
+
scopes: ["finance:write"],
|
|
33345
|
+
tag: "Money",
|
|
33346
|
+
summary: "Sync bank connections now",
|
|
33347
|
+
description: "Sync every live bank link the key may see, or with `accountId` the one feeding that account, the way the daily run does: booked transactions go through the CSV import's pipeline (the bank's entry id, else the CSV row of the same day, amount and counterparty or reference, is matched instead of booked twice), the rules and transfer matching run, and the balance is updated. Per link: outcome (ok \xB7 failed), fetched, imported, matched, duplicates and the error in plain words. An account is the household's (`visibility: space`) or \"Only me\" (`owner`, the default for a new one); another member never sees an Only me account or anything on it.",
|
|
33348
|
+
body: moneyBankSyncInputSchema,
|
|
33349
|
+
status: 200,
|
|
33350
|
+
response: { description: "What each sync did." },
|
|
33351
|
+
errors: {
|
|
33352
|
+
400: true,
|
|
33353
|
+
404: `No such account or transaction, or it is another member's "Only me" one.`
|
|
33354
|
+
}
|
|
33355
|
+
},
|
|
33356
|
+
listConnectionSyncs: {
|
|
33357
|
+
method: "get",
|
|
33358
|
+
path: "/money/connections/{id}/syncs",
|
|
33359
|
+
scopes: ["finance:read"],
|
|
33360
|
+
tag: "Money",
|
|
33361
|
+
summary: "List a bank connection's sync log",
|
|
33362
|
+
description: "The link's last 30 sync runs, newest first: when, outcome, fetched, imported, matched, duplicates and the error.",
|
|
33363
|
+
pathParams: { id: "The bank link's ULID." },
|
|
33364
|
+
pathParamSchemas: { id: ulidSchema },
|
|
33365
|
+
status: 200,
|
|
33366
|
+
response: { description: "The sync log." },
|
|
33367
|
+
errors: { 404: `No such account or transaction, or it is another member's "Only me" one.` }
|
|
33368
|
+
},
|
|
33369
|
+
getAccount: {
|
|
33370
|
+
method: "get",
|
|
33371
|
+
path: "/money/accounts/{id}",
|
|
33372
|
+
scopes: ["finance:read"],
|
|
33373
|
+
tag: "Money",
|
|
33374
|
+
summary: "Get a money account",
|
|
33375
|
+
description: "One account.",
|
|
33376
|
+
pathParams: { id: "The account's ULID." },
|
|
33377
|
+
pathParamSchemas: { id: ulidSchema },
|
|
33378
|
+
status: 200,
|
|
33379
|
+
response: { description: "The account." },
|
|
33380
|
+
errors: { 404: `No such account or transaction, or it is another member's "Only me" one.` }
|
|
33381
|
+
},
|
|
33382
|
+
updateAccount: {
|
|
33383
|
+
method: "patch",
|
|
33384
|
+
path: "/money/accounts/{id}",
|
|
33385
|
+
scopes: ["finance:write"],
|
|
33386
|
+
tag: "Money",
|
|
33387
|
+
summary: "Update a money account",
|
|
33388
|
+
description: "Rename it, change its kind, IBAN, opening balance, what it counts towards, or who sees it.",
|
|
33389
|
+
pathParams: { id: "The account's ULID." },
|
|
33390
|
+
pathParamSchemas: { id: ulidSchema },
|
|
33391
|
+
body: updateMoneyAccountInputSchema,
|
|
33392
|
+
status: 200,
|
|
33393
|
+
response: { description: "The account." },
|
|
33394
|
+
errors: {
|
|
33395
|
+
400: true,
|
|
33396
|
+
404: `No such account or transaction, or it is another member's "Only me" one.`
|
|
33397
|
+
}
|
|
33398
|
+
},
|
|
33399
|
+
removeAccount: {
|
|
33400
|
+
method: "delete",
|
|
33401
|
+
path: "/money/accounts/{id}",
|
|
33402
|
+
scopes: ["finance:write"],
|
|
33403
|
+
tag: "Money",
|
|
33404
|
+
summary: "Close a money account",
|
|
33405
|
+
description: "The account goes to Trash; its transactions stay with it for a restore.",
|
|
33406
|
+
pathParams: { id: "The account's ULID." },
|
|
33407
|
+
pathParamSchemas: { id: ulidSchema },
|
|
33408
|
+
status: 204,
|
|
33409
|
+
response: { description: "Closed." },
|
|
33410
|
+
errors: { 404: `No such account or transaction, or it is another member's "Only me" one.` }
|
|
33411
|
+
},
|
|
33412
|
+
listCategories: {
|
|
33413
|
+
method: "get",
|
|
33414
|
+
path: "/money/categories",
|
|
33415
|
+
scopes: ["finance:read"],
|
|
33416
|
+
tag: "Money",
|
|
33417
|
+
summary: "List money categories",
|
|
33418
|
+
description: "The household's categories (two levels; group fixed \xB7 flexible \xB7 saving \xB7 income \xB7 transfer). A Space's first read makes the starting list.",
|
|
33419
|
+
status: 200,
|
|
33420
|
+
response: { description: "The categories." }
|
|
33421
|
+
},
|
|
33422
|
+
createCategory: {
|
|
33423
|
+
method: "post",
|
|
33424
|
+
path: "/money/categories",
|
|
33425
|
+
scopes: ["finance:write"],
|
|
33426
|
+
tag: "Money",
|
|
33427
|
+
summary: "Add a money category",
|
|
33428
|
+
description: "`id`, `name`, optional `parentId` (one level up at most), `group`, `icon`, `sortOrder`.",
|
|
33429
|
+
body: createMoneyCategoryInputSchema,
|
|
33430
|
+
status: 201,
|
|
33431
|
+
response: { description: "The category." },
|
|
33432
|
+
errors: { 400: true, 409: "That name is already there." }
|
|
33433
|
+
},
|
|
33434
|
+
listTransactions: {
|
|
33435
|
+
method: "get",
|
|
33436
|
+
path: "/money/transactions",
|
|
33437
|
+
scopes: ["finance:read"],
|
|
33438
|
+
tag: "Money",
|
|
33439
|
+
summary: "List money transactions",
|
|
33440
|
+
description: "The ledger, newest first, paged by `cursor`: each with its signed `amount` (a decimal string), day, payee, the bank's text, category, status (unreviewed \xB7 reviewed), kind, `businessShare` (0\u2013100), `links` (what it points at across do, by name) and `recurring` (the stream its payee belongs to). Filters: `accountId`, `status`, `categoryId`, `from`/`to` (days), `q` (payee or text), `business=true` (a business share above 0), `businessStatus`, `taxTag`.",
|
|
33441
|
+
query: [
|
|
33442
|
+
{ name: "accountId", description: "Only this account." },
|
|
33443
|
+
{ name: "status", description: "unreviewed or reviewed." },
|
|
33444
|
+
{ name: "categoryId", description: "Only this category." },
|
|
33445
|
+
{ name: "from", description: "First day, YYYY-MM-DD." },
|
|
33446
|
+
{ name: "to", description: "Last day, YYYY-MM-DD." },
|
|
33447
|
+
{ name: "q", description: "Payee or bank text contains." },
|
|
33448
|
+
{ name: "business", description: "`true`: only rows with a business share." },
|
|
33449
|
+
{ name: "businessStatus", description: "none, asked, draft_pushed, posted or declined." },
|
|
33450
|
+
{ name: "taxTag", description: "Only this tax tag." },
|
|
33451
|
+
{ name: "limit", description: "Page size (max 100).", type: "integer" },
|
|
33452
|
+
{ name: "cursor", description: "The previous page's nextCursor." }
|
|
33453
|
+
],
|
|
33454
|
+
querySchema: moneyTransactionsQuerySchema,
|
|
33455
|
+
status: 200,
|
|
33456
|
+
response: { description: "A page: `{ data, nextCursor }`." },
|
|
33457
|
+
errors: { 400: true }
|
|
33458
|
+
},
|
|
33459
|
+
createTransaction: {
|
|
33460
|
+
method: "post",
|
|
33461
|
+
path: "/money/transactions",
|
|
33462
|
+
scopes: ["finance:write"],
|
|
33463
|
+
tag: "Money",
|
|
33464
|
+
summary: "Book a money transaction",
|
|
33465
|
+
description: "Book one by hand (cash, or a payment the bank hasn't shown yet): `id`, `accountId`, `bookedOn`, `amount` (negative is money out), optional `counterpartyName`, `note`, `categoryId`, `contactId`, `kind`.",
|
|
33466
|
+
body: createMoneyTransactionInputSchema,
|
|
33467
|
+
status: 201,
|
|
33468
|
+
response: { description: "The transaction." },
|
|
33469
|
+
errors: {
|
|
33470
|
+
400: true,
|
|
33471
|
+
404: `No such account or transaction, or it is another member's "Only me" one.`
|
|
33472
|
+
}
|
|
33473
|
+
},
|
|
33474
|
+
getTransaction: {
|
|
33475
|
+
method: "get",
|
|
33476
|
+
path: "/money/transactions/{id}",
|
|
33477
|
+
scopes: ["finance:read"],
|
|
33478
|
+
tag: "Money",
|
|
33479
|
+
summary: "Get a money transaction",
|
|
33480
|
+
description: "One transaction with its account's and category's names.",
|
|
33481
|
+
pathParams: { id: "The transaction's ULID." },
|
|
33482
|
+
pathParamSchemas: { id: ulidSchema },
|
|
33483
|
+
status: 200,
|
|
33484
|
+
response: { description: "The transaction." },
|
|
33485
|
+
errors: { 404: `No such account or transaction, or it is another member's "Only me" one.` }
|
|
33486
|
+
},
|
|
33487
|
+
sortTransaction: {
|
|
33488
|
+
method: "patch",
|
|
33489
|
+
path: "/money/transactions/{id}",
|
|
33490
|
+
scopes: ["finance:write"],
|
|
33491
|
+
tag: "Money",
|
|
33492
|
+
summary: "Sort a money transaction",
|
|
33493
|
+
description: "Sort one: `categoryId`, `contactId`, `kind`, `note`, `status`, `businessShare` (0\u2013100), `businessNote`, `businessStatus` (none \xB7 asked \xB7 declined), `taxTag` (`null` clears). The ledger facts (day, amount, account, the bank's text) never change. Answers with the same receipt as `/sort`.",
|
|
33494
|
+
pathParams: { id: "The transaction's ULID." },
|
|
33495
|
+
pathParamSchemas: { id: ulidSchema },
|
|
33496
|
+
body: sortMoneyTransactionInputSchema,
|
|
33497
|
+
status: 200,
|
|
33498
|
+
response: { description: "The receipt." },
|
|
33499
|
+
errors: {
|
|
33500
|
+
400: true,
|
|
33501
|
+
404: `No such account or transaction, or it is another member's "Only me" one.`
|
|
33502
|
+
}
|
|
33503
|
+
},
|
|
33504
|
+
listSplits: {
|
|
33505
|
+
method: "get",
|
|
33506
|
+
path: "/money/transactions/{id}/splits",
|
|
33507
|
+
scopes: ["finance:read"],
|
|
33508
|
+
tag: "Money",
|
|
33509
|
+
summary: "List a money transaction's splits",
|
|
33510
|
+
description: "Its parts (empty when it isn't split), each with its signed `amount`, category, and who owes it (`owedBy`: `{ userId }` or `{ contactId }`, with `owedAmount`).",
|
|
33511
|
+
pathParams: { id: "The transaction's ULID." },
|
|
33512
|
+
pathParamSchemas: { id: ulidSchema },
|
|
33513
|
+
status: 200,
|
|
33514
|
+
response: { description: "The parts." },
|
|
33515
|
+
errors: { 404: `No such account or transaction, or it is another member's "Only me" one.` }
|
|
33516
|
+
},
|
|
33517
|
+
setSplits: {
|
|
33518
|
+
method: "put",
|
|
33519
|
+
path: "/money/transactions/{id}/splits",
|
|
33520
|
+
scopes: ["finance:write"],
|
|
33521
|
+
tag: "Money",
|
|
33522
|
+
summary: "Split a money transaction",
|
|
33523
|
+
description: "Replace its parts: `splits: [{ amount, categoryId?, owedBy?, owedAmount?, note? }]` (up to 20), adding up to the transaction, each with its sign; `[]` unsplits it. A part someone owes is owed to the member splitting it; that member (another member, never yourself) then sees the part and its note on their settle-up, never the transaction. Answers a receipt whose `undo` is the old parts.",
|
|
33524
|
+
pathParams: { id: "The transaction's ULID." },
|
|
33525
|
+
pathParamSchemas: { id: ulidSchema },
|
|
33526
|
+
body: setMoneySplitsInputSchema,
|
|
33527
|
+
status: 200,
|
|
33528
|
+
response: { description: "The receipt." },
|
|
33529
|
+
errors: {
|
|
33530
|
+
400: true,
|
|
33531
|
+
404: `No such account or transaction, or it is another member's "Only me" one.`
|
|
33532
|
+
}
|
|
33533
|
+
},
|
|
33534
|
+
share: {
|
|
33535
|
+
method: "post",
|
|
33536
|
+
path: "/money/transactions/{id}/share",
|
|
33537
|
+
scopes: ["finance:write"],
|
|
33538
|
+
tag: "Money",
|
|
33539
|
+
summary: "Share a money transaction",
|
|
33540
|
+
description: "`money_split`: `with` (`{ userId }` or `{ contactId }`) owes `percent` of it (50 by default) or exactly `owedAmount`; optional `note`. An unsplit transaction becomes one shared part; one already in several parts answers 409 (split it by hand).",
|
|
33541
|
+
pathParams: { id: "The transaction's ULID." },
|
|
33542
|
+
pathParamSchemas: { id: ulidSchema },
|
|
33543
|
+
body: shareMoneyTransactionInputSchema,
|
|
33544
|
+
status: 200,
|
|
33545
|
+
response: { description: "The receipt." },
|
|
33546
|
+
errors: {
|
|
33547
|
+
400: true,
|
|
33548
|
+
404: `No such account or transaction, or it is another member's "Only me" one.`,
|
|
33549
|
+
409: "It's split in several parts."
|
|
33550
|
+
},
|
|
33551
|
+
operationId: "money_split"
|
|
33552
|
+
},
|
|
33553
|
+
settleUp: {
|
|
33554
|
+
method: "get",
|
|
33555
|
+
path: "/money/settle-up",
|
|
33556
|
+
scopes: ["finance:read"],
|
|
33557
|
+
tag: "Money",
|
|
33558
|
+
summary: "Get the money settle-up",
|
|
33559
|
+
description: "Per person (a member's `userId` or a Contact with its `name`): the `balance` (positive: they owe you; negative: you owe them) and the lines behind it, newest first (parts owed and settlements, each signed the same way; `transactionId` only when you may open it). Needs a member behind the key.",
|
|
33560
|
+
status: 200,
|
|
33561
|
+
response: { description: "`{ balances }`." },
|
|
33562
|
+
errors: { 403: "No member behind the key, or no finance scope." },
|
|
33563
|
+
operationId: "money_settle_up"
|
|
33564
|
+
},
|
|
33565
|
+
settle: {
|
|
33566
|
+
method: "post",
|
|
33567
|
+
path: "/money/settlements",
|
|
33568
|
+
scopes: ["finance:write"],
|
|
33569
|
+
tag: "Money",
|
|
33570
|
+
summary: "Record a money settlement",
|
|
33571
|
+
description: "Money paid back: `id`, `with`, `direction` (`they_paid` you or `you_paid` them), `amount`, optional `settledOn` (default today), `transactionId` (the transfer) and `note`. Only the members on its sides see it.",
|
|
33572
|
+
body: createMoneySettlementInputSchema,
|
|
33573
|
+
status: 201,
|
|
33574
|
+
response: { description: "The settlement." },
|
|
33575
|
+
errors: {
|
|
33576
|
+
400: true,
|
|
33577
|
+
404: `No such account or transaction, or it is another member's "Only me" one.`
|
|
33578
|
+
}
|
|
33579
|
+
},
|
|
33580
|
+
removeSettlement: {
|
|
33581
|
+
method: "delete",
|
|
33582
|
+
path: "/money/settlements/{id}",
|
|
33583
|
+
scopes: ["finance:write"],
|
|
33584
|
+
tag: "Money",
|
|
33585
|
+
summary: "Remove a money settlement",
|
|
33586
|
+
description: "Take it back (either side may).",
|
|
33587
|
+
pathParams: { id: "The settlement's ULID." },
|
|
33588
|
+
pathParamSchemas: { id: ulidSchema },
|
|
33589
|
+
status: 204,
|
|
33590
|
+
response: { description: "Removed." },
|
|
33591
|
+
errors: { 404: `No such account or transaction, or it is another member's "Only me" one.` }
|
|
33592
|
+
},
|
|
33593
|
+
taxEvidence: {
|
|
33594
|
+
method: "get",
|
|
33595
|
+
path: "/money/tax-evidence",
|
|
33596
|
+
scopes: ["finance:read"],
|
|
33597
|
+
tag: "Money",
|
|
33598
|
+
summary: "Get the money tax evidence",
|
|
33599
|
+
description: "A year's tax-tagged payments (`year`, optionally one `tag`: pension_saving \xB7 long_term_saving \xB7 gift_281_71 \xB7 childcare \xB7 service_cheques \xB7 home_energy_investment \xB7 business_cost), grouped by tag in that order, oldest first, with each group's signed `total` and each payment's `evidence`: the nodes linked as evidence and the files on them (an empty list when none is linked yet).",
|
|
33600
|
+
query: [
|
|
33601
|
+
{ name: "year", description: "The year, YYYY.", type: "integer", required: true },
|
|
33602
|
+
{ name: "tag", description: "Only this tax tag." }
|
|
33603
|
+
],
|
|
33604
|
+
querySchema: moneyTaxEvidenceQuerySchema,
|
|
33605
|
+
status: 200,
|
|
33606
|
+
response: { description: "`{ year, groups }`." },
|
|
33607
|
+
errors: { 400: true },
|
|
33608
|
+
operationId: "money_tax_evidence"
|
|
33609
|
+
},
|
|
33610
|
+
pushOdooDraft: {
|
|
33611
|
+
method: "post",
|
|
33612
|
+
path: "/money/transactions/{id}/odoo-draft",
|
|
33613
|
+
scopes: ["finance:write"],
|
|
33614
|
+
tag: "Money",
|
|
33615
|
+
summary: "Push a money transaction to Odoo",
|
|
33616
|
+
description: "`money_push_odoo`: the business share goes to Odoo as a **draft** vendor bill (never posted from do), for the share only (30% of \u20AC120 is \u20AC36), dated the day it was paid, with the calculation note (`note` overrides the transaction's `businessNote`) and the files on its `evidence` links attached. Idempotent on the bill's ref `do:tx:<id>`: a second push answers the same draft with `alreadyThere`. The receipt has the draft's `odooRef`, `openUrl` and a calm `line`; undo is `DELETE` on the same path. 400 without a business share or for money in; 403 while the deployment's push is off (`MONEY_ODOO_PUSH` and its Space list); 409 once the bill was booked in Odoo; 502 when Odoo doesn't answer.",
|
|
33617
|
+
pathParams: { id: "The transaction's ULID." },
|
|
33618
|
+
pathParamSchemas: { id: ulidSchema },
|
|
33619
|
+
body: moneyOdooPushInputSchema,
|
|
33620
|
+
bodyOptional: true,
|
|
33621
|
+
status: 200,
|
|
33622
|
+
response: { description: "The receipt." },
|
|
33623
|
+
errors: {
|
|
33624
|
+
400: true,
|
|
33625
|
+
403: "The Odoo push is off for this Space.",
|
|
33626
|
+
404: `No such account or transaction, or it is another member's "Only me" one.`,
|
|
33627
|
+
409: "Its bill is booked in Odoo already.",
|
|
33628
|
+
502: "Odoo didn't answer."
|
|
33629
|
+
},
|
|
33630
|
+
operationId: "money_push_odoo"
|
|
33631
|
+
},
|
|
33632
|
+
undoOdooDraft: {
|
|
33633
|
+
method: "delete",
|
|
33634
|
+
path: "/money/transactions/{id}/odoo-draft",
|
|
33635
|
+
scopes: ["finance:write"],
|
|
33636
|
+
tag: "Money",
|
|
33637
|
+
summary: "Take a money transaction's draft back from Odoo",
|
|
33638
|
+
description: "Undo a push: deletes the draft bill in Odoo while it is still a draft, and the transaction is ready again (`businessStatus: none`). A bill booked in Odoo meanwhile stays: the answer is 409 and the transaction says `posted`.",
|
|
33639
|
+
pathParams: { id: "The transaction's ULID." },
|
|
33640
|
+
pathParamSchemas: { id: ulidSchema },
|
|
33641
|
+
status: 200,
|
|
33642
|
+
response: { description: "`{ transactionId, line }`." },
|
|
33643
|
+
errors: {
|
|
33644
|
+
403: "The Odoo push is off for this Space.",
|
|
33645
|
+
404: `No such account or transaction, or it is another member's "Only me" one.`,
|
|
33646
|
+
409: "No draft to take back, or it was booked.",
|
|
33647
|
+
502: "Odoo didn't answer."
|
|
33648
|
+
},
|
|
33649
|
+
operationId: "money_push_odoo_undo"
|
|
33650
|
+
},
|
|
33651
|
+
review: {
|
|
33652
|
+
method: "get",
|
|
33653
|
+
path: "/money/review",
|
|
33654
|
+
scopes: ["finance:read"],
|
|
33655
|
+
tag: "Money",
|
|
33656
|
+
summary: "Review money transactions",
|
|
33657
|
+
description: "The review queue (`money_review`): `count` waiting and the oldest first (`limit`, default 50; `accountId`), each with a `suggestion` \u2014 the category its payee's sorted transactions went to most, and how many \u2014 when it has none yet.",
|
|
33658
|
+
query: [
|
|
33659
|
+
{ name: "accountId", description: "Only this account." },
|
|
33660
|
+
{ name: "limit", description: "How many (max 200).", type: "integer" }
|
|
33661
|
+
],
|
|
33662
|
+
querySchema: moneyReviewQuerySchema,
|
|
33663
|
+
status: 200,
|
|
33664
|
+
response: { description: "`{ count, items }`." },
|
|
33665
|
+
errors: { 400: true },
|
|
33666
|
+
operationId: "money_review"
|
|
33667
|
+
},
|
|
33668
|
+
sort: {
|
|
33669
|
+
method: "post",
|
|
33670
|
+
path: "/money/sort",
|
|
33671
|
+
scopes: ["finance:write"],
|
|
33672
|
+
tag: "Money",
|
|
33673
|
+
summary: "Sort money transactions",
|
|
33674
|
+
description: "Sort a batch in one call (`money_sort`): `items: [{ id, categoryId?, contactId?, kind?, note?, status? }]` (1\u2013200). A member's sort confirms each (`reviewed`); an agent's leaves it `unreviewed` for the member's nod. Answers with a receipt: a calm `line` per transaction, `before`/`after`, `undo` (post it to `/sort/undo` to take it all back) and `ruleProposals` (a payee sorted into the same category three times by hand, with no rule yet: post one to `/rules` to keep it).",
|
|
33675
|
+
body: moneySortInputSchema,
|
|
33676
|
+
status: 200,
|
|
33677
|
+
response: { description: "The receipt." },
|
|
33678
|
+
errors: {
|
|
33679
|
+
400: true,
|
|
33680
|
+
404: `No such account or transaction, or it is another member's "Only me" one.`
|
|
33681
|
+
},
|
|
33682
|
+
operationId: "money_sort"
|
|
33683
|
+
},
|
|
33684
|
+
undoSort: {
|
|
33685
|
+
method: "post",
|
|
33686
|
+
path: "/money/sort/undo",
|
|
33687
|
+
scopes: ["finance:write"],
|
|
33688
|
+
tag: "Money",
|
|
33689
|
+
summary: "Undo a money sort",
|
|
33690
|
+
description: "Put each transaction back the way a sort's receipt recorded it (its `undo`). Answers with a receipt of its own.",
|
|
33691
|
+
body: moneySortUndoInputSchema,
|
|
33692
|
+
status: 200,
|
|
33693
|
+
response: { description: "The receipt." },
|
|
33694
|
+
errors: {
|
|
33695
|
+
400: true,
|
|
33696
|
+
404: `No such account or transaction, or it is another member's "Only me" one.`
|
|
33697
|
+
},
|
|
33698
|
+
operationId: "money_sort_undo"
|
|
33699
|
+
},
|
|
33700
|
+
listRules: {
|
|
33701
|
+
method: "get",
|
|
33702
|
+
path: "/money/rules",
|
|
33703
|
+
scopes: ["finance:read"],
|
|
33704
|
+
tag: "Money",
|
|
33705
|
+
summary: "List money rules",
|
|
33706
|
+
description: "The sorting rules the key may see, in the order they run (`priority`), with their hits. A rule on an Only me account is its member's own.",
|
|
33707
|
+
status: 200,
|
|
33708
|
+
response: { description: "The rules." }
|
|
33709
|
+
},
|
|
33710
|
+
ruleSuggestions: {
|
|
33711
|
+
method: "get",
|
|
33712
|
+
path: "/money/rules/suggestions",
|
|
33713
|
+
scopes: ["finance:read"],
|
|
33714
|
+
tag: "Money",
|
|
33715
|
+
summary: "Suggest money rules",
|
|
33716
|
+
description: 'The rules worth making now: each payee sorted into the same category by hand three times or more this past year that no rule covers, most-sorted first (at most three): `name`, `payee`, `categoryName`, `conditions`, `actions`, `count`, `createdFromTransactionId`, and `goal` ({ nodeId, title } those payments were mostly counted toward, or null). Accepting one is a POST /money/rules with its fields, plus `actions.link: { nodeId, kind: "for_goal" }` to count the next ones toward the goal.',
|
|
33717
|
+
status: 200,
|
|
33718
|
+
response: { description: "The suggestions." }
|
|
33719
|
+
},
|
|
33720
|
+
createRule: {
|
|
33721
|
+
method: "post",
|
|
33722
|
+
path: "/money/rules",
|
|
33723
|
+
scopes: ["finance:write"],
|
|
33724
|
+
tag: "Money",
|
|
33725
|
+
summary: "Add a money rule",
|
|
33726
|
+
description: "`id`, `name`, `conditions` (all must hold: `counterpartyContains`, `descriptionContains`, `counterpartyIbanHash`, `structuredRefPrefix`, `direction` in/out, `amountMin`/`amountMax` on the absolute amount) and `actions` (`categoryId`, `contactId`, `kind`, `markReviewed`, `link: { nodeId, kind }`), optional `accountId`, `priority`, `createdFromTransactionId`, `visibility`. It runs over what's still unreviewed right away; a hand sort is never overwritten.",
|
|
33727
|
+
body: createMoneyRuleInputSchema,
|
|
33728
|
+
status: 201,
|
|
33729
|
+
response: { description: "The rule, with its first hits." },
|
|
33730
|
+
errors: {
|
|
33731
|
+
400: true,
|
|
33732
|
+
404: `No such account or transaction, or it is another member's "Only me" one.`
|
|
33733
|
+
}
|
|
33734
|
+
},
|
|
33735
|
+
applyRules: {
|
|
33736
|
+
method: "post",
|
|
33737
|
+
path: "/money/rules/apply",
|
|
33738
|
+
scopes: ["finance:write"],
|
|
33739
|
+
tag: "Money",
|
|
33740
|
+
summary: "Apply money rules",
|
|
33741
|
+
description: "Run the rules, then the transfer matching between own accounts, over what's still unreviewed (optionally one `accountId`). Answers `{ sorted, transfers }`.",
|
|
33742
|
+
body: applyMoneyRulesInputSchema,
|
|
33743
|
+
bodyOptional: true,
|
|
33744
|
+
status: 200,
|
|
33745
|
+
response: { description: "The counts." },
|
|
33746
|
+
errors: { 404: `No such account or transaction, or it is another member's "Only me" one.` }
|
|
33747
|
+
},
|
|
33748
|
+
getRule: {
|
|
33749
|
+
method: "get",
|
|
33750
|
+
path: "/money/rules/{id}",
|
|
33751
|
+
scopes: ["finance:read"],
|
|
33752
|
+
tag: "Money",
|
|
33753
|
+
summary: "Get a money rule",
|
|
33754
|
+
description: "One rule.",
|
|
33755
|
+
pathParams: { id: "The rule's ULID." },
|
|
33756
|
+
pathParamSchemas: { id: ulidSchema },
|
|
33757
|
+
status: 200,
|
|
33758
|
+
response: { description: "The rule." },
|
|
33759
|
+
errors: { 404: `No such account or transaction, or it is another member's "Only me" one.` }
|
|
33760
|
+
},
|
|
33761
|
+
updateRule: {
|
|
33762
|
+
method: "patch",
|
|
33763
|
+
path: "/money/rules/{id}",
|
|
33764
|
+
scopes: ["finance:write"],
|
|
33765
|
+
tag: "Money",
|
|
33766
|
+
summary: "Update a money rule",
|
|
33767
|
+
description: "Rename it, change what it matches or does, its priority, or switch it off.",
|
|
33768
|
+
pathParams: { id: "The rule's ULID." },
|
|
33769
|
+
pathParamSchemas: { id: ulidSchema },
|
|
33770
|
+
body: updateMoneyRuleInputSchema,
|
|
33771
|
+
status: 200,
|
|
33772
|
+
response: { description: "The rule." },
|
|
33773
|
+
errors: {
|
|
33774
|
+
400: true,
|
|
33775
|
+
404: `No such account or transaction, or it is another member's "Only me" one.`
|
|
33776
|
+
}
|
|
33777
|
+
},
|
|
33778
|
+
removeRule: {
|
|
33779
|
+
method: "delete",
|
|
33780
|
+
path: "/money/rules/{id}",
|
|
33781
|
+
scopes: ["finance:write"],
|
|
33782
|
+
tag: "Money",
|
|
33783
|
+
summary: "Remove a money rule",
|
|
33784
|
+
description: "What it already sorted stays sorted.",
|
|
33785
|
+
pathParams: { id: "The rule's ULID." },
|
|
33786
|
+
pathParamSchemas: { id: ulidSchema },
|
|
33787
|
+
status: 204,
|
|
33788
|
+
response: { description: "Removed." },
|
|
33789
|
+
errors: { 404: `No such account or transaction, or it is another member's "Only me" one.` }
|
|
33790
|
+
},
|
|
33791
|
+
budgetMonth: {
|
|
33792
|
+
method: "get",
|
|
33793
|
+
path: "/money/budget",
|
|
33794
|
+
scopes: ["finance:read"],
|
|
33795
|
+
tag: "Money",
|
|
33796
|
+
summary: "Get the money plan for a month",
|
|
33797
|
+
description: "A month's plan next to what happened (plan vs record): `rows` per category (fixed, then flexible, then saving) with `planned` (the plan lines the scope covers, listed in `lines`), `spent` so far (spending less refunds; for a saving category, what moved toward it) and `lastMonth`; a `summary` with `incomeIn`, `plannedOut`, `spent`, `unsorted` and `notYetPlanned`. Categories show when planned, or spent on this month or last. `scope`: `all` (default), `space` (the household's accounts and plan) or `owner` (yours). Nothing is judged: a category ahead of its plan is just ahead.",
|
|
33798
|
+
query: [
|
|
33799
|
+
{ name: "month", description: "The month, YYYY-MM.", required: true },
|
|
33800
|
+
{ name: "scope", description: "all, space or owner." }
|
|
33801
|
+
],
|
|
33802
|
+
querySchema: moneyBudgetQuerySchema,
|
|
33803
|
+
status: 200,
|
|
33804
|
+
response: { description: "The month." },
|
|
33805
|
+
errors: { 400: true }
|
|
33806
|
+
},
|
|
33807
|
+
setBudgetLine: {
|
|
33808
|
+
method: "put",
|
|
33809
|
+
path: "/money/budget/lines",
|
|
33810
|
+
scopes: ["finance:write"],
|
|
33811
|
+
tag: "Money",
|
|
33812
|
+
summary: "Set a money plan line",
|
|
33813
|
+
description: "Plan a category for a month: `month`, `categoryId` (a fixed, flexible or saving one), `planned` (never negative), optional `note`. The household's line, or `mine: true` for your own (only you see it). Setting it again replaces the amount (and the note, when given). `madeVia: agent` marks a line the agent proposed.",
|
|
33814
|
+
body: setMoneyBudgetLineInputSchema,
|
|
33815
|
+
status: 200,
|
|
33816
|
+
response: { description: "The line." },
|
|
33817
|
+
errors: { 400: true, 404: true }
|
|
33818
|
+
},
|
|
33819
|
+
removeBudgetLine: {
|
|
33820
|
+
method: "delete",
|
|
33821
|
+
path: "/money/budget/lines/{id}",
|
|
33822
|
+
scopes: ["finance:write"],
|
|
33823
|
+
tag: "Money",
|
|
33824
|
+
summary: "Remove a money plan line",
|
|
33825
|
+
description: "Take a category out of a month's plan.",
|
|
33826
|
+
pathParams: { id: "The plan line's ULID." },
|
|
33827
|
+
pathParamSchemas: { id: ulidSchema },
|
|
33828
|
+
status: 204,
|
|
33829
|
+
response: { description: "Removed." },
|
|
33830
|
+
errors: { 404: true }
|
|
33831
|
+
},
|
|
33832
|
+
draftBudget: {
|
|
33833
|
+
method: "post",
|
|
33834
|
+
path: "/money/budget/draft",
|
|
33835
|
+
scopes: ["finance:write"],
|
|
33836
|
+
tag: "Money",
|
|
33837
|
+
summary: "Draft a money plan from history",
|
|
33838
|
+
description: "Draft `month`'s household plan from the `months` before it (3 by default): per fixed or flexible category spent on, the average month rounded up (fixed to the euro, flexible to ten). Categories the month already plans are kept. Answers `{ lines: [{ id, categoryId, name, planned }], kept, months }`; taking the lines out (DELETE /money/budget/lines/{id}) is the undo.",
|
|
33839
|
+
body: draftMoneyBudgetInputSchema,
|
|
33840
|
+
status: 200,
|
|
33841
|
+
response: { description: "The drafted lines." },
|
|
33842
|
+
errors: { 400: true }
|
|
33843
|
+
},
|
|
33844
|
+
copyBudget: {
|
|
33845
|
+
method: "post",
|
|
33846
|
+
path: "/money/budget/copy",
|
|
33847
|
+
scopes: ["finance:write"],
|
|
33848
|
+
tag: "Money",
|
|
33849
|
+
summary: "Copy a money plan to another month",
|
|
33850
|
+
description: "Copy `from` month's plan into `to`: each line stays the household's or yours; a line `to` already has is kept. Answers `{ copied, kept }`.",
|
|
33851
|
+
body: copyMoneyBudgetInputSchema,
|
|
33852
|
+
status: 200,
|
|
33853
|
+
response: { description: "The counts." },
|
|
33854
|
+
errors: { 400: true }
|
|
33855
|
+
},
|
|
33856
|
+
year: {
|
|
33857
|
+
method: "get",
|
|
33858
|
+
path: "/money/year",
|
|
33859
|
+
scopes: ["finance:read"],
|
|
33860
|
+
tag: "Money",
|
|
33861
|
+
summary: "Get the year in money",
|
|
33862
|
+
description: "A calendar year of the ledger, like Admin's yearly review: `totals` (`income`, `spent` \u2014 fixed and flexible spending and what isn't sorted, refunds netted, transfers left out \u2014 and `saved`, what moved toward saving categories) and `lastYear` (the same months a year earlier; null when nothing was booked then); `months` January to December; `spending` and `income` by category, biggest first, each with `lastYear`; `recurring`: each tracked stream's `thisYear` and `lastYear` with `change` (new, stopped, up, down or same), the biggest change first; `goals`: what went toward each this year (`thisYear`), `saved` and `target`. A year under way counts to this month (`through`); `firstYear` is the oldest year the ledger reaches. Read over the accounts counted in the budget; another member's Only me account, stream or goal never adds to it. `year` 2000\u20132100 (this one by default); `scope`: `all` (default), `space` or `owner`.",
|
|
33863
|
+
query: [
|
|
33864
|
+
{ name: "year", description: "The calendar year (default this one)." },
|
|
33865
|
+
{ name: "scope", description: "all, space or owner." }
|
|
33866
|
+
],
|
|
33867
|
+
querySchema: moneyYearQuerySchema,
|
|
33868
|
+
status: 200,
|
|
33869
|
+
response: { description: "The year." },
|
|
33870
|
+
errors: { 400: true }
|
|
33871
|
+
},
|
|
33872
|
+
netWorthRead: {
|
|
33873
|
+
method: "get",
|
|
33874
|
+
path: "/money/net-worth",
|
|
33875
|
+
scopes: ["finance:read"],
|
|
33876
|
+
tag: "Money",
|
|
33877
|
+
summary: "Get net worth and its monthly line",
|
|
33878
|
+
description: "Net worth for the accounts that count in it (`includeInNetWorth`): `total`, `have` and `owe` this month, `points` (one per month, oldest first, the current month last; `total` null before any account had a value) and `accounts` (biggest first, each with its `value`, `source` \u2014 balance, ledger or manual \u2014 and the `month` that value is from). A loan or a credit card always counts as owed. This month follows each account's balance; the months before an account was first read are worked back from its ledger; a value set by hand carries on until the next one. `scope`: `all` (default), `space` or `owner`; `months` 2\u201360 (12 by default).",
|
|
33879
|
+
query: [
|
|
33880
|
+
{ name: "scope", description: "all, space or owner." },
|
|
33881
|
+
{ name: "months", description: "How many months the line covers (2\u201360, default 12)." }
|
|
33882
|
+
],
|
|
33883
|
+
querySchema: moneyNetWorthQuerySchema,
|
|
33884
|
+
status: 200,
|
|
33885
|
+
response: { description: "Net worth." },
|
|
33886
|
+
errors: { 400: true }
|
|
33887
|
+
},
|
|
33888
|
+
setNetWorthValue: {
|
|
33889
|
+
method: "put",
|
|
33890
|
+
path: "/money/net-worth/values",
|
|
33891
|
+
scopes: ["finance:write"],
|
|
33892
|
+
tag: "Money",
|
|
33893
|
+
summary: "Set an account's value for a month",
|
|
33894
|
+
description: "Value an account by hand for a month (a house's estimate, a car, a pension statement): `accountId`, `value` (a decimal string), optional `month` (YYYY-MM, this month by default; a month ahead is a 400). Again for the same month replaces it. This month's value also becomes the account's balance, unless a bank link keeps that. Answers the snapshot `{ id, accountId, month, value, source }`.",
|
|
33895
|
+
body: setMoneyNetWorthValueInputSchema,
|
|
33896
|
+
status: 200,
|
|
33897
|
+
response: { description: "The snapshot." },
|
|
33898
|
+
errors: { 400: true, 404: true }
|
|
33899
|
+
},
|
|
33900
|
+
listGoals: {
|
|
33901
|
+
method: "get",
|
|
33902
|
+
path: "/money/goals",
|
|
33903
|
+
scopes: ["finance:read"],
|
|
33904
|
+
tag: "Money",
|
|
33905
|
+
summary: "List money goals",
|
|
33906
|
+
description: "The goals this key may see (the household's, and its member's Only me ones), soonest target first: `targetAmount`, `targetOn`, `monthlyPlan`, the pot's account and Project by name, `saved` (`savedBefore` plus the transactions counted toward it) and the lines' `linesPlanned`/`linesPaid`.",
|
|
33907
|
+
status: 200,
|
|
33908
|
+
response: { description: "The goals." }
|
|
33909
|
+
},
|
|
33910
|
+
createGoal: {
|
|
33911
|
+
method: "post",
|
|
33912
|
+
path: "/money/goals",
|
|
33913
|
+
scopes: ["finance:write"],
|
|
33914
|
+
tag: "Money",
|
|
33915
|
+
summary: "Set a money goal",
|
|
33916
|
+
description: "`id`, `title`, `targetAmount`, optional `targetOn`, `accountId` (where the pot sits), `monthlyPlan`, `savedBefore`, `projectId` (a Project), `startedOn`. Only me unless `visibility: space`.",
|
|
33917
|
+
body: createMoneyGoalInputSchema,
|
|
33918
|
+
status: 201,
|
|
33919
|
+
response: { description: "The goal." },
|
|
33920
|
+
errors: { 400: true, 404: true }
|
|
33921
|
+
},
|
|
33922
|
+
getGoal: {
|
|
33923
|
+
method: "get",
|
|
33924
|
+
path: "/money/goals/{id}",
|
|
33925
|
+
scopes: ["finance:read"],
|
|
33926
|
+
tag: "Money",
|
|
33927
|
+
summary: "Get a money goal",
|
|
33928
|
+
description: "One goal with its `lines` and the `contributions` counted toward it, newest first.",
|
|
33929
|
+
pathParams: { id: "The goal's ULID." },
|
|
33930
|
+
pathParamSchemas: { id: ulidSchema },
|
|
33931
|
+
status: 200,
|
|
33932
|
+
response: { description: "The goal." },
|
|
33933
|
+
errors: { 404: true }
|
|
33934
|
+
},
|
|
33935
|
+
updateGoal: {
|
|
33936
|
+
method: "patch",
|
|
33937
|
+
path: "/money/goals/{id}",
|
|
33938
|
+
scopes: ["finance:write"],
|
|
33939
|
+
tag: "Money",
|
|
33940
|
+
summary: "Update a money goal",
|
|
33941
|
+
description: "Change any field, or `status` (active \xB7 reached \xB7 paused).",
|
|
33942
|
+
pathParams: { id: "The goal's ULID." },
|
|
33943
|
+
pathParamSchemas: { id: ulidSchema },
|
|
33944
|
+
body: updateMoneyGoalInputSchema,
|
|
33945
|
+
status: 200,
|
|
33946
|
+
response: { description: "The goal." },
|
|
33947
|
+
errors: { 400: true, 404: true }
|
|
33095
33948
|
},
|
|
33096
|
-
|
|
33949
|
+
removeGoal: {
|
|
33950
|
+
method: "delete",
|
|
33951
|
+
path: "/money/goals/{id}",
|
|
33952
|
+
scopes: ["finance:write"],
|
|
33953
|
+
tag: "Money",
|
|
33954
|
+
summary: "Remove a money goal",
|
|
33955
|
+
description: "Let it go (to Trash); the money and the transactions stay.",
|
|
33956
|
+
pathParams: { id: "The goal's ULID." },
|
|
33957
|
+
pathParamSchemas: { id: ulidSchema },
|
|
33958
|
+
status: 204,
|
|
33959
|
+
response: { description: "Removed." },
|
|
33960
|
+
errors: { 404: true }
|
|
33961
|
+
},
|
|
33962
|
+
addGoalLine: {
|
|
33963
|
+
method: "post",
|
|
33964
|
+
path: "/money/goals/{id}/lines",
|
|
33965
|
+
scopes: ["finance:write"],
|
|
33966
|
+
tag: "Money",
|
|
33967
|
+
summary: "Add a money goal line",
|
|
33968
|
+
description: "What the goal pays for: `id`, `title`, `planned`, optional `paid`, `note`, `dueOn`, `sortOrder`.",
|
|
33969
|
+
pathParams: { id: "The goal's ULID." },
|
|
33970
|
+
pathParamSchemas: { id: ulidSchema },
|
|
33971
|
+
body: createMoneyGoalLineInputSchema,
|
|
33972
|
+
status: 201,
|
|
33973
|
+
response: { description: "The line." },
|
|
33974
|
+
errors: { 400: true, 404: true }
|
|
33975
|
+
},
|
|
33976
|
+
updateGoalLine: {
|
|
33097
33977
|
method: "patch",
|
|
33098
|
-
path: "/
|
|
33099
|
-
scopes: ["
|
|
33100
|
-
tag: "
|
|
33101
|
-
summary: "
|
|
33102
|
-
description: "Change
|
|
33103
|
-
|
|
33978
|
+
path: "/money/goals/lines/{lineId}",
|
|
33979
|
+
scopes: ["finance:write"],
|
|
33980
|
+
tag: "Money",
|
|
33981
|
+
summary: "Update a money goal line",
|
|
33982
|
+
description: "Change what's planned or paid, the note or the day it's due.",
|
|
33983
|
+
pathParams: { lineId: "The line's ULID." },
|
|
33984
|
+
pathParamSchemas: { lineId: ulidSchema },
|
|
33985
|
+
body: updateMoneyGoalLineInputSchema,
|
|
33104
33986
|
status: 200,
|
|
33105
|
-
response: { description: "The
|
|
33106
|
-
errors: { 400: true, 404: true }
|
|
33107
|
-
webhook: "member.role.updated"
|
|
33987
|
+
response: { description: "The line." },
|
|
33988
|
+
errors: { 400: true, 404: true }
|
|
33108
33989
|
},
|
|
33109
|
-
|
|
33990
|
+
removeGoalLine: {
|
|
33110
33991
|
method: "delete",
|
|
33111
|
-
path: "/
|
|
33112
|
-
scopes: ["
|
|
33113
|
-
tag: "
|
|
33114
|
-
summary: "Remove a
|
|
33115
|
-
description: "
|
|
33992
|
+
path: "/money/goals/lines/{lineId}",
|
|
33993
|
+
scopes: ["finance:write"],
|
|
33994
|
+
tag: "Money",
|
|
33995
|
+
summary: "Remove a money goal line",
|
|
33996
|
+
description: "Take a line off the goal.",
|
|
33997
|
+
pathParams: { lineId: "The line's ULID." },
|
|
33998
|
+
pathParamSchemas: { lineId: ulidSchema },
|
|
33116
33999
|
status: 204,
|
|
33117
34000
|
response: { description: "Removed." },
|
|
33118
|
-
errors: { 404: true }
|
|
33119
|
-
|
|
33120
|
-
|
|
33121
|
-
|
|
33122
|
-
|
|
33123
|
-
|
|
33124
|
-
|
|
33125
|
-
|
|
33126
|
-
|
|
33127
|
-
|
|
33128
|
-
|
|
33129
|
-
|
|
33130
|
-
tag: "Habits",
|
|
33131
|
-
summary: "List metrics",
|
|
33132
|
-
description: "Weight (kg), sleep (h), mood (1\u20135), the day rating, energy, bedtime, resting heart rate (bpm) and HRV (ms) as trend lines: one point per day in the member's timezone (that day's last value, hand-logged or from Google Fit or Google Health), oldest first, plus the latest. No target, no streak. The key must act for a member. Resting heart rate and HRV are health data: without `health:read` held by name their lines come back empty.",
|
|
33133
|
-
query: [
|
|
33134
|
-
{ name: "days", description: "How far back, 1\u2013730 days (default 90).", type: "integer" }
|
|
33135
|
-
],
|
|
33136
|
-
querySchema: metricsQuerySchema,
|
|
34001
|
+
errors: { 404: true }
|
|
34002
|
+
},
|
|
34003
|
+
addGoalContribution: {
|
|
34004
|
+
method: "post",
|
|
34005
|
+
path: "/money/goals/{id}/contributions",
|
|
34006
|
+
scopes: ["finance:write"],
|
|
34007
|
+
tag: "Money",
|
|
34008
|
+
summary: "Count a transaction toward a money goal",
|
|
34009
|
+
description: "`transactionId`: money moved into the pot now counts as saved (a `for_goal` link). Again is a no-op.",
|
|
34010
|
+
pathParams: { id: "The goal's ULID." },
|
|
34011
|
+
pathParamSchemas: { id: ulidSchema },
|
|
34012
|
+
body: moneyGoalContributionInputSchema,
|
|
33137
34013
|
status: 200,
|
|
33138
|
-
response: { description: "
|
|
33139
|
-
errors: {
|
|
34014
|
+
response: { description: "The goal." },
|
|
34015
|
+
errors: { 400: true, 404: true }
|
|
33140
34016
|
},
|
|
33141
|
-
|
|
34017
|
+
removeGoalContribution: {
|
|
34018
|
+
method: "delete",
|
|
34019
|
+
path: "/money/goals/{id}/contributions/{transactionId}",
|
|
34020
|
+
scopes: ["finance:write"],
|
|
34021
|
+
tag: "Money",
|
|
34022
|
+
summary: "Stop counting a transaction toward a money goal",
|
|
34023
|
+
description: "The transaction stays; it just no longer counts as saved for this goal.",
|
|
34024
|
+
pathParams: { id: "The goal's ULID.", transactionId: "The transaction's ULID." },
|
|
34025
|
+
pathParamSchemas: { id: ulidSchema, transactionId: ulidSchema },
|
|
34026
|
+
status: 200,
|
|
34027
|
+
response: { description: "The goal." },
|
|
34028
|
+
errors: { 404: true }
|
|
34029
|
+
},
|
|
34030
|
+
recurringOverview: {
|
|
33142
34031
|
method: "get",
|
|
33143
|
-
path: "/
|
|
33144
|
-
scopes: ["
|
|
33145
|
-
tag: "
|
|
33146
|
-
summary: "List
|
|
33147
|
-
description: "
|
|
33148
|
-
query: [
|
|
33149
|
-
{ name: "days", description: "How far back, 1\u2013365 days (default 14).", type: "integer" }
|
|
33150
|
-
],
|
|
33151
|
-
querySchema: sessionsQuerySchema,
|
|
34032
|
+
path: "/money/recurring",
|
|
34033
|
+
scopes: ["finance:read"],
|
|
34034
|
+
tag: "Money",
|
|
34035
|
+
summary: "List recurring money streams",
|
|
34036
|
+
description: "Recurring payments and subscriptions: `streams` (active and paused, soonest next first; each with `yearly`, the provider, category and paper by name, the paper's soonest `keyDate` \u2014 cancel-by, promo ends \u2014 and `lastPaid` from the ledger), `found` (patterns over the whole ledger, across accounts, that aren't tracked \u2014 grouped by counterparty IBAN, name or the bank line's payee and split by amount: payee, `kind` (subscription, or standing_order for money moved to an own account), cadence, amount, next day, whose account), `changes` (a stream whose latest payment differs by more than 5%) and `summary` (fixed costs per year: all, household, yours, the business share).",
|
|
33152
34037
|
status: 200,
|
|
33153
|
-
response: { description: "The
|
|
33154
|
-
errors: { 403: NO_MEMBER2 }
|
|
34038
|
+
response: { description: "The overview." }
|
|
33155
34039
|
},
|
|
33156
|
-
|
|
34040
|
+
createRecurring: {
|
|
33157
34041
|
method: "post",
|
|
33158
|
-
path: "/
|
|
33159
|
-
scopes: ["
|
|
33160
|
-
tag: "
|
|
33161
|
-
summary: "
|
|
33162
|
-
description: "
|
|
33163
|
-
body:
|
|
34042
|
+
path: "/money/recurring",
|
|
34043
|
+
scopes: ["finance:write"],
|
|
34044
|
+
tag: "Money",
|
|
34045
|
+
summary: "Track a recurring money stream",
|
|
34046
|
+
description: "`id`, `title`, `expectedAmount`, optional `cadence` (weekly \xB7 monthly \xB7 quarterly \xB7 yearly), `nextOn`, `matchText` (the payee, to recognise its payments), `contactId`, `categoryId`, `documentId` (its Admin paper), `businessShare` (0\u2013100), `pick` (keep \xB7 negotiate \xB7 compare \xB7 drop), `detectedBy`. `status: ignored` calls a found pattern a one-off. Only me unless `visibility: space`.",
|
|
34047
|
+
body: createMoneyRecurringInputSchema,
|
|
33164
34048
|
status: 201,
|
|
33165
|
-
response: { description: "
|
|
33166
|
-
errors: { 400: true,
|
|
34049
|
+
response: { description: "The stream." },
|
|
34050
|
+
errors: { 400: true, 404: true }
|
|
33167
34051
|
},
|
|
33168
|
-
|
|
33169
|
-
method: "
|
|
33170
|
-
path: "/
|
|
33171
|
-
|
|
33172
|
-
|
|
33173
|
-
|
|
33174
|
-
|
|
33175
|
-
|
|
33176
|
-
},
|
|
33177
|
-
|
|
33178
|
-
|
|
33179
|
-
|
|
33180
|
-
|
|
33181
|
-
|
|
33182
|
-
|
|
33183
|
-
|
|
33184
|
-
|
|
33185
|
-
|
|
34052
|
+
getRecurring: {
|
|
34053
|
+
method: "get",
|
|
34054
|
+
path: "/money/recurring/{id}",
|
|
34055
|
+
scopes: ["finance:read"],
|
|
34056
|
+
tag: "Money",
|
|
34057
|
+
summary: "Get a recurring money stream",
|
|
34058
|
+
description: "One stream, with its paper's soonest key date.",
|
|
34059
|
+
pathParams: { id: "The stream's ULID." },
|
|
34060
|
+
pathParamSchemas: { id: ulidSchema },
|
|
34061
|
+
status: 200,
|
|
34062
|
+
response: { description: "The stream." },
|
|
34063
|
+
errors: { 404: true }
|
|
34064
|
+
},
|
|
34065
|
+
updateRecurring: {
|
|
34066
|
+
method: "patch",
|
|
34067
|
+
path: "/money/recurring/{id}",
|
|
34068
|
+
scopes: ["finance:write"],
|
|
34069
|
+
tag: "Money",
|
|
34070
|
+
summary: "Update a recurring money stream",
|
|
34071
|
+
description: "Change any field: the amount, the next day, the paper, the pick, or `status` (active \xB7 paused \xB7 cancelled \xB7 ignored).",
|
|
34072
|
+
pathParams: { id: "The stream's ULID." },
|
|
34073
|
+
pathParamSchemas: { id: ulidSchema },
|
|
34074
|
+
body: updateMoneyRecurringInputSchema,
|
|
34075
|
+
status: 200,
|
|
34076
|
+
response: { description: "The stream." },
|
|
34077
|
+
errors: { 400: true, 404: true }
|
|
34078
|
+
},
|
|
34079
|
+
removeRecurring: {
|
|
34080
|
+
method: "delete",
|
|
34081
|
+
path: "/money/recurring/{id}",
|
|
34082
|
+
scopes: ["finance:write"],
|
|
34083
|
+
tag: "Money",
|
|
34084
|
+
summary: "Remove a recurring money stream",
|
|
34085
|
+
description: "Stop tracking it (to Trash); its payments stay.",
|
|
34086
|
+
pathParams: { id: "The stream's ULID." },
|
|
34087
|
+
pathParamSchemas: { id: ulidSchema },
|
|
34088
|
+
status: 204,
|
|
34089
|
+
response: { description: "Removed." },
|
|
34090
|
+
errors: { 404: true }
|
|
33186
34091
|
}
|
|
33187
34092
|
});
|
|
33188
34093
|
|
|
@@ -35766,7 +36671,7 @@ function parseCapture2(input, now) {
|
|
|
35766
36671
|
|
|
35767
36672
|
// src/meta.ts
|
|
35768
36673
|
var CLI_NAME = "do";
|
|
35769
|
-
var VERSION = "1.314.
|
|
36674
|
+
var VERSION = "1.314.1";
|
|
35770
36675
|
var API_PREFIX = "/api/v1";
|
|
35771
36676
|
var DEFAULT_API_URL = "http://localhost:3001";
|
|
35772
36677
|
|
|
@@ -40436,9 +41341,9 @@ var COMMAND_SPECS = [
|
|
|
40436
41341
|
summary: "List a node's files, newest first (never their bytes).",
|
|
40437
41342
|
args: [],
|
|
40438
41343
|
flags: [{ name: "node", type: "string", description: "The owner node's ULID (required)." }],
|
|
40439
|
-
scopes: [
|
|
41344
|
+
scopes: [...fileOperations.list.scopes],
|
|
40440
41345
|
returns: "FileView",
|
|
40441
|
-
notes:
|
|
41346
|
+
notes: `${routeOf(fileOperations.list)}?nodeId=. A node the key's member can't see is not found (exit 4).`
|
|
40442
41347
|
},
|
|
40443
41348
|
{
|
|
40444
41349
|
path: ["files", "get"],
|
|
@@ -40507,9 +41412,9 @@ var COMMAND_SPECS = [
|
|
|
40507
41412
|
summary: "Get a short-lived link that shows a file in a browser (a PDF, a picture).",
|
|
40508
41413
|
args: [{ name: "id", required: true, description: "File ULID." }],
|
|
40509
41414
|
flags: [],
|
|
40510
|
-
scopes: [
|
|
41415
|
+
scopes: [...fileOperations.viewUrl.scopes],
|
|
40511
41416
|
returns: "FileViewUrl",
|
|
40512
|
-
notes:
|
|
41417
|
+
notes: `${routeOf(fileOperations.viewUrl)}. Prints the URL (--json: id, url, expiresAt). It works for ten minutes, opens the file inline, and only while this key could still download it.`
|
|
40513
41418
|
},
|
|
40514
41419
|
{
|
|
40515
41420
|
path: ["files", "delete"],
|
|
@@ -41702,36 +42607,36 @@ var COMMAND_SPECS = [
|
|
|
41702
42607
|
summary: "List the money accounts you may see: the household's and your Only me ones.",
|
|
41703
42608
|
args: [],
|
|
41704
42609
|
flags: [],
|
|
41705
|
-
scopes: [
|
|
42610
|
+
scopes: [...moneyOperations.listAccounts.scopes],
|
|
41706
42611
|
returns: "MoneyAccountView[]",
|
|
41707
|
-
notes:
|
|
42612
|
+
notes: `${routeOf(moneyOperations.listAccounts)}. Money is a sensitive group: \`*\` never covers finance:*.`
|
|
41708
42613
|
},
|
|
41709
42614
|
{
|
|
41710
42615
|
path: ["money", "account"],
|
|
41711
42616
|
summary: "Show one money account.",
|
|
41712
42617
|
args: [{ name: "id", required: true, description: "Account ULID." }],
|
|
41713
42618
|
flags: [],
|
|
41714
|
-
scopes: [
|
|
42619
|
+
scopes: [...moneyOperations.getAccount.scopes],
|
|
41715
42620
|
returns: "MoneyAccountView",
|
|
41716
|
-
notes:
|
|
42621
|
+
notes: `${routeOf(moneyOperations.getAccount)}.`
|
|
41717
42622
|
},
|
|
41718
42623
|
{
|
|
41719
42624
|
path: ["money", "account-add"],
|
|
41720
42625
|
summary: "Open a money account (Only me unless --data says visibility: space).",
|
|
41721
42626
|
args: [],
|
|
41722
42627
|
flags: [{ name: "data", type: "string", description: "CreateMoneyAccountInput JSON." }],
|
|
41723
|
-
scopes: [
|
|
42628
|
+
scopes: [...moneyOperations.createAccount.scopes],
|
|
41724
42629
|
returns: "MoneyAccountView",
|
|
41725
|
-
notes:
|
|
42630
|
+
notes: `${routeOf(moneyOperations.createAccount)}. \`do money account-add --data '{"title":"Joint","kind":"current","holder":"joint","visibility":"space"}'\`. An IBAN is stored only masked and hashed.`
|
|
41726
42631
|
},
|
|
41727
42632
|
{
|
|
41728
42633
|
path: ["money", "account-update"],
|
|
41729
42634
|
summary: "Edit a money account.",
|
|
41730
42635
|
args: [{ name: "id", required: true, description: "Account ULID." }],
|
|
41731
42636
|
flags: [{ name: "data", type: "string", description: "UpdateMoneyAccountInput JSON." }],
|
|
41732
|
-
scopes: [
|
|
42637
|
+
scopes: [...moneyOperations.updateAccount.scopes],
|
|
41733
42638
|
returns: "MoneyAccountView",
|
|
41734
|
-
notes:
|
|
42639
|
+
notes: `${routeOf(moneyOperations.updateAccount)}.`
|
|
41735
42640
|
},
|
|
41736
42641
|
{
|
|
41737
42642
|
path: ["money", "account-close"],
|
|
@@ -41740,18 +42645,18 @@ var COMMAND_SPECS = [
|
|
|
41740
42645
|
flags: [
|
|
41741
42646
|
{ name: "allow-destructive", type: "boolean", description: "Required to actually close." }
|
|
41742
42647
|
],
|
|
41743
|
-
scopes: [
|
|
42648
|
+
scopes: [...moneyOperations.removeAccount.scopes],
|
|
41744
42649
|
returns: "{ ok, closed }",
|
|
41745
|
-
notes:
|
|
42650
|
+
notes: `${routeOf(moneyOperations.removeAccount)}.`
|
|
41746
42651
|
},
|
|
41747
42652
|
{
|
|
41748
42653
|
path: ["money", "connections"],
|
|
41749
42654
|
summary: "List the bank links feeding your money accounts: bank, account, consent end, last sync.",
|
|
41750
42655
|
args: [],
|
|
41751
42656
|
flags: [],
|
|
41752
|
-
scopes: [
|
|
42657
|
+
scopes: [...moneyOperations.listConnections.scopes],
|
|
41753
42658
|
returns: "MoneyConnectionView[]",
|
|
41754
|
-
notes:
|
|
42659
|
+
notes: `${routeOf(moneyOperations.listConnections)}. \`reconnectSoon\` is true when the bank's consent ends within 14 days (or did). No credential or provider id is ever returned.`
|
|
41755
42660
|
},
|
|
41756
42661
|
{
|
|
41757
42662
|
path: ["money", "sync"],
|
|
@@ -41760,36 +42665,36 @@ var COMMAND_SPECS = [
|
|
|
41760
42665
|
flags: [
|
|
41761
42666
|
{ name: "account", type: "string", description: "Only the link feeding this account ULID." }
|
|
41762
42667
|
],
|
|
41763
|
-
scopes: [
|
|
42668
|
+
scopes: [...moneyOperations.syncConnections.scopes],
|
|
41764
42669
|
returns: "MoneyBankSyncResult",
|
|
41765
|
-
notes:
|
|
42670
|
+
notes: `${routeOf(moneyOperations.syncConnections)}. Rows go through the CSV import's pipeline, so nothing already imported is booked twice. Each result has outcome, imported, matched, duplicates and the error.`
|
|
41766
42671
|
},
|
|
41767
42672
|
{
|
|
41768
42673
|
path: ["money", "connection-syncs"],
|
|
41769
42674
|
summary: "Show a bank link's sync log, newest first.",
|
|
41770
42675
|
args: [{ name: "id", required: true, description: "Bank link (connection) ULID." }],
|
|
41771
42676
|
flags: [],
|
|
41772
|
-
scopes: [
|
|
42677
|
+
scopes: [...moneyOperations.listConnectionSyncs.scopes],
|
|
41773
42678
|
returns: "MoneyConnectionSync[]",
|
|
41774
|
-
notes:
|
|
42679
|
+
notes: `${routeOf(moneyOperations.listConnectionSyncs)}.`
|
|
41775
42680
|
},
|
|
41776
42681
|
{
|
|
41777
42682
|
path: ["money", "categories"],
|
|
41778
42683
|
summary: "List the household's money categories (the starting list arrives on first use).",
|
|
41779
42684
|
args: [],
|
|
41780
42685
|
flags: [],
|
|
41781
|
-
scopes: [
|
|
42686
|
+
scopes: [...moneyOperations.listCategories.scopes],
|
|
41782
42687
|
returns: "MoneyCategory[]",
|
|
41783
|
-
notes:
|
|
42688
|
+
notes: `${routeOf(moneyOperations.listCategories)}.`
|
|
41784
42689
|
},
|
|
41785
42690
|
{
|
|
41786
42691
|
path: ["money", "category-add"],
|
|
41787
42692
|
summary: "Add a money category.",
|
|
41788
42693
|
args: [],
|
|
41789
42694
|
flags: [{ name: "data", type: "string", description: "CreateMoneyCategoryInput JSON." }],
|
|
41790
|
-
scopes: [
|
|
42695
|
+
scopes: [...moneyOperations.createCategory.scopes],
|
|
41791
42696
|
returns: "MoneyCategory",
|
|
41792
|
-
notes:
|
|
42697
|
+
notes: `${routeOf(moneyOperations.createCategory)}. Two levels at most.`
|
|
41793
42698
|
},
|
|
41794
42699
|
{
|
|
41795
42700
|
path: ["money", "transactions"],
|
|
@@ -41812,27 +42717,27 @@ var COMMAND_SPECS = [
|
|
|
41812
42717
|
{ name: "limit", type: "string", description: "Page size (max 100)." },
|
|
41813
42718
|
{ name: "cursor", type: "string", description: "The previous page's nextCursor." }
|
|
41814
42719
|
],
|
|
41815
|
-
scopes: [
|
|
42720
|
+
scopes: [...moneyOperations.listTransactions.scopes],
|
|
41816
42721
|
returns: "{ data: MoneyTransactionView[], nextCursor }",
|
|
41817
|
-
notes:
|
|
42722
|
+
notes: `${routeOf(moneyOperations.listTransactions)}. Amounts are signed decimal strings. \`--business\` keeps rows with a business share; \`--business-status\` and \`--tax-tag\` narrow further.`
|
|
41818
42723
|
},
|
|
41819
42724
|
{
|
|
41820
42725
|
path: ["money", "transaction"],
|
|
41821
42726
|
summary: "Show one money transaction.",
|
|
41822
42727
|
args: [{ name: "id", required: true, description: "Transaction ULID." }],
|
|
41823
42728
|
flags: [],
|
|
41824
|
-
scopes: [
|
|
42729
|
+
scopes: [...moneyOperations.getTransaction.scopes],
|
|
41825
42730
|
returns: "MoneyTransactionView",
|
|
41826
|
-
notes:
|
|
42731
|
+
notes: `${routeOf(moneyOperations.getTransaction)}.`
|
|
41827
42732
|
},
|
|
41828
42733
|
{
|
|
41829
42734
|
path: ["money", "book"],
|
|
41830
42735
|
summary: "Book a transaction by hand (cash, or one the bank hasn't shown yet).",
|
|
41831
42736
|
args: [],
|
|
41832
42737
|
flags: [{ name: "data", type: "string", description: "CreateMoneyTransactionInput JSON." }],
|
|
41833
|
-
scopes: [
|
|
42738
|
+
scopes: [...moneyOperations.createTransaction.scopes],
|
|
41834
42739
|
returns: "MoneyTransactionView",
|
|
41835
|
-
notes:
|
|
42740
|
+
notes: `${routeOf(moneyOperations.createTransaction)}. \`do money book --data '{"accountId":"\u2026","bookedOn":"2026-10-18","amount":"-20","counterpartyName":"Fries stand"}'\`.`
|
|
41836
42741
|
},
|
|
41837
42742
|
{
|
|
41838
42743
|
path: ["money", "review"],
|
|
@@ -41842,9 +42747,9 @@ var COMMAND_SPECS = [
|
|
|
41842
42747
|
{ name: "account", type: "string", description: "Only this account (ULID)." },
|
|
41843
42748
|
{ name: "limit", type: "string", description: "How many (default 50, max 200)." }
|
|
41844
42749
|
],
|
|
41845
|
-
scopes: [
|
|
42750
|
+
scopes: [...moneyOperations.review.scopes],
|
|
41846
42751
|
returns: "MoneyReview",
|
|
41847
|
-
notes:
|
|
42752
|
+
notes: `${routeOf(moneyOperations.review)} (\`money_review\`).`
|
|
41848
42753
|
},
|
|
41849
42754
|
{
|
|
41850
42755
|
path: ["money", "sort"],
|
|
@@ -41874,36 +42779,36 @@ var COMMAND_SPECS = [
|
|
|
41874
42779
|
},
|
|
41875
42780
|
{ name: "data", type: "string", description: "MoneySortInput JSON: { items: [...] }." }
|
|
41876
42781
|
],
|
|
41877
|
-
scopes: [
|
|
42782
|
+
scopes: [...moneyOperations.sort.scopes],
|
|
41878
42783
|
returns: "MoneySortReceipt",
|
|
41879
|
-
notes:
|
|
42784
|
+
notes: `${routeOf(moneyOperations.sort)} (\`money_sort\`). A member's sort confirms it; an agent's leaves it for the member. The receipt's \`undo\` goes to \`do money sort-undo --data\`; \`ruleProposals\` to \`do money rule-add --data\`. A share on an \`asked\` row answers it: above 0 is business, 0 is not. A row whose bill is in Odoo keeps its share until the draft is taken back.`
|
|
41880
42785
|
},
|
|
41881
42786
|
{
|
|
41882
42787
|
path: ["money", "sort-undo"],
|
|
41883
42788
|
summary: "Take a sort back, from its receipt's undo.",
|
|
41884
42789
|
args: [],
|
|
41885
42790
|
flags: [{ name: "data", type: "string", description: "The receipt's `undo` JSON." }],
|
|
41886
|
-
scopes: [
|
|
42791
|
+
scopes: [...moneyOperations.undoSort.scopes],
|
|
41887
42792
|
returns: "MoneySortReceipt",
|
|
41888
|
-
notes:
|
|
42793
|
+
notes: `${routeOf(moneyOperations.undoSort)}.`
|
|
41889
42794
|
},
|
|
41890
42795
|
{
|
|
41891
42796
|
path: ["money", "splits"],
|
|
41892
42797
|
summary: "Show a transaction's parts (empty when it isn't split).",
|
|
41893
42798
|
args: [{ name: "id", required: true, description: "Transaction ULID." }],
|
|
41894
42799
|
flags: [],
|
|
41895
|
-
scopes: [
|
|
42800
|
+
scopes: [...moneyOperations.listSplits.scopes],
|
|
41896
42801
|
returns: "MoneySplitView[]",
|
|
41897
|
-
notes:
|
|
42802
|
+
notes: `${routeOf(moneyOperations.listSplits)}.`
|
|
41898
42803
|
},
|
|
41899
42804
|
{
|
|
41900
42805
|
path: ["money", "split"],
|
|
41901
42806
|
summary: `Split a transaction into parts (or --data '{"splits":[]}' to unsplit it).`,
|
|
41902
42807
|
args: [{ name: "id", required: true, description: "Transaction ULID." }],
|
|
41903
42808
|
flags: [{ name: "data", type: "string", description: "SetMoneySplitsInput JSON." }],
|
|
41904
|
-
scopes: [
|
|
42809
|
+
scopes: [...moneyOperations.setSplits.scopes],
|
|
41905
42810
|
returns: "MoneySplitsReceipt",
|
|
41906
|
-
notes:
|
|
42811
|
+
notes: `${routeOf(moneyOperations.setSplits)}. The parts add up to the transaction, each with its sign; a part may be owed by a member or a Contact: \`{"splits":[{"amount":"-70","categoryId":"\u2026"},{"amount":"-30","owedBy":{"contactId":"\u2026"},"owedAmount":"15"}]}\`. The receipt's \`undo\` goes back to \`do money split <id> --data\`.`
|
|
41907
42812
|
},
|
|
41908
42813
|
{
|
|
41909
42814
|
path: ["money", "share"],
|
|
@@ -41924,18 +42829,18 @@ var COMMAND_SPECS = [
|
|
|
41924
42829
|
},
|
|
41925
42830
|
{ name: "note", type: "string", description: "What it was, shown to whoever owes it." }
|
|
41926
42831
|
],
|
|
41927
|
-
scopes: [
|
|
42832
|
+
scopes: [...moneyOperations.share.scopes],
|
|
41928
42833
|
returns: "MoneySplitsReceipt",
|
|
41929
|
-
notes:
|
|
42834
|
+
notes: `${routeOf(moneyOperations.share)} (\`money_split\`). The member who owes a part sees that part and its note, never the transaction.`
|
|
41930
42835
|
},
|
|
41931
42836
|
{
|
|
41932
42837
|
path: ["money", "settle-up"],
|
|
41933
42838
|
summary: "Who owes you and whom you owe, per person, with the lines behind it.",
|
|
41934
42839
|
args: [],
|
|
41935
42840
|
flags: [],
|
|
41936
|
-
scopes: [
|
|
42841
|
+
scopes: [...moneyOperations.settleUp.scopes],
|
|
41937
42842
|
returns: "MoneySettleUp",
|
|
41938
|
-
notes:
|
|
42843
|
+
notes: `${routeOf(moneyOperations.settleUp)}. A positive balance is owed to you, a negative one by you. Needs a member behind the key.`
|
|
41939
42844
|
},
|
|
41940
42845
|
{
|
|
41941
42846
|
path: ["money", "settle"],
|
|
@@ -41955,9 +42860,9 @@ var COMMAND_SPECS = [
|
|
|
41955
42860
|
{ name: "transaction", type: "string", description: "The transfer that carried it (ULID)." },
|
|
41956
42861
|
{ name: "note", type: "string", description: "A note." }
|
|
41957
42862
|
],
|
|
41958
|
-
scopes: [
|
|
42863
|
+
scopes: [...moneyOperations.settle.scopes],
|
|
41959
42864
|
returns: "MoneySettlementView",
|
|
41960
|
-
notes:
|
|
42865
|
+
notes: `${routeOf(moneyOperations.settle)}. Undo: \`do money settlement-remove <id>\`.`
|
|
41961
42866
|
},
|
|
41962
42867
|
{
|
|
41963
42868
|
path: ["money", "settlement-remove"],
|
|
@@ -41966,9 +42871,9 @@ var COMMAND_SPECS = [
|
|
|
41966
42871
|
flags: [
|
|
41967
42872
|
{ name: "allow-destructive", type: "boolean", description: "Required to actually remove." }
|
|
41968
42873
|
],
|
|
41969
|
-
scopes: [
|
|
42874
|
+
scopes: [...moneyOperations.removeSettlement.scopes],
|
|
41970
42875
|
returns: "{ ok, removed }",
|
|
41971
|
-
notes:
|
|
42876
|
+
notes: `${routeOf(moneyOperations.removeSettlement)}.`
|
|
41972
42877
|
},
|
|
41973
42878
|
{
|
|
41974
42879
|
path: ["money", "tax-evidence"],
|
|
@@ -41978,72 +42883,72 @@ var COMMAND_SPECS = [
|
|
|
41978
42883
|
{ name: "year", type: "string", description: "The year (YYYY)." },
|
|
41979
42884
|
{ name: "tag", type: "string", description: "Only this tax tag." }
|
|
41980
42885
|
],
|
|
41981
|
-
scopes: [
|
|
42886
|
+
scopes: [...moneyOperations.taxEvidence.scopes],
|
|
41982
42887
|
returns: "MoneyTaxEvidence",
|
|
41983
|
-
notes:
|
|
42888
|
+
notes: `${routeOf(moneyOperations.taxEvidence)}?year=. Per tag, the year's payments oldest first, their signed total, and each one's evidence (linked nodes and their files).`
|
|
41984
42889
|
},
|
|
41985
42890
|
{
|
|
41986
42891
|
path: ["money", "odoo-push"],
|
|
41987
42892
|
summary: "Push a transaction's business share to Odoo as a draft vendor bill.",
|
|
41988
42893
|
args: [{ name: "id", required: true, description: "Transaction ULID." }],
|
|
41989
42894
|
flags: [{ name: "note", type: "string", description: "The note on the bill." }],
|
|
41990
|
-
scopes: [
|
|
42895
|
+
scopes: [...moneyOperations.pushOdooDraft.scopes],
|
|
41991
42896
|
returns: "MoneyOdooReceipt",
|
|
41992
|
-
notes:
|
|
42897
|
+
notes: `${routeOf(moneyOperations.pushOdooDraft)} (\`money_push_odoo\`). Draft only, never posted; the papers linked as evidence are attached. Idempotent on the bill's ref \`do:tx:<id>\`. Off (403) until the deployment sets MONEY_ODOO_PUSH and lists the Space. Undo: \`do money odoo-undo <id>\`.`
|
|
41993
42898
|
},
|
|
41994
42899
|
{
|
|
41995
42900
|
path: ["money", "odoo-undo"],
|
|
41996
42901
|
summary: "Take a draft bill back from Odoo while it is still a draft.",
|
|
41997
42902
|
args: [{ name: "id", required: true, description: "Transaction ULID." }],
|
|
41998
42903
|
flags: [],
|
|
41999
|
-
scopes: [
|
|
42904
|
+
scopes: [...moneyOperations.undoOdooDraft.scopes],
|
|
42000
42905
|
returns: "MoneyOdooUndoResult",
|
|
42001
|
-
notes:
|
|
42906
|
+
notes: `${routeOf(moneyOperations.undoOdooDraft)}. A bill posted in Odoo meanwhile can't be taken back (409); the transaction then says \`posted\`.`
|
|
42002
42907
|
},
|
|
42003
42908
|
{
|
|
42004
42909
|
path: ["money", "rules"],
|
|
42005
42910
|
summary: "List the sorting rules, in the order they run.",
|
|
42006
42911
|
args: [],
|
|
42007
42912
|
flags: [],
|
|
42008
|
-
scopes: [
|
|
42913
|
+
scopes: [...moneyOperations.listRules.scopes],
|
|
42009
42914
|
returns: "MoneyRuleView[]",
|
|
42010
|
-
notes:
|
|
42915
|
+
notes: `${routeOf(moneyOperations.listRules)}.`
|
|
42011
42916
|
},
|
|
42012
42917
|
{
|
|
42013
42918
|
path: ["money", "rule-suggestions"],
|
|
42014
42919
|
summary: "The rules worth making now: payees sorted the same way by hand, with their goal.",
|
|
42015
42920
|
args: [],
|
|
42016
42921
|
flags: [],
|
|
42017
|
-
scopes: [
|
|
42922
|
+
scopes: [...moneyOperations.ruleSuggestions.scopes],
|
|
42018
42923
|
returns: "MoneyRuleSuggestion[]",
|
|
42019
|
-
notes:
|
|
42924
|
+
notes: `${routeOf(moneyOperations.ruleSuggestions)}. Accept one with \`do money rule-add --data\` (its name, conditions and actions; add actions.link to its goal to count the next ones there).`
|
|
42020
42925
|
},
|
|
42021
42926
|
{
|
|
42022
42927
|
path: ["money", "rule"],
|
|
42023
42928
|
summary: "Show one sorting rule.",
|
|
42024
42929
|
args: [{ name: "id", required: true, description: "Rule ULID." }],
|
|
42025
42930
|
flags: [],
|
|
42026
|
-
scopes: [
|
|
42931
|
+
scopes: [...moneyOperations.getRule.scopes],
|
|
42027
42932
|
returns: "MoneyRuleView",
|
|
42028
|
-
notes:
|
|
42933
|
+
notes: `${routeOf(moneyOperations.getRule)}.`
|
|
42029
42934
|
},
|
|
42030
42935
|
{
|
|
42031
42936
|
path: ["money", "rule-add"],
|
|
42032
42937
|
summary: "Add a sorting rule; it runs over what's waiting right away.",
|
|
42033
42938
|
args: [],
|
|
42034
42939
|
flags: [{ name: "data", type: "string", description: "CreateMoneyRuleInput JSON." }],
|
|
42035
|
-
scopes: [
|
|
42940
|
+
scopes: [...moneyOperations.createRule.scopes],
|
|
42036
42941
|
returns: "MoneyRuleView",
|
|
42037
|
-
notes:
|
|
42942
|
+
notes: `${routeOf(moneyOperations.createRule)}. \`do money rule-add --data '{"name":"Supermarket","conditions":{"counterpartyContains":"supermarkt"},"actions":{"categoryId":"\u2026","markReviewed":true}}'\`. A hand sort is never overwritten.`
|
|
42038
42943
|
},
|
|
42039
42944
|
{
|
|
42040
42945
|
path: ["money", "rule-update"],
|
|
42041
42946
|
summary: "Edit a sorting rule (or switch it off).",
|
|
42042
42947
|
args: [{ name: "id", required: true, description: "Rule ULID." }],
|
|
42043
42948
|
flags: [{ name: "data", type: "string", description: "UpdateMoneyRuleInput JSON." }],
|
|
42044
|
-
scopes: [
|
|
42949
|
+
scopes: [...moneyOperations.updateRule.scopes],
|
|
42045
42950
|
returns: "MoneyRuleView",
|
|
42046
|
-
notes:
|
|
42951
|
+
notes: `${routeOf(moneyOperations.updateRule)}.`
|
|
42047
42952
|
},
|
|
42048
42953
|
{
|
|
42049
42954
|
path: ["money", "rule-remove"],
|
|
@@ -42052,18 +42957,18 @@ var COMMAND_SPECS = [
|
|
|
42052
42957
|
flags: [
|
|
42053
42958
|
{ name: "allow-destructive", type: "boolean", description: "Required to actually remove." }
|
|
42054
42959
|
],
|
|
42055
|
-
scopes: [
|
|
42960
|
+
scopes: [...moneyOperations.removeRule.scopes],
|
|
42056
42961
|
returns: "{ ok, removed }",
|
|
42057
|
-
notes:
|
|
42962
|
+
notes: `${routeOf(moneyOperations.removeRule)}.`
|
|
42058
42963
|
},
|
|
42059
42964
|
{
|
|
42060
42965
|
path: ["money", "rules-apply"],
|
|
42061
42966
|
summary: "Run the rules and the transfer matching again over what's waiting.",
|
|
42062
42967
|
args: [],
|
|
42063
42968
|
flags: [{ name: "account", type: "string", description: "Only this account (ULID)." }],
|
|
42064
|
-
scopes: [
|
|
42969
|
+
scopes: [...moneyOperations.applyRules.scopes],
|
|
42065
42970
|
returns: "{ sorted, transfers }",
|
|
42066
|
-
notes:
|
|
42971
|
+
notes: `${routeOf(moneyOperations.applyRules)}.`
|
|
42067
42972
|
},
|
|
42068
42973
|
{
|
|
42069
42974
|
path: ["money", "import"],
|
|
@@ -42086,9 +42991,9 @@ var COMMAND_SPECS = [
|
|
|
42086
42991
|
{ name: "month", type: "string", description: "The month, YYYY-MM (default this month)." },
|
|
42087
42992
|
{ name: "scope", type: "string", description: "all (default) | space | owner." }
|
|
42088
42993
|
],
|
|
42089
|
-
scopes: [
|
|
42994
|
+
scopes: [...moneyOperations.budgetMonth.scopes],
|
|
42090
42995
|
returns: "MoneyBudgetMonth",
|
|
42091
|
-
notes:
|
|
42996
|
+
notes: `${routeOf(moneyOperations.budgetMonth)}. Rows (fixed, flexible, saving) with planned, spent so far and lastMonth; a summary with incomeIn, plannedOut, spent, unsorted and notYetPlanned.`
|
|
42092
42997
|
},
|
|
42093
42998
|
{
|
|
42094
42999
|
path: ["money", "budget-set"],
|
|
@@ -42102,9 +43007,9 @@ var COMMAND_SPECS = [
|
|
|
42102
43007
|
{ name: "mine", type: "boolean", description: "Your own line (only you see it)." },
|
|
42103
43008
|
{ name: "data", type: "string", description: "SetMoneyBudgetLineInput JSON instead." }
|
|
42104
43009
|
],
|
|
42105
|
-
scopes: [
|
|
43010
|
+
scopes: [...moneyOperations.setBudgetLine.scopes],
|
|
42106
43011
|
returns: "MoneyBudgetLine",
|
|
42107
|
-
notes:
|
|
43012
|
+
notes: `${routeOf(moneyOperations.setBudgetLine)}. Only fixed, flexible and saving categories are planned. \`do money budget-set --category <id> --planned 400\`.`
|
|
42108
43013
|
},
|
|
42109
43014
|
{
|
|
42110
43015
|
path: ["money", "budget-remove"],
|
|
@@ -42113,9 +43018,9 @@ var COMMAND_SPECS = [
|
|
|
42113
43018
|
flags: [
|
|
42114
43019
|
{ name: "allow-destructive", type: "boolean", description: "Required to actually remove." }
|
|
42115
43020
|
],
|
|
42116
|
-
scopes: [
|
|
43021
|
+
scopes: [...moneyOperations.removeBudgetLine.scopes],
|
|
42117
43022
|
returns: "{ ok, removed }",
|
|
42118
|
-
notes:
|
|
43023
|
+
notes: `${routeOf(moneyOperations.removeBudgetLine)}.`
|
|
42119
43024
|
},
|
|
42120
43025
|
{
|
|
42121
43026
|
path: ["money", "budget-draft"],
|
|
@@ -42125,9 +43030,9 @@ var COMMAND_SPECS = [
|
|
|
42125
43030
|
{ name: "month", type: "string", description: "The month to plan, YYYY-MM." },
|
|
42126
43031
|
{ name: "months", type: "string", description: "How many months back to read (default 3)." }
|
|
42127
43032
|
],
|
|
42128
|
-
scopes: [
|
|
43033
|
+
scopes: [...moneyOperations.draftBudget.scopes],
|
|
42129
43034
|
returns: "{ lines, kept, months }",
|
|
42130
|
-
notes:
|
|
43035
|
+
notes: `${routeOf(moneyOperations.draftBudget)}. Undo by taking the lines out: \`do money budget-remove <id>\`.`
|
|
42131
43036
|
},
|
|
42132
43037
|
{
|
|
42133
43038
|
path: ["money", "budget-copy"],
|
|
@@ -42137,9 +43042,9 @@ var COMMAND_SPECS = [
|
|
|
42137
43042
|
{ name: "from", type: "string", description: "The month to copy, YYYY-MM." },
|
|
42138
43043
|
{ name: "to", type: "string", description: "The month to fill, YYYY-MM." }
|
|
42139
43044
|
],
|
|
42140
|
-
scopes: [
|
|
43045
|
+
scopes: [...moneyOperations.copyBudget.scopes],
|
|
42141
43046
|
returns: "{ copied, kept }",
|
|
42142
|
-
notes:
|
|
43047
|
+
notes: `${routeOf(moneyOperations.copyBudget)}.`
|
|
42143
43048
|
},
|
|
42144
43049
|
{
|
|
42145
43050
|
path: ["money", "year"],
|
|
@@ -42149,9 +43054,9 @@ var COMMAND_SPECS = [
|
|
|
42149
43054
|
{ name: "year", type: "string", description: "The calendar year (default this one)." },
|
|
42150
43055
|
{ name: "scope", type: "string", description: "all (default) | space | owner." }
|
|
42151
43056
|
],
|
|
42152
|
-
scopes: [
|
|
43057
|
+
scopes: [...moneyOperations.year.scopes],
|
|
42153
43058
|
returns: "MoneyYear",
|
|
42154
|
-
notes:
|
|
43059
|
+
notes: `${routeOf(moneyOperations.year)}. totals (income, spent, saved) and lastYear (the same months a year earlier, null with nothing booked then); months Jan\u2013Dec; spending and income by category, biggest first, each with lastYear; recurring streams with thisYear, lastYear and change (new \xB7 stopped \xB7 up \xB7 down \xB7 same); goals with what went toward them this year. A year under way counts to this month (through).`
|
|
42155
43060
|
},
|
|
42156
43061
|
{
|
|
42157
43062
|
path: ["money", "net-worth"],
|
|
@@ -42165,9 +43070,9 @@ var COMMAND_SPECS = [
|
|
|
42165
43070
|
description: "How many months the line covers (2\u201360, default 12)."
|
|
42166
43071
|
}
|
|
42167
43072
|
],
|
|
42168
|
-
scopes: [
|
|
43073
|
+
scopes: [...moneyOperations.netWorthRead.scopes],
|
|
42169
43074
|
returns: "MoneyNetWorth",
|
|
42170
|
-
notes:
|
|
43075
|
+
notes: `${routeOf(moneyOperations.netWorthRead)}. total, have and owe this month; points per month (oldest first, total null before any value); accounts biggest first with value, source (balance \xB7 ledger \xB7 manual) and the month it's from. A loan or a card always counts as owed.`
|
|
42171
43076
|
},
|
|
42172
43077
|
{
|
|
42173
43078
|
path: ["money", "net-worth-set"],
|
|
@@ -42178,45 +43083,45 @@ var COMMAND_SPECS = [
|
|
|
42178
43083
|
{ name: "month", type: "string", description: "The month, YYYY-MM (default this month)." },
|
|
42179
43084
|
{ name: "data", type: "string", description: "SetMoneyNetWorthValueInput JSON instead." }
|
|
42180
43085
|
],
|
|
42181
|
-
scopes: [
|
|
43086
|
+
scopes: [...moneyOperations.setNetWorthValue.scopes],
|
|
42182
43087
|
returns: "MoneySnapshot",
|
|
42183
|
-
notes:
|
|
43088
|
+
notes: `${routeOf(moneyOperations.setNetWorthValue)}. A month ahead is refused. This month's value also becomes the account's balance unless a bank link keeps it. \`do money net-worth-set <accountId> --value 310000\`.`
|
|
42184
43089
|
},
|
|
42185
43090
|
{
|
|
42186
43091
|
path: ["money", "goals"],
|
|
42187
43092
|
summary: "List money goals: what's saved toward each, soonest first.",
|
|
42188
43093
|
args: [],
|
|
42189
43094
|
flags: [],
|
|
42190
|
-
scopes: [
|
|
43095
|
+
scopes: [...moneyOperations.listGoals.scopes],
|
|
42191
43096
|
returns: "MoneyGoalView[]",
|
|
42192
|
-
notes:
|
|
43097
|
+
notes: `${routeOf(moneyOperations.listGoals)}.`
|
|
42193
43098
|
},
|
|
42194
43099
|
{
|
|
42195
43100
|
path: ["money", "goal"],
|
|
42196
43101
|
summary: "Show one money goal with its lines and what went into it.",
|
|
42197
43102
|
args: [{ name: "id", required: true, description: "Goal ULID." }],
|
|
42198
43103
|
flags: [],
|
|
42199
|
-
scopes: [
|
|
43104
|
+
scopes: [...moneyOperations.getGoal.scopes],
|
|
42200
43105
|
returns: "MoneyGoalDetail",
|
|
42201
|
-
notes:
|
|
43106
|
+
notes: `${routeOf(moneyOperations.getGoal)}.`
|
|
42202
43107
|
},
|
|
42203
43108
|
{
|
|
42204
43109
|
path: ["money", "goal-add"],
|
|
42205
43110
|
summary: "Set a money goal (Only me unless --data says visibility: space).",
|
|
42206
43111
|
args: [],
|
|
42207
43112
|
flags: [{ name: "data", type: "string", description: "CreateMoneyGoalInput JSON." }],
|
|
42208
|
-
scopes: [
|
|
43113
|
+
scopes: [...moneyOperations.createGoal.scopes],
|
|
42209
43114
|
returns: "MoneyGoalView",
|
|
42210
|
-
notes:
|
|
43115
|
+
notes: `${routeOf(moneyOperations.createGoal)}. \`do money goal-add --data '{"title":"Garden shed","targetAmount":"3000","targetOn":"2027-04-01","monthlyPlan":"200","visibility":"space"}'\`.`
|
|
42211
43116
|
},
|
|
42212
43117
|
{
|
|
42213
43118
|
path: ["money", "goal-update"],
|
|
42214
43119
|
summary: "Edit a money goal, or mark it reached or paused.",
|
|
42215
43120
|
args: [{ name: "id", required: true, description: "Goal ULID." }],
|
|
42216
43121
|
flags: [{ name: "data", type: "string", description: "UpdateMoneyGoalInput JSON." }],
|
|
42217
|
-
scopes: [
|
|
43122
|
+
scopes: [...moneyOperations.updateGoal.scopes],
|
|
42218
43123
|
returns: "MoneyGoalView",
|
|
42219
|
-
notes:
|
|
43124
|
+
notes: `${routeOf(moneyOperations.updateGoal)}.`
|
|
42220
43125
|
},
|
|
42221
43126
|
{
|
|
42222
43127
|
path: ["money", "goal-remove"],
|
|
@@ -42225,27 +43130,27 @@ var COMMAND_SPECS = [
|
|
|
42225
43130
|
flags: [
|
|
42226
43131
|
{ name: "allow-destructive", type: "boolean", description: "Required to actually remove." }
|
|
42227
43132
|
],
|
|
42228
|
-
scopes: [
|
|
43133
|
+
scopes: [...moneyOperations.removeGoal.scopes],
|
|
42229
43134
|
returns: "{ ok, removed }",
|
|
42230
|
-
notes:
|
|
43135
|
+
notes: `${routeOf(moneyOperations.removeGoal)}. The money and its transactions stay.`
|
|
42231
43136
|
},
|
|
42232
43137
|
{
|
|
42233
43138
|
path: ["money", "goal-line-add"],
|
|
42234
43139
|
summary: "Add a line of what a goal pays for (planned, paid).",
|
|
42235
43140
|
args: [{ name: "id", required: true, description: "Goal ULID." }],
|
|
42236
43141
|
flags: [{ name: "data", type: "string", description: "CreateMoneyGoalLineInput JSON." }],
|
|
42237
|
-
scopes: [
|
|
43142
|
+
scopes: [...moneyOperations.addGoalLine.scopes],
|
|
42238
43143
|
returns: "MoneyGoalLine",
|
|
42239
|
-
notes:
|
|
43144
|
+
notes: `${routeOf(moneyOperations.addGoalLine)}. \`do money goal-line-add <goal-id> --data '{"title":"Venue","planned":"5200","paid":"1500"}'\`.`
|
|
42240
43145
|
},
|
|
42241
43146
|
{
|
|
42242
43147
|
path: ["money", "goal-line-update"],
|
|
42243
43148
|
summary: "Edit a goal's line (what's planned or paid, its paper in Admin via documentId).",
|
|
42244
43149
|
args: [{ name: "id", required: true, description: "Line ULID." }],
|
|
42245
43150
|
flags: [{ name: "data", type: "string", description: "UpdateMoneyGoalLineInput JSON." }],
|
|
42246
|
-
scopes: [
|
|
43151
|
+
scopes: [...moneyOperations.updateGoalLine.scopes],
|
|
42247
43152
|
returns: "MoneyGoalLine",
|
|
42248
|
-
notes:
|
|
43153
|
+
notes: `${routeOf(moneyOperations.updateGoalLine)}.`
|
|
42249
43154
|
},
|
|
42250
43155
|
{
|
|
42251
43156
|
path: ["money", "goal-line-remove"],
|
|
@@ -42254,9 +43159,9 @@ var COMMAND_SPECS = [
|
|
|
42254
43159
|
flags: [
|
|
42255
43160
|
{ name: "allow-destructive", type: "boolean", description: "Required to actually remove." }
|
|
42256
43161
|
],
|
|
42257
|
-
scopes: [
|
|
43162
|
+
scopes: [...moneyOperations.removeGoalLine.scopes],
|
|
42258
43163
|
returns: "{ ok, removed }",
|
|
42259
|
-
notes:
|
|
43164
|
+
notes: `${routeOf(moneyOperations.removeGoalLine)}.`
|
|
42260
43165
|
},
|
|
42261
43166
|
{
|
|
42262
43167
|
path: ["money", "goal-count"],
|
|
@@ -42266,9 +43171,9 @@ var COMMAND_SPECS = [
|
|
|
42266
43171
|
{ name: "transaction", required: true, description: "Transaction ULID." }
|
|
42267
43172
|
],
|
|
42268
43173
|
flags: [],
|
|
42269
|
-
scopes: [
|
|
43174
|
+
scopes: [...moneyOperations.addGoalContribution.scopes],
|
|
42270
43175
|
returns: "MoneyGoalView",
|
|
42271
|
-
notes:
|
|
43176
|
+
notes: `${routeOf(moneyOperations.addGoalContribution)}.`
|
|
42272
43177
|
},
|
|
42273
43178
|
{
|
|
42274
43179
|
path: ["money", "goal-uncount"],
|
|
@@ -42278,36 +43183,36 @@ var COMMAND_SPECS = [
|
|
|
42278
43183
|
{ name: "transaction", required: true, description: "Transaction ULID." }
|
|
42279
43184
|
],
|
|
42280
43185
|
flags: [],
|
|
42281
|
-
scopes: [
|
|
43186
|
+
scopes: [...moneyOperations.removeGoalContribution.scopes],
|
|
42282
43187
|
returns: "MoneyGoalView",
|
|
42283
|
-
notes:
|
|
43188
|
+
notes: `${routeOf(moneyOperations.removeGoalContribution)}.`
|
|
42284
43189
|
},
|
|
42285
43190
|
{
|
|
42286
43191
|
path: ["money", "recurring"],
|
|
42287
43192
|
summary: "Recurring payments: the streams, what the ledger shows untracked, price changes, the year's fixed costs.",
|
|
42288
43193
|
args: [],
|
|
42289
43194
|
flags: [],
|
|
42290
|
-
scopes: [
|
|
43195
|
+
scopes: [...moneyOperations.recurringOverview.scopes],
|
|
42291
43196
|
returns: "MoneyRecurringOverview",
|
|
42292
|
-
notes:
|
|
43197
|
+
notes: `${routeOf(moneyOperations.recurringOverview)}. \`found\` is read over the whole ledger, across accounts (grouped by counterparty IBAN, name or the bank line's payee, split by amount); each has \`kind\`: subscription, or standing_order for money moved to an own account.`
|
|
42293
43198
|
},
|
|
42294
43199
|
{
|
|
42295
43200
|
path: ["money", "recurring-add"],
|
|
42296
43201
|
summary: "Track a recurring payment (Only me unless --data says visibility: space).",
|
|
42297
43202
|
args: [],
|
|
42298
43203
|
flags: [{ name: "data", type: "string", description: "CreateMoneyRecurringInput JSON." }],
|
|
42299
|
-
scopes: [
|
|
43204
|
+
scopes: [...moneyOperations.createRecurring.scopes],
|
|
42300
43205
|
returns: "MoneyRecurringView",
|
|
42301
|
-
notes:
|
|
43206
|
+
notes: `${routeOf(moneyOperations.createRecurring)}. \`do money recurring-add --data '{"title":"Energy","cadence":"monthly","expectedAmount":"148","matchText":"Bright Energy","visibility":"space"}'\`. \`"status":"ignored"\` calls a found pattern a one-off.`
|
|
42302
43207
|
},
|
|
42303
43208
|
{
|
|
42304
43209
|
path: ["money", "recurring-update"],
|
|
42305
43210
|
summary: "Edit a recurring payment (amount, next day, paper, pick, status).",
|
|
42306
43211
|
args: [{ name: "id", required: true, description: "Stream ULID." }],
|
|
42307
43212
|
flags: [{ name: "data", type: "string", description: "UpdateMoneyRecurringInput JSON." }],
|
|
42308
|
-
scopes: [
|
|
43213
|
+
scopes: [...moneyOperations.updateRecurring.scopes],
|
|
42309
43214
|
returns: "MoneyRecurringView",
|
|
42310
|
-
notes:
|
|
43215
|
+
notes: `${routeOf(moneyOperations.updateRecurring)}.`
|
|
42311
43216
|
},
|
|
42312
43217
|
{
|
|
42313
43218
|
path: ["money", "recurring-remove"],
|
|
@@ -42316,18 +43221,18 @@ var COMMAND_SPECS = [
|
|
|
42316
43221
|
flags: [
|
|
42317
43222
|
{ name: "allow-destructive", type: "boolean", description: "Required to actually remove." }
|
|
42318
43223
|
],
|
|
42319
|
-
scopes: [
|
|
43224
|
+
scopes: [...moneyOperations.removeRecurring.scopes],
|
|
42320
43225
|
returns: "{ ok, removed }",
|
|
42321
|
-
notes:
|
|
43226
|
+
notes: `${routeOf(moneyOperations.removeRecurring)}. Its payments stay.`
|
|
42322
43227
|
},
|
|
42323
43228
|
{
|
|
42324
43229
|
path: ["money", "stream"],
|
|
42325
43230
|
summary: "Show one recurring payment, with its paper's soonest key date.",
|
|
42326
43231
|
args: [{ name: "id", required: true, description: "Stream ULID." }],
|
|
42327
43232
|
flags: [],
|
|
42328
|
-
scopes: [
|
|
43233
|
+
scopes: [...moneyOperations.getRecurring.scopes],
|
|
42329
43234
|
returns: "MoneyRecurringView",
|
|
42330
|
-
notes:
|
|
43235
|
+
notes: `${routeOf(moneyOperations.getRecurring)}.`
|
|
42331
43236
|
},
|
|
42332
43237
|
{
|
|
42333
43238
|
path: ["animals", "overview"],
|
|
@@ -45219,14 +46124,17 @@ var HANDLERS = {
|
|
|
45219
46124
|
return { data: { ok: true, unlinked: node }, render: renderRecord };
|
|
45220
46125
|
},
|
|
45221
46126
|
"files list": async ({ flags, requireClient }) => ({
|
|
45222
|
-
data: await requireClient().get(
|
|
46127
|
+
data: await requireClient().get(pathOf(fileOperations.list), {
|
|
45223
46128
|
query: { nodeId: requireFlag(flags, "node", "files list needs --node <node id>") }
|
|
45224
46129
|
}),
|
|
45225
46130
|
render: renderList
|
|
45226
46131
|
}),
|
|
45227
46132
|
"files get": async ({ args, requireClient }) => {
|
|
45228
46133
|
const id = requireArg(args, 0, "file id");
|
|
45229
|
-
return {
|
|
46134
|
+
return {
|
|
46135
|
+
data: await requireClient().get(pathOf(fileOperations.get, { id })),
|
|
46136
|
+
render: renderRecord
|
|
46137
|
+
};
|
|
45230
46138
|
},
|
|
45231
46139
|
"files upload": async ({ args, flags, requireClient }) => {
|
|
45232
46140
|
const path = requireArg(args, 0, "path");
|
|
@@ -45274,14 +46182,14 @@ var HANDLERS = {
|
|
|
45274
46182
|
"files view-url": async ({ args, requireClient }) => {
|
|
45275
46183
|
const id = requireArg(args, 0, "file id");
|
|
45276
46184
|
const client = requireClient();
|
|
45277
|
-
const link = await client.post(
|
|
46185
|
+
const link = await client.post(pathOf(fileOperations.viewUrl, { id }), {});
|
|
45278
46186
|
const url = new URL(link.path, client.url("/")).toString();
|
|
45279
46187
|
return { data: { id, url, expiresAt: link.expiresAt }, render: () => url };
|
|
45280
46188
|
},
|
|
45281
46189
|
"files delete": async ({ args, flags, requireClient }) => {
|
|
45282
46190
|
const id = requireArg(args, 0, "file id");
|
|
45283
46191
|
assertDestructiveAllowed(flags, `delete file ${id}`);
|
|
45284
|
-
await requireClient().delete(
|
|
46192
|
+
await requireClient().delete(pathOf(fileOperations.remove, { id }));
|
|
45285
46193
|
return { data: { ok: true, deleted: id }, render: renderRecord };
|
|
45286
46194
|
},
|
|
45287
46195
|
"foods search": async ({ args, flags, requireClient }) => {
|
|
@@ -46662,33 +47570,39 @@ var HANDLERS = {
|
|
|
46662
47570
|
};
|
|
46663
47571
|
},
|
|
46664
47572
|
"money accounts": async ({ requireClient }) => ({
|
|
46665
|
-
data: await requireClient().get(
|
|
47573
|
+
data: await requireClient().get(pathOf(moneyOperations.listAccounts)),
|
|
46666
47574
|
render: renderList
|
|
46667
47575
|
}),
|
|
46668
47576
|
"money account": async ({ args, requireClient }) => {
|
|
46669
47577
|
const id = requireArg(args, 0, "account id");
|
|
46670
|
-
return {
|
|
47578
|
+
return {
|
|
47579
|
+
data: await requireClient().get(pathOf(moneyOperations.getAccount, { id })),
|
|
47580
|
+
render: renderRecord
|
|
47581
|
+
};
|
|
46671
47582
|
},
|
|
46672
47583
|
"money account-add": async ({ flags, requireClient }) => {
|
|
46673
47584
|
const body = parseInput(createMoneyAccountInputSchema, { id: ulid3(), ...readDataFlag(flags) });
|
|
46674
|
-
return {
|
|
47585
|
+
return {
|
|
47586
|
+
data: await requireClient().post(pathOf(moneyOperations.createAccount), body),
|
|
47587
|
+
render: renderRecord
|
|
47588
|
+
};
|
|
46675
47589
|
},
|
|
46676
47590
|
"money account-update": async ({ args, flags, requireClient }) => {
|
|
46677
47591
|
const id = requireArg(args, 0, "account id");
|
|
46678
47592
|
const body = parseInput(updateMoneyAccountInputSchema, readDataFlag(flags));
|
|
46679
47593
|
return {
|
|
46680
|
-
data: await requireClient().patch(
|
|
47594
|
+
data: await requireClient().patch(pathOf(moneyOperations.updateAccount, { id }), body),
|
|
46681
47595
|
render: renderRecord
|
|
46682
47596
|
};
|
|
46683
47597
|
},
|
|
46684
47598
|
"money account-close": async ({ args, flags, requireClient }) => {
|
|
46685
47599
|
const id = requireArg(args, 0, "account id");
|
|
46686
47600
|
assertDestructiveAllowed(flags, `close account ${id}`);
|
|
46687
|
-
await requireClient().delete(
|
|
47601
|
+
await requireClient().delete(pathOf(moneyOperations.removeAccount, { id }));
|
|
46688
47602
|
return { data: { ok: true, closed: id }, render: renderRecord };
|
|
46689
47603
|
},
|
|
46690
47604
|
"money connections": async ({ requireClient }) => ({
|
|
46691
|
-
data: await requireClient().get(
|
|
47605
|
+
data: await requireClient().get(pathOf(moneyOperations.listConnections)),
|
|
46692
47606
|
render: renderList
|
|
46693
47607
|
}),
|
|
46694
47608
|
"money sync": async ({ flags, requireClient }) => {
|
|
@@ -46696,27 +47610,30 @@ var HANDLERS = {
|
|
|
46696
47610
|
...typeof flags.account === "string" ? { accountId: flags.account } : {}
|
|
46697
47611
|
});
|
|
46698
47612
|
return {
|
|
46699
|
-
data: await requireClient().post(
|
|
47613
|
+
data: await requireClient().post(pathOf(moneyOperations.syncConnections), body),
|
|
46700
47614
|
render: renderRecord
|
|
46701
47615
|
};
|
|
46702
47616
|
},
|
|
46703
47617
|
"money connection-syncs": async ({ args, requireClient }) => {
|
|
46704
47618
|
const id = requireArg(args, 0, "id");
|
|
46705
47619
|
return {
|
|
46706
|
-
data: await requireClient().get(
|
|
47620
|
+
data: await requireClient().get(pathOf(moneyOperations.listConnectionSyncs, { id })),
|
|
46707
47621
|
render: renderList
|
|
46708
47622
|
};
|
|
46709
47623
|
},
|
|
46710
47624
|
"money categories": async ({ requireClient }) => ({
|
|
46711
|
-
data: await requireClient().get(
|
|
47625
|
+
data: await requireClient().get(pathOf(moneyOperations.listCategories)),
|
|
46712
47626
|
render: renderList
|
|
46713
47627
|
}),
|
|
46714
47628
|
"money category-add": async ({ flags, requireClient }) => {
|
|
46715
47629
|
const body = parseInput(createMoneyCategoryInputSchema, { id: ulid3(), ...readDataFlag(flags) });
|
|
46716
|
-
return {
|
|
47630
|
+
return {
|
|
47631
|
+
data: await requireClient().post(pathOf(moneyOperations.createCategory), body),
|
|
47632
|
+
render: renderRecord
|
|
47633
|
+
};
|
|
46717
47634
|
},
|
|
46718
47635
|
"money transactions": async ({ flags, requireClient }) => ({
|
|
46719
|
-
data: await requireClient().get(
|
|
47636
|
+
data: await requireClient().get(pathOf(moneyOperations.listTransactions), {
|
|
46720
47637
|
query: {
|
|
46721
47638
|
accountId: flagString(flags, "account"),
|
|
46722
47639
|
status: flagString(flags, "status"),
|
|
@@ -46735,17 +47652,23 @@ var HANDLERS = {
|
|
|
46735
47652
|
}),
|
|
46736
47653
|
"money transaction": async ({ args, requireClient }) => {
|
|
46737
47654
|
const id = requireArg(args, 0, "transaction id");
|
|
46738
|
-
return {
|
|
47655
|
+
return {
|
|
47656
|
+
data: await requireClient().get(pathOf(moneyOperations.getTransaction, { id })),
|
|
47657
|
+
render: renderRecord
|
|
47658
|
+
};
|
|
46739
47659
|
},
|
|
46740
47660
|
"money book": async ({ flags, requireClient }) => {
|
|
46741
47661
|
const body = parseInput(createMoneyTransactionInputSchema, {
|
|
46742
47662
|
id: ulid3(),
|
|
46743
47663
|
...readDataFlag(flags)
|
|
46744
47664
|
});
|
|
46745
|
-
return {
|
|
47665
|
+
return {
|
|
47666
|
+
data: await requireClient().post(pathOf(moneyOperations.createTransaction), body),
|
|
47667
|
+
render: renderRecord
|
|
47668
|
+
};
|
|
46746
47669
|
},
|
|
46747
47670
|
"money review": async ({ flags, requireClient }) => ({
|
|
46748
|
-
data: await requireClient().get(
|
|
47671
|
+
data: await requireClient().get(pathOf(moneyOperations.review), {
|
|
46749
47672
|
query: { accountId: flagString(flags, "account"), limit: flagString(flags, "limit") }
|
|
46750
47673
|
}),
|
|
46751
47674
|
render: renderRecord
|
|
@@ -46767,16 +47690,22 @@ var HANDLERS = {
|
|
|
46767
47690
|
}
|
|
46768
47691
|
]
|
|
46769
47692
|
});
|
|
46770
|
-
return {
|
|
47693
|
+
return {
|
|
47694
|
+
data: await requireClient().post(pathOf(moneyOperations.sort), body),
|
|
47695
|
+
render: renderRecord
|
|
47696
|
+
};
|
|
46771
47697
|
},
|
|
46772
47698
|
"money sort-undo": async ({ flags, requireClient }) => {
|
|
46773
47699
|
const body = parseInput(moneySortUndoInputSchema, readDataFlag(flags));
|
|
46774
|
-
return {
|
|
47700
|
+
return {
|
|
47701
|
+
data: await requireClient().post(pathOf(moneyOperations.undoSort), body),
|
|
47702
|
+
render: renderRecord
|
|
47703
|
+
};
|
|
46775
47704
|
},
|
|
46776
47705
|
"money splits": async ({ args, requireClient }) => {
|
|
46777
47706
|
const id = requireArg(args, 0, "transaction id");
|
|
46778
47707
|
return {
|
|
46779
|
-
data: await requireClient().get(
|
|
47708
|
+
data: await requireClient().get(pathOf(moneyOperations.listSplits, { id })),
|
|
46780
47709
|
render: renderList
|
|
46781
47710
|
};
|
|
46782
47711
|
},
|
|
@@ -46784,7 +47713,7 @@ var HANDLERS = {
|
|
|
46784
47713
|
const id = requireArg(args, 0, "transaction id");
|
|
46785
47714
|
const body = parseInput(setMoneySplitsInputSchema, readDataFlag(flags));
|
|
46786
47715
|
return {
|
|
46787
|
-
data: await requireClient().put(
|
|
47716
|
+
data: await requireClient().put(pathOf(moneyOperations.setSplits, { id }), body),
|
|
46788
47717
|
render: renderRecord
|
|
46789
47718
|
};
|
|
46790
47719
|
},
|
|
@@ -46798,12 +47727,12 @@ var HANDLERS = {
|
|
|
46798
47727
|
note: flagString(flags, "note")
|
|
46799
47728
|
});
|
|
46800
47729
|
return {
|
|
46801
|
-
data: await requireClient().post(
|
|
47730
|
+
data: await requireClient().post(pathOf(moneyOperations.share, { id }), body),
|
|
46802
47731
|
render: renderRecord
|
|
46803
47732
|
};
|
|
46804
47733
|
},
|
|
46805
47734
|
"money settle-up": async ({ requireClient }) => ({
|
|
46806
|
-
data: await requireClient().get(
|
|
47735
|
+
data: await requireClient().get(pathOf(moneyOperations.settleUp)),
|
|
46807
47736
|
render: renderRecord
|
|
46808
47737
|
}),
|
|
46809
47738
|
"money settle": async ({ flags, requireClient }) => {
|
|
@@ -46820,18 +47749,21 @@ var HANDLERS = {
|
|
|
46820
47749
|
transactionId: flagString(flags, "transaction"),
|
|
46821
47750
|
note: flagString(flags, "note")
|
|
46822
47751
|
});
|
|
46823
|
-
return {
|
|
47752
|
+
return {
|
|
47753
|
+
data: await requireClient().post(pathOf(moneyOperations.settle), body),
|
|
47754
|
+
render: renderRecord
|
|
47755
|
+
};
|
|
46824
47756
|
},
|
|
46825
47757
|
"money settlement-remove": async ({ args, flags, requireClient }) => {
|
|
46826
47758
|
const id = requireArg(args, 0, "settlement id");
|
|
46827
47759
|
assertDestructiveAllowed(flags, `remove settlement ${id}`);
|
|
46828
|
-
await requireClient().delete(
|
|
47760
|
+
await requireClient().delete(pathOf(moneyOperations.removeSettlement, { id }));
|
|
46829
47761
|
return { data: { ok: true, removed: id }, render: renderRecord };
|
|
46830
47762
|
},
|
|
46831
47763
|
"money tax-evidence": async ({ flags, requireClient }) => {
|
|
46832
47764
|
const year = requireFlag(flags, "year", "money tax-evidence needs --year <YYYY>");
|
|
46833
47765
|
return {
|
|
46834
|
-
data: await requireClient().get(
|
|
47766
|
+
data: await requireClient().get(pathOf(moneyOperations.taxEvidence), {
|
|
46835
47767
|
query: { year, tag: flagString(flags, "tag") }
|
|
46836
47768
|
}),
|
|
46837
47769
|
render: renderRecord
|
|
@@ -46841,48 +47773,57 @@ var HANDLERS = {
|
|
|
46841
47773
|
const id = requireArg(args, 0, "transaction id");
|
|
46842
47774
|
const body = parseInput(moneyOdooPushInputSchema, { note: flagString(flags, "note") });
|
|
46843
47775
|
return {
|
|
46844
|
-
data: await requireClient().post(
|
|
47776
|
+
data: await requireClient().post(pathOf(moneyOperations.pushOdooDraft, { id }), body),
|
|
46845
47777
|
render: renderRecord
|
|
46846
47778
|
};
|
|
46847
47779
|
},
|
|
46848
47780
|
"money odoo-undo": async ({ args, requireClient }) => {
|
|
46849
47781
|
const id = requireArg(args, 0, "transaction id");
|
|
46850
47782
|
return {
|
|
46851
|
-
data: await requireClient().delete(
|
|
47783
|
+
data: await requireClient().delete(pathOf(moneyOperations.undoOdooDraft, { id })),
|
|
46852
47784
|
render: renderRecord
|
|
46853
47785
|
};
|
|
46854
47786
|
},
|
|
46855
47787
|
"money rules": async ({ requireClient }) => ({
|
|
46856
|
-
data: await requireClient().get(
|
|
47788
|
+
data: await requireClient().get(pathOf(moneyOperations.listRules)),
|
|
46857
47789
|
render: renderList
|
|
46858
47790
|
}),
|
|
46859
47791
|
"money rule-suggestions": async ({ requireClient }) => ({
|
|
46860
|
-
data: await requireClient().get(
|
|
47792
|
+
data: await requireClient().get(pathOf(moneyOperations.ruleSuggestions)),
|
|
46861
47793
|
render: renderList
|
|
46862
47794
|
}),
|
|
46863
47795
|
"money rule": async ({ args, requireClient }) => {
|
|
46864
47796
|
const id = requireArg(args, 0, "rule id");
|
|
46865
|
-
return {
|
|
47797
|
+
return {
|
|
47798
|
+
data: await requireClient().get(pathOf(moneyOperations.getRule, { id })),
|
|
47799
|
+
render: renderRecord
|
|
47800
|
+
};
|
|
46866
47801
|
},
|
|
46867
47802
|
"money rule-add": async ({ flags, requireClient }) => {
|
|
46868
47803
|
const body = parseInput(createMoneyRuleInputSchema, { id: ulid3(), ...readDataFlag(flags) });
|
|
46869
|
-
return {
|
|
47804
|
+
return {
|
|
47805
|
+
data: await requireClient().post(pathOf(moneyOperations.createRule), body),
|
|
47806
|
+
render: renderRecord
|
|
47807
|
+
};
|
|
46870
47808
|
},
|
|
46871
47809
|
"money rule-update": async ({ args, flags, requireClient }) => {
|
|
46872
47810
|
const id = requireArg(args, 0, "rule id");
|
|
46873
47811
|
const body = parseInput(updateMoneyRuleInputSchema, readDataFlag(flags));
|
|
46874
|
-
return {
|
|
47812
|
+
return {
|
|
47813
|
+
data: await requireClient().patch(pathOf(moneyOperations.updateRule, { id }), body),
|
|
47814
|
+
render: renderRecord
|
|
47815
|
+
};
|
|
46875
47816
|
},
|
|
46876
47817
|
"money rule-remove": async ({ args, flags, requireClient }) => {
|
|
46877
47818
|
const id = requireArg(args, 0, "rule id");
|
|
46878
47819
|
assertDestructiveAllowed(flags, `remove rule ${id}`);
|
|
46879
|
-
await requireClient().delete(
|
|
47820
|
+
await requireClient().delete(pathOf(moneyOperations.removeRule, { id }));
|
|
46880
47821
|
return { data: { ok: true, removed: id }, render: renderRecord };
|
|
46881
47822
|
},
|
|
46882
47823
|
"money rules-apply": async ({ flags, requireClient }) => {
|
|
46883
47824
|
const account = flagString(flags, "account");
|
|
46884
47825
|
return {
|
|
46885
|
-
data: await requireClient().post(
|
|
47826
|
+
data: await requireClient().post(pathOf(moneyOperations.applyRules), account ? { accountId: account } : {}),
|
|
46886
47827
|
render: renderRecord
|
|
46887
47828
|
};
|
|
46888
47829
|
},
|
|
@@ -46906,13 +47847,13 @@ var HANDLERS = {
|
|
|
46906
47847
|
return { data: await requireClient().upload(route, form), render: renderRecord };
|
|
46907
47848
|
},
|
|
46908
47849
|
"money year": async ({ flags, requireClient }) => ({
|
|
46909
|
-
data: await requireClient().get(
|
|
47850
|
+
data: await requireClient().get(pathOf(moneyOperations.year), {
|
|
46910
47851
|
query: { year: flagString(flags, "year"), scope: flagString(flags, "scope") }
|
|
46911
47852
|
}),
|
|
46912
47853
|
render: renderRecord
|
|
46913
47854
|
}),
|
|
46914
47855
|
"money budget": async ({ flags, io, requireClient }) => ({
|
|
46915
|
-
data: await requireClient().get(
|
|
47856
|
+
data: await requireClient().get(pathOf(moneyOperations.budgetMonth), {
|
|
46916
47857
|
query: {
|
|
46917
47858
|
month: flagString(flags, "month") ?? localMonth(io.now()),
|
|
46918
47859
|
scope: flagString(flags, "scope")
|
|
@@ -46928,12 +47869,15 @@ var HANDLERS = {
|
|
|
46928
47869
|
note: flagString(flags, "note"),
|
|
46929
47870
|
mine: flagBool(flags, "mine") || undefined
|
|
46930
47871
|
});
|
|
46931
|
-
return {
|
|
47872
|
+
return {
|
|
47873
|
+
data: await requireClient().put(pathOf(moneyOperations.setBudgetLine), body),
|
|
47874
|
+
render: renderRecord
|
|
47875
|
+
};
|
|
46932
47876
|
},
|
|
46933
47877
|
"money budget-remove": async ({ args, flags, requireClient }) => {
|
|
46934
47878
|
const id = requireArg(args, 0, "plan line id");
|
|
46935
47879
|
assertDestructiveAllowed(flags, `remove plan line ${id}`);
|
|
46936
|
-
await requireClient().delete(
|
|
47880
|
+
await requireClient().delete(pathOf(moneyOperations.removeBudgetLine, { id }));
|
|
46937
47881
|
return { data: { ok: true, removed: id }, render: renderRecord };
|
|
46938
47882
|
},
|
|
46939
47883
|
"money budget-draft": async ({ flags, requireClient }) => {
|
|
@@ -46942,17 +47886,23 @@ var HANDLERS = {
|
|
|
46942
47886
|
month: requireFlag(flags, "month", "money budget-draft needs --month <YYYY-MM>"),
|
|
46943
47887
|
...months ? { months: Number(months) } : {}
|
|
46944
47888
|
});
|
|
46945
|
-
return {
|
|
47889
|
+
return {
|
|
47890
|
+
data: await requireClient().post(pathOf(moneyOperations.draftBudget), body),
|
|
47891
|
+
render: renderRecord
|
|
47892
|
+
};
|
|
46946
47893
|
},
|
|
46947
47894
|
"money budget-copy": async ({ flags, requireClient }) => {
|
|
46948
47895
|
const body = parseInput(copyMoneyBudgetInputSchema, {
|
|
46949
47896
|
from: requireFlag(flags, "from", "money budget-copy needs --from <YYYY-MM>"),
|
|
46950
47897
|
to: requireFlag(flags, "to", "money budget-copy needs --to <YYYY-MM>")
|
|
46951
47898
|
});
|
|
46952
|
-
return {
|
|
47899
|
+
return {
|
|
47900
|
+
data: await requireClient().post(pathOf(moneyOperations.copyBudget), body),
|
|
47901
|
+
render: renderRecord
|
|
47902
|
+
};
|
|
46953
47903
|
},
|
|
46954
47904
|
"money net-worth": async ({ flags, requireClient }) => ({
|
|
46955
|
-
data: await requireClient().get(
|
|
47905
|
+
data: await requireClient().get(pathOf(moneyOperations.netWorthRead), {
|
|
46956
47906
|
query: { scope: flagString(flags, "scope"), months: flagString(flags, "months") }
|
|
46957
47907
|
}),
|
|
46958
47908
|
render: renderRecord
|
|
@@ -46964,38 +47914,47 @@ var HANDLERS = {
|
|
|
46964
47914
|
month: flagString(flags, "month")
|
|
46965
47915
|
});
|
|
46966
47916
|
return {
|
|
46967
|
-
data: await requireClient().put(
|
|
47917
|
+
data: await requireClient().put(pathOf(moneyOperations.setNetWorthValue), body),
|
|
46968
47918
|
render: renderRecord
|
|
46969
47919
|
};
|
|
46970
47920
|
},
|
|
46971
47921
|
"money goals": async ({ requireClient }) => ({
|
|
46972
|
-
data: await requireClient().get(
|
|
47922
|
+
data: await requireClient().get(pathOf(moneyOperations.listGoals)),
|
|
46973
47923
|
render: renderList
|
|
46974
47924
|
}),
|
|
46975
47925
|
"money goal": async ({ args, requireClient }) => {
|
|
46976
47926
|
const id = requireArg(args, 0, "goal id");
|
|
46977
|
-
return {
|
|
47927
|
+
return {
|
|
47928
|
+
data: await requireClient().get(pathOf(moneyOperations.getGoal, { id })),
|
|
47929
|
+
render: renderRecord
|
|
47930
|
+
};
|
|
46978
47931
|
},
|
|
46979
47932
|
"money goal-add": async ({ flags, requireClient }) => {
|
|
46980
47933
|
const body = parseInput(createMoneyGoalInputSchema, { id: ulid3(), ...readDataFlag(flags) });
|
|
46981
|
-
return {
|
|
47934
|
+
return {
|
|
47935
|
+
data: await requireClient().post(pathOf(moneyOperations.createGoal), body),
|
|
47936
|
+
render: renderRecord
|
|
47937
|
+
};
|
|
46982
47938
|
},
|
|
46983
47939
|
"money goal-update": async ({ args, flags, requireClient }) => {
|
|
46984
47940
|
const id = requireArg(args, 0, "goal id");
|
|
46985
47941
|
const body = parseInput(updateMoneyGoalInputSchema, readDataFlag(flags));
|
|
46986
|
-
return {
|
|
47942
|
+
return {
|
|
47943
|
+
data: await requireClient().patch(pathOf(moneyOperations.updateGoal, { id }), body),
|
|
47944
|
+
render: renderRecord
|
|
47945
|
+
};
|
|
46987
47946
|
},
|
|
46988
47947
|
"money goal-remove": async ({ args, flags, requireClient }) => {
|
|
46989
47948
|
const id = requireArg(args, 0, "goal id");
|
|
46990
47949
|
assertDestructiveAllowed(flags, `remove goal ${id}`);
|
|
46991
|
-
await requireClient().delete(
|
|
47950
|
+
await requireClient().delete(pathOf(moneyOperations.removeGoal, { id }));
|
|
46992
47951
|
return { data: { ok: true, removed: id }, render: renderRecord };
|
|
46993
47952
|
},
|
|
46994
47953
|
"money goal-line-add": async ({ args, flags, requireClient }) => {
|
|
46995
47954
|
const id = requireArg(args, 0, "goal id");
|
|
46996
47955
|
const body = parseInput(createMoneyGoalLineInputSchema, { id: ulid3(), ...readDataFlag(flags) });
|
|
46997
47956
|
return {
|
|
46998
|
-
data: await requireClient().post(
|
|
47957
|
+
data: await requireClient().post(pathOf(moneyOperations.addGoalLine, { id }), body),
|
|
46999
47958
|
render: renderRecord
|
|
47000
47959
|
};
|
|
47001
47960
|
},
|
|
@@ -47003,14 +47962,14 @@ var HANDLERS = {
|
|
|
47003
47962
|
const id = requireArg(args, 0, "line id");
|
|
47004
47963
|
const body = parseInput(updateMoneyGoalLineInputSchema, readDataFlag(flags));
|
|
47005
47964
|
return {
|
|
47006
|
-
data: await requireClient().patch(
|
|
47965
|
+
data: await requireClient().patch(pathOf(moneyOperations.updateGoalLine, { lineId: id }), body),
|
|
47007
47966
|
render: renderRecord
|
|
47008
47967
|
};
|
|
47009
47968
|
},
|
|
47010
47969
|
"money goal-line-remove": async ({ args, flags, requireClient }) => {
|
|
47011
47970
|
const id = requireArg(args, 0, "line id");
|
|
47012
47971
|
assertDestructiveAllowed(flags, `remove goal line ${id}`);
|
|
47013
|
-
await requireClient().delete(
|
|
47972
|
+
await requireClient().delete(pathOf(moneyOperations.removeGoalLine, { lineId: id }));
|
|
47014
47973
|
return { data: { ok: true, removed: id }, render: renderRecord };
|
|
47015
47974
|
},
|
|
47016
47975
|
"money goal-count": async ({ args, requireClient }) => {
|
|
@@ -47019,7 +47978,7 @@ var HANDLERS = {
|
|
|
47019
47978
|
transactionId: requireArg(args, 1, "transaction id")
|
|
47020
47979
|
});
|
|
47021
47980
|
return {
|
|
47022
|
-
data: await requireClient().post(
|
|
47981
|
+
data: await requireClient().post(pathOf(moneyOperations.addGoalContribution, { id }), body),
|
|
47023
47982
|
render: renderRecord
|
|
47024
47983
|
};
|
|
47025
47984
|
},
|
|
@@ -47027,37 +47986,43 @@ var HANDLERS = {
|
|
|
47027
47986
|
const id = requireArg(args, 0, "goal id");
|
|
47028
47987
|
const tx = requireArg(args, 1, "transaction id");
|
|
47029
47988
|
return {
|
|
47030
|
-
data: await requireClient().delete(
|
|
47989
|
+
data: await requireClient().delete(pathOf(moneyOperations.removeGoalContribution, { id, transactionId: tx })),
|
|
47031
47990
|
render: renderRecord
|
|
47032
47991
|
};
|
|
47033
47992
|
},
|
|
47034
47993
|
"money recurring": async ({ requireClient }) => ({
|
|
47035
|
-
data: await requireClient().get(
|
|
47994
|
+
data: await requireClient().get(pathOf(moneyOperations.recurringOverview)),
|
|
47036
47995
|
render: renderRecord
|
|
47037
47996
|
}),
|
|
47038
47997
|
"money stream": async ({ args, requireClient }) => {
|
|
47039
47998
|
const id = requireArg(args, 0, "stream id");
|
|
47040
|
-
return {
|
|
47999
|
+
return {
|
|
48000
|
+
data: await requireClient().get(pathOf(moneyOperations.getRecurring, { id })),
|
|
48001
|
+
render: renderRecord
|
|
48002
|
+
};
|
|
47041
48003
|
},
|
|
47042
48004
|
"money recurring-add": async ({ flags, requireClient }) => {
|
|
47043
48005
|
const body = parseInput(createMoneyRecurringInputSchema, {
|
|
47044
48006
|
id: ulid3(),
|
|
47045
48007
|
...readDataFlag(flags)
|
|
47046
48008
|
});
|
|
47047
|
-
return {
|
|
48009
|
+
return {
|
|
48010
|
+
data: await requireClient().post(pathOf(moneyOperations.createRecurring), body),
|
|
48011
|
+
render: renderRecord
|
|
48012
|
+
};
|
|
47048
48013
|
},
|
|
47049
48014
|
"money recurring-update": async ({ args, flags, requireClient }) => {
|
|
47050
48015
|
const id = requireArg(args, 0, "stream id");
|
|
47051
48016
|
const body = parseInput(updateMoneyRecurringInputSchema, readDataFlag(flags));
|
|
47052
48017
|
return {
|
|
47053
|
-
data: await requireClient().patch(
|
|
48018
|
+
data: await requireClient().patch(pathOf(moneyOperations.updateRecurring, { id }), body),
|
|
47054
48019
|
render: renderRecord
|
|
47055
48020
|
};
|
|
47056
48021
|
},
|
|
47057
48022
|
"money recurring-remove": async ({ args, flags, requireClient }) => {
|
|
47058
48023
|
const id = requireArg(args, 0, "stream id");
|
|
47059
48024
|
assertDestructiveAllowed(flags, `stop tracking ${id}`);
|
|
47060
|
-
await requireClient().delete(
|
|
48025
|
+
await requireClient().delete(pathOf(moneyOperations.removeRecurring, { id }));
|
|
47061
48026
|
return { data: { ok: true, removed: id }, render: renderRecord };
|
|
47062
48027
|
},
|
|
47063
48028
|
"animals overview": async ({ requireClient }) => ({
|