@wirecat/cli-core 0.571.0 → 0.573.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,24 @@ shape of this file.
|
|
|
7
7
|
|
|
8
8
|
## Unreleased
|
|
9
9
|
|
|
10
|
+
## 0.573.0 — 05.11.2026
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- **The owner sets a confirmed payment's wrong split right.** `store.finance.unallocate` now takes an allocation back
|
|
15
|
+
from a confirmed payment too, when `by` is the owner; `allocate` then puts the right amounts on, under the same
|
|
16
|
+
over-payment, over-invoice and currency rules, and the invoices' statuses follow. A bot is still refused on a
|
|
17
|
+
confirmed payment (`finance.owner-only`); a rejected or deleted payment is `finance.unallocate`.
|
|
18
|
+
|
|
19
|
+
## 0.572.0 — 05.11.2026
|
|
20
|
+
|
|
21
|
+
### Changed — may break callers
|
|
22
|
+
|
|
23
|
+
- **`facts.unconfirm` is now `facts.revoke`**, its refusal reason `fact.unconfirm-correction` is
|
|
24
|
+
`fact.revoke-correction`, and the step it writes into a fact's `metadata.history` is `revoked`. memo's command is
|
|
25
|
+
`memo facts revoke`, a word the shared vocabulary has ("take back what was granted"); `unconfirm` is not in it. Nothing
|
|
26
|
+
called the old names but memo's unreleased command, which moves with this.
|
|
27
|
+
|
|
10
28
|
## 0.571.0 — 05.11.2026
|
|
11
29
|
|
|
12
30
|
### Added
|
package/dist/errors/reasons.js
CHANGED
|
@@ -164,10 +164,10 @@ const OTHERS = [
|
|
|
164
164
|
validation("input.required", "the command needs an answer and cannot ask for one"),
|
|
165
165
|
validation("input.too-large", "the input is over its size limit"),
|
|
166
166
|
["meeting-project.stale", "configuration_error", "the meeting's project changed meanwhile"],
|
|
167
|
-
validation("fact.not-accepted", "only an accepted fact can be
|
|
168
|
-
validation("fact.owner-written", "the owner wrote this fact; it was never proposed, so it cannot be
|
|
167
|
+
validation("fact.not-accepted", "only an accepted fact can be revoked"),
|
|
168
|
+
validation("fact.owner-written", "the owner wrote this fact; it was never proposed, so it cannot be revoked"),
|
|
169
169
|
validation("fact.payment-retired", "a payment is a payments row in store.finance, not a fact"),
|
|
170
|
-
validation("fact.
|
|
170
|
+
validation("fact.revoke-correction", "an accepted correction cannot be revoked; its superseded fact stays"),
|
|
171
171
|
validation("finance.allocate", "the invoice or payment cannot take an allocation in its state"),
|
|
172
172
|
validation("finance.currency", "the payment and the invoice are in different currencies; nothing is converted"),
|
|
173
173
|
validation("finance.field", "a field of the invoice or payment is not valid"),
|
|
@@ -181,7 +181,7 @@ const OTHERS = [
|
|
|
181
181
|
validation("finance.ref", "the reference names no invoice or payment"),
|
|
182
182
|
validation("finance.status", "the invoice's status does not allow this"),
|
|
183
183
|
validation("finance.total", "the invoice's total is not the sum of its lines"),
|
|
184
|
-
validation("finance.unallocate", "
|
|
184
|
+
validation("finance.unallocate", "a rejected or deleted payment's allocations are not taken back"),
|
|
185
185
|
validation("record.entity", "the invoice or payment the record stands for was refused"),
|
|
186
186
|
["record.map-owner-only", "permission_error", "only the owner says which entity a source record is"],
|
|
187
187
|
validation("record.map-type", "a record maps only to an entity of its own type"),
|
|
@@ -74,7 +74,7 @@ export interface FactsStore {
|
|
|
74
74
|
* The owner takes back the approval of an accepted fact an agent proposed: it waits as `proposed` again. The step is
|
|
75
75
|
* kept in `metadata.history`, with the decision it took back.
|
|
76
76
|
*/
|
|
77
|
-
|
|
77
|
+
revoke(reference: string, by: Decider, reason?: string): Promise<Fact>;
|
|
78
78
|
/** The owner, or an agent for the owner, turns down a proposed fact; it stays, marked `rejected`. */
|
|
79
79
|
reject(reference: string, by: Decider, reason?: string): Promise<Fact>;
|
|
80
80
|
/**
|
|
@@ -154,24 +154,24 @@ export const factOperationsOver = (context) => {
|
|
|
154
154
|
database.prepare("UPDATE facts SET status = 'reversed', updated_at = ? WHERE id = ?").run(now(), Number(row.id));
|
|
155
155
|
return factOf(rowOf(reference));
|
|
156
156
|
},
|
|
157
|
-
|
|
157
|
+
revoke: (reference, by, reason) => {
|
|
158
158
|
const row = rowOf(reference);
|
|
159
159
|
const ref = `fact:${row.id}`;
|
|
160
160
|
assertMayWithdraw({ id: ref, proposedBy: { type: "unknown" }, proposed: false }, by);
|
|
161
161
|
write(database, () => {
|
|
162
162
|
const current = database.prepare("SELECT * FROM facts WHERE id = ?").get(Number(row.id));
|
|
163
163
|
if (current.status !== "accepted")
|
|
164
|
-
throw new CliError("validation_error", `only an accepted fact can be
|
|
164
|
+
throw new CliError("validation_error", `only an accepted fact can be revoked; ${ref} is ${String(current.status)}`, { reason: "fact.not-accepted" });
|
|
165
165
|
if (current.author_type === "person")
|
|
166
166
|
throw new CliError("validation_error", `${ref} is the owner's own fact, never proposed; correct it with a fact that supersedes it, or remove it`, { reason: "fact.owner-written" });
|
|
167
167
|
// Accepting it marked the fact it corrects superseded, and what that one was before is not kept.
|
|
168
168
|
if (current.supersedes_id != null)
|
|
169
169
|
throw new CliError("validation_error", `${ref} corrects fact:${current.supersedes_id}, which stopped holding when ${ref} was accepted; ` +
|
|
170
|
-
"remove it or correct it with another fact instead", { reason: "fact.
|
|
170
|
+
"remove it or correct it with another fact instead", { reason: "fact.revoke-correction" });
|
|
171
171
|
const at = now();
|
|
172
172
|
const { decision, history, ...metadata } = (current.metadata == null ? {} : JSON.parse(String(current.metadata)));
|
|
173
173
|
const step = {
|
|
174
|
-
step: "
|
|
174
|
+
step: "revoked",
|
|
175
175
|
by: "owner",
|
|
176
176
|
at: iso(at),
|
|
177
177
|
confirmedBy: { type: current.confirmed_by_type, id: String(current.confirmed_by_id) },
|
|
@@ -236,7 +236,7 @@ export const factsStoreOver = (context) => {
|
|
|
236
236
|
list: async (options) => operations.list(options),
|
|
237
237
|
accept: async (reference, by, reason) => operations.accept(reference, by, reason),
|
|
238
238
|
reverse: async (reference, by) => operations.reverse(reference, by),
|
|
239
|
-
|
|
239
|
+
revoke: async (reference, by, reason) => operations.revoke(reference, by, reason),
|
|
240
240
|
reject: async (reference, by, reason) => operations.reject(reference, by, reason),
|
|
241
241
|
remove: async (reference, by) => operations.remove(reference, by),
|
|
242
242
|
sources: async (reference) => operations.sources(reference),
|
|
@@ -181,8 +181,8 @@ export interface FinanceStore {
|
|
|
181
181
|
by: Author;
|
|
182
182
|
}): Promise<Allocation>;
|
|
183
183
|
/**
|
|
184
|
-
* Takes one allocation back
|
|
185
|
-
*
|
|
184
|
+
* Takes one allocation back, under the same rule as `allocate`: the owner from any payment, confirmed too, to set a
|
|
185
|
+
* wrong split right; a bot only from one it proposed that is still proposed.
|
|
186
186
|
*/
|
|
187
187
|
unallocate(input: {
|
|
188
188
|
payment: string;
|
|
@@ -501,8 +501,8 @@ export const financeOperationsOver = (context) => {
|
|
|
501
501
|
const row = rowOf(payment, "payment");
|
|
502
502
|
const ref = `payment:${row.id}`;
|
|
503
503
|
mayAllocate(row, by);
|
|
504
|
-
if (row.review
|
|
505
|
-
refuse(`${ref} is ${row.deleted_at != null ? "deleted" :
|
|
504
|
+
if (row.review === "rejected" || row.deleted_at != null)
|
|
505
|
+
refuse(`${ref} is ${row.deleted_at != null ? "deleted" : "rejected"}; only a proposed or confirmed payment's ` +
|
|
506
506
|
"allocations are taken back", "finance.unallocate");
|
|
507
507
|
const target = rowOf(invoice, "invoice");
|
|
508
508
|
write(database, () => {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wirecat/cli-core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.573.0",
|
|
4
4
|
"description": "The messenger-neutral half of a messaging CLI: domain model, message locators, rendering, name resolution, the SQLite seam, the command skeleton and shared read commands, the send guard, run records and the message store",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"author": "Viacheslav Ptsarev",
|