@wirecat/cli-core 0.557.0 → 0.559.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.
Files changed (55) hide show
  1. package/CHANGELOG.md +33 -0
  2. package/dist/cli/index.d.ts +0 -1
  3. package/dist/cli/index.js +0 -1
  4. package/dist/domain/records.d.ts +161 -0
  5. package/dist/domain/records.js +234 -0
  6. package/dist/entities/fact.d.ts +1 -12
  7. package/dist/entities/fact.js +0 -13
  8. package/dist/entities/index.d.ts +2 -12
  9. package/dist/entities/meeting-findings.d.ts +1 -1
  10. package/dist/errors/reasons.js +10 -0
  11. package/dist/index.d.ts +1 -0
  12. package/dist/index.js +1 -0
  13. package/dist/meetings/findings-rules.d.ts +7 -4
  14. package/dist/meetings/findings-rules.js +11 -4
  15. package/dist/meetings/payment.d.ts +10 -6
  16. package/dist/meetings/payment.js +21 -6
  17. package/dist/runs/secrets.d.ts +2 -0
  18. package/dist/runs/secrets.js +2 -0
  19. package/dist/services/index.d.ts +1 -0
  20. package/dist/services/index.js +1 -0
  21. package/dist/services/ingest.d.ts +45 -0
  22. package/dist/services/ingest.js +80 -0
  23. package/dist/services/project-status/index.d.ts +1 -1
  24. package/dist/services/project-status/index.js +7 -3
  25. package/dist/services/project-status/signals/payments.d.ts +3 -3
  26. package/dist/services/project-status/signals/payments.js +43 -17
  27. package/dist/store/evidence-findings.js +16 -8
  28. package/dist/store/index.d.ts +2 -1
  29. package/dist/store/project-transfer/request.d.ts +1 -1
  30. package/dist/store/project-transfer/schema.d.ts +2 -2
  31. package/dist/store/project-transfer/snapshot-model.d.ts +2 -2
  32. package/dist/store/sqlite/accounts.js +4 -0
  33. package/dist/store/sqlite/facts.d.ts +0 -13
  34. package/dist/store/sqlite/facts.js +5 -58
  35. package/dist/store/sqlite/finance.d.ts +4 -0
  36. package/dist/store/sqlite/finance.js +19 -4
  37. package/dist/store/sqlite/findings-core.js +5 -14
  38. package/dist/store/sqlite/manifest.js +2 -0
  39. package/dist/store/sqlite/migrations.generated.js +18 -0
  40. package/dist/store/sqlite/open-store.js +2 -0
  41. package/dist/store/sqlite/payment-entries.d.ts +26 -0
  42. package/dist/store/sqlite/payment-entries.js +91 -0
  43. package/dist/store/sqlite/payment-facts.d.ts +12 -0
  44. package/dist/store/sqlite/payment-facts.js +92 -0
  45. package/dist/store/sqlite/project-transfer/snapshot.d.ts +1 -1
  46. package/dist/store/sqlite/records.d.ts +81 -0
  47. package/dist/store/sqlite/records.js +372 -0
  48. package/dist/store/sqlite/schema.d.ts +353 -0
  49. package/dist/store/sqlite/schema.js +37 -0
  50. package/dist/store/store.d.ts +3 -1
  51. package/dist/store/store.js +5 -0
  52. package/package.json +4 -2
  53. package/schemas/records-envelope.v1.schema.json +108 -0
  54. package/dist/cli/payment-query.d.ts +0 -8
  55. package/dist/cli/payment-query.js +0 -27
@@ -14890,6 +14890,359 @@ export declare const paymentAllocations: import("drizzle-orm/sqlite-core").SQLit
14890
14890
  dialect: 'sqlite';
14891
14891
  isAlias: false;
14892
14892
  }>;
14893
+ /** What a source said about one of its records, as it said it: the layer under the entity an import makes. */
14894
+ export declare const records: import("drizzle-orm/sqlite-core").SQLiteTableWithColumns<{
14895
+ name: "records";
14896
+ schema: undefined;
14897
+ columns: {
14898
+ id: import("drizzle-orm/sqlite-core").SQLiteColumn<{
14899
+ name: string;
14900
+ tableName: "records";
14901
+ dataType: "number int53";
14902
+ data: number;
14903
+ driverParam: number;
14904
+ notNull: true;
14905
+ hasDefault: true;
14906
+ isPrimaryKey: true;
14907
+ isAutoincrement: false;
14908
+ hasRuntimeDefault: false;
14909
+ enumValues: undefined;
14910
+ baseColumn: never;
14911
+ identity: undefined;
14912
+ generated: undefined;
14913
+ }, {}>;
14914
+ accountId: import("drizzle-orm/sqlite-core").SQLiteColumn<{
14915
+ name: string;
14916
+ tableName: "records";
14917
+ dataType: "number int53";
14918
+ data: number;
14919
+ driverParam: number;
14920
+ notNull: true;
14921
+ hasDefault: false;
14922
+ isPrimaryKey: false;
14923
+ isAutoincrement: false;
14924
+ hasRuntimeDefault: false;
14925
+ enumValues: undefined;
14926
+ baseColumn: never;
14927
+ identity: undefined;
14928
+ generated: undefined;
14929
+ }, {}>;
14930
+ type: import("drizzle-orm/sqlite-core").SQLiteColumn<{
14931
+ name: string;
14932
+ tableName: "records";
14933
+ dataType: "string";
14934
+ data: string;
14935
+ driverParam: string;
14936
+ notNull: true;
14937
+ hasDefault: false;
14938
+ isPrimaryKey: false;
14939
+ isAutoincrement: false;
14940
+ hasRuntimeDefault: false;
14941
+ enumValues: [string, ...string[]];
14942
+ baseColumn: never;
14943
+ identity: undefined;
14944
+ generated: undefined;
14945
+ }, {}>;
14946
+ externalId: import("drizzle-orm/sqlite-core").SQLiteColumn<{
14947
+ name: string;
14948
+ tableName: "records";
14949
+ dataType: "string";
14950
+ data: string;
14951
+ driverParam: string;
14952
+ notNull: true;
14953
+ hasDefault: false;
14954
+ isPrimaryKey: false;
14955
+ isAutoincrement: false;
14956
+ hasRuntimeDefault: false;
14957
+ enumValues: [string, ...string[]];
14958
+ baseColumn: never;
14959
+ identity: undefined;
14960
+ generated: undefined;
14961
+ }, {}>;
14962
+ fields: import("drizzle-orm/sqlite-core").SQLiteColumn<{
14963
+ name: string;
14964
+ tableName: "records";
14965
+ dataType: "string";
14966
+ data: string;
14967
+ driverParam: string;
14968
+ notNull: true;
14969
+ hasDefault: false;
14970
+ isPrimaryKey: false;
14971
+ isAutoincrement: false;
14972
+ hasRuntimeDefault: false;
14973
+ enumValues: [string, ...string[]];
14974
+ baseColumn: never;
14975
+ identity: undefined;
14976
+ generated: undefined;
14977
+ }, {}>;
14978
+ revision: import("drizzle-orm/sqlite-core").SQLiteColumn<{
14979
+ name: string;
14980
+ tableName: "records";
14981
+ dataType: "number int53";
14982
+ data: number;
14983
+ driverParam: number;
14984
+ notNull: false;
14985
+ hasDefault: false;
14986
+ isPrimaryKey: false;
14987
+ isAutoincrement: false;
14988
+ hasRuntimeDefault: false;
14989
+ enumValues: undefined;
14990
+ baseColumn: never;
14991
+ identity: undefined;
14992
+ generated: undefined;
14993
+ }, {}>;
14994
+ fingerprint: import("drizzle-orm/sqlite-core").SQLiteColumn<{
14995
+ name: string;
14996
+ tableName: "records";
14997
+ dataType: "string";
14998
+ data: string;
14999
+ driverParam: string;
15000
+ notNull: true;
15001
+ hasDefault: false;
15002
+ isPrimaryKey: false;
15003
+ isAutoincrement: false;
15004
+ hasRuntimeDefault: false;
15005
+ enumValues: [string, ...string[]];
15006
+ baseColumn: never;
15007
+ identity: undefined;
15008
+ generated: undefined;
15009
+ }, {}>;
15010
+ entityType: import("drizzle-orm/sqlite-core").SQLiteColumn<{
15011
+ name: string;
15012
+ tableName: "records";
15013
+ dataType: "string";
15014
+ data: string;
15015
+ driverParam: string;
15016
+ notNull: false;
15017
+ hasDefault: false;
15018
+ isPrimaryKey: false;
15019
+ isAutoincrement: false;
15020
+ hasRuntimeDefault: false;
15021
+ enumValues: [string, ...string[]];
15022
+ baseColumn: never;
15023
+ identity: undefined;
15024
+ generated: undefined;
15025
+ }, {}>;
15026
+ entityId: import("drizzle-orm/sqlite-core").SQLiteColumn<{
15027
+ name: string;
15028
+ tableName: "records";
15029
+ dataType: "number int53";
15030
+ data: number;
15031
+ driverParam: number;
15032
+ notNull: false;
15033
+ hasDefault: false;
15034
+ isPrimaryKey: false;
15035
+ isAutoincrement: false;
15036
+ hasRuntimeDefault: false;
15037
+ enumValues: undefined;
15038
+ baseColumn: never;
15039
+ identity: undefined;
15040
+ generated: undefined;
15041
+ }, {}>;
15042
+ projectedFingerprint: import("drizzle-orm/sqlite-core").SQLiteColumn<{
15043
+ name: string;
15044
+ tableName: "records";
15045
+ dataType: "string";
15046
+ data: string;
15047
+ driverParam: string;
15048
+ notNull: false;
15049
+ hasDefault: false;
15050
+ isPrimaryKey: false;
15051
+ isAutoincrement: false;
15052
+ hasRuntimeDefault: false;
15053
+ enumValues: [string, ...string[]];
15054
+ baseColumn: never;
15055
+ identity: undefined;
15056
+ generated: undefined;
15057
+ }, {}>;
15058
+ batchId: import("drizzle-orm/sqlite-core").SQLiteColumn<{
15059
+ name: string;
15060
+ tableName: "records";
15061
+ dataType: "string";
15062
+ data: string;
15063
+ driverParam: string;
15064
+ notNull: true;
15065
+ hasDefault: false;
15066
+ isPrimaryKey: false;
15067
+ isAutoincrement: false;
15068
+ hasRuntimeDefault: false;
15069
+ enumValues: [string, ...string[]];
15070
+ baseColumn: never;
15071
+ identity: undefined;
15072
+ generated: undefined;
15073
+ }, {}>;
15074
+ createdAt: import("drizzle-orm/sqlite-core").SQLiteColumn<{
15075
+ name: string;
15076
+ tableName: "records";
15077
+ dataType: "number int53";
15078
+ data: number;
15079
+ driverParam: number;
15080
+ notNull: true;
15081
+ hasDefault: false;
15082
+ isPrimaryKey: false;
15083
+ isAutoincrement: false;
15084
+ hasRuntimeDefault: false;
15085
+ enumValues: undefined;
15086
+ baseColumn: never;
15087
+ identity: undefined;
15088
+ generated: undefined;
15089
+ }, {}>;
15090
+ updatedAt: import("drizzle-orm/sqlite-core").SQLiteColumn<{
15091
+ name: string;
15092
+ tableName: "records";
15093
+ dataType: "number int53";
15094
+ data: number;
15095
+ driverParam: number;
15096
+ notNull: true;
15097
+ hasDefault: false;
15098
+ isPrimaryKey: false;
15099
+ isAutoincrement: false;
15100
+ hasRuntimeDefault: false;
15101
+ enumValues: undefined;
15102
+ baseColumn: never;
15103
+ identity: undefined;
15104
+ generated: undefined;
15105
+ }, {}>;
15106
+ deletedAt: import("drizzle-orm/sqlite-core").SQLiteColumn<{
15107
+ name: string;
15108
+ tableName: "records";
15109
+ dataType: "number int53";
15110
+ data: number;
15111
+ driverParam: number;
15112
+ notNull: false;
15113
+ hasDefault: false;
15114
+ isPrimaryKey: false;
15115
+ isAutoincrement: false;
15116
+ hasRuntimeDefault: false;
15117
+ enumValues: undefined;
15118
+ baseColumn: never;
15119
+ identity: undefined;
15120
+ generated: undefined;
15121
+ }, {}>;
15122
+ };
15123
+ dialect: 'sqlite';
15124
+ isAlias: false;
15125
+ }>;
15126
+ export declare const recordRelations: import("drizzle-orm/sqlite-core").SQLiteTableWithColumns<{
15127
+ name: "record_relations";
15128
+ schema: undefined;
15129
+ columns: {
15130
+ id: import("drizzle-orm/sqlite-core").SQLiteColumn<{
15131
+ name: string;
15132
+ tableName: "record_relations";
15133
+ dataType: "number int53";
15134
+ data: number;
15135
+ driverParam: number;
15136
+ notNull: true;
15137
+ hasDefault: true;
15138
+ isPrimaryKey: true;
15139
+ isAutoincrement: false;
15140
+ hasRuntimeDefault: false;
15141
+ enumValues: undefined;
15142
+ baseColumn: never;
15143
+ identity: undefined;
15144
+ generated: undefined;
15145
+ }, {}>;
15146
+ recordId: import("drizzle-orm/sqlite-core").SQLiteColumn<{
15147
+ name: string;
15148
+ tableName: "record_relations";
15149
+ dataType: "number int53";
15150
+ data: number;
15151
+ driverParam: number;
15152
+ notNull: true;
15153
+ hasDefault: false;
15154
+ isPrimaryKey: false;
15155
+ isAutoincrement: false;
15156
+ hasRuntimeDefault: false;
15157
+ enumValues: undefined;
15158
+ baseColumn: never;
15159
+ identity: undefined;
15160
+ generated: undefined;
15161
+ }, {}>;
15162
+ role: import("drizzle-orm/sqlite-core").SQLiteColumn<{
15163
+ name: string;
15164
+ tableName: "record_relations";
15165
+ dataType: "string";
15166
+ data: string;
15167
+ driverParam: string;
15168
+ notNull: true;
15169
+ hasDefault: false;
15170
+ isPrimaryKey: false;
15171
+ isAutoincrement: false;
15172
+ hasRuntimeDefault: false;
15173
+ enumValues: [string, ...string[]];
15174
+ baseColumn: never;
15175
+ identity: undefined;
15176
+ generated: undefined;
15177
+ }, {}>;
15178
+ targetType: import("drizzle-orm/sqlite-core").SQLiteColumn<{
15179
+ name: string;
15180
+ tableName: "record_relations";
15181
+ dataType: "string";
15182
+ data: string;
15183
+ driverParam: string;
15184
+ notNull: true;
15185
+ hasDefault: false;
15186
+ isPrimaryKey: false;
15187
+ isAutoincrement: false;
15188
+ hasRuntimeDefault: false;
15189
+ enumValues: [string, ...string[]];
15190
+ baseColumn: never;
15191
+ identity: undefined;
15192
+ generated: undefined;
15193
+ }, {}>;
15194
+ targetExternalId: import("drizzle-orm/sqlite-core").SQLiteColumn<{
15195
+ name: string;
15196
+ tableName: "record_relations";
15197
+ dataType: "string";
15198
+ data: string;
15199
+ driverParam: string;
15200
+ notNull: true;
15201
+ hasDefault: false;
15202
+ isPrimaryKey: false;
15203
+ isAutoincrement: false;
15204
+ hasRuntimeDefault: false;
15205
+ enumValues: [string, ...string[]];
15206
+ baseColumn: never;
15207
+ identity: undefined;
15208
+ generated: undefined;
15209
+ }, {}>;
15210
+ targetId: import("drizzle-orm/sqlite-core").SQLiteColumn<{
15211
+ name: string;
15212
+ tableName: "record_relations";
15213
+ dataType: "number int53";
15214
+ data: number;
15215
+ driverParam: number;
15216
+ notNull: false;
15217
+ hasDefault: false;
15218
+ isPrimaryKey: false;
15219
+ isAutoincrement: false;
15220
+ hasRuntimeDefault: false;
15221
+ enumValues: undefined;
15222
+ baseColumn: never;
15223
+ identity: undefined;
15224
+ generated: undefined;
15225
+ }, {}>;
15226
+ createdAt: import("drizzle-orm/sqlite-core").SQLiteColumn<{
15227
+ name: string;
15228
+ tableName: "record_relations";
15229
+ dataType: "number int53";
15230
+ data: number;
15231
+ driverParam: number;
15232
+ notNull: true;
15233
+ hasDefault: false;
15234
+ isPrimaryKey: false;
15235
+ isAutoincrement: false;
15236
+ hasRuntimeDefault: false;
15237
+ enumValues: undefined;
15238
+ baseColumn: never;
15239
+ identity: undefined;
15240
+ generated: undefined;
15241
+ }, {}>;
15242
+ };
15243
+ dialect: 'sqlite';
15244
+ isAlias: false;
15245
+ }>;
14893
15246
  export declare const proposedActions: import("drizzle-orm/sqlite-core").SQLiteTableWithColumns<{
14894
15247
  name: "proposed_actions";
14895
15248
  schema: undefined;
@@ -1492,6 +1492,43 @@ export const paymentAllocations = sqliteTable("payment_allocations", {
1492
1492
  index("payment_allocations_by_invoice_id").on(table.invoiceId),
1493
1493
  index("payment_allocations_by_author_type_author_id").on(table.authorType, table.authorId),
1494
1494
  ]);
1495
+ /** What a source said about one of its records, as it said it: the layer under the entity an import makes. */
1496
+ export const records = sqliteTable("records", {
1497
+ id: integer("id").primaryKey(),
1498
+ accountId: integer("account_id")
1499
+ .notNull()
1500
+ .references(() => accounts.id),
1501
+ type: text("type").notNull(),
1502
+ externalId: text("external_id").notNull(),
1503
+ fields: text("fields").notNull(),
1504
+ revision: integer("revision"),
1505
+ fingerprint: text("fingerprint").notNull(),
1506
+ entityType: text("entity_type"),
1507
+ entityId: integer("entity_id"),
1508
+ projectedFingerprint: text("projected_fingerprint"),
1509
+ batchId: text("batch_id").notNull(),
1510
+ createdAt: integer("created_at").notNull(),
1511
+ updatedAt: integer("updated_at").notNull(),
1512
+ deletedAt: integer("deleted_at"),
1513
+ }, (table) => [
1514
+ unique().on(table.accountId, table.type, table.externalId),
1515
+ index("records_by_entity_type_entity_id").on(table.entityType, table.entityId),
1516
+ ]);
1517
+ export const recordRelations = sqliteTable("record_relations", {
1518
+ id: integer("id").primaryKey(),
1519
+ recordId: integer("record_id")
1520
+ .notNull()
1521
+ .references(() => records.id),
1522
+ role: text("role").notNull(),
1523
+ targetType: text("target_type").notNull(),
1524
+ targetExternalId: text("target_external_id").notNull(),
1525
+ targetId: integer("target_id").references(() => records.id),
1526
+ createdAt: integer("created_at").notNull(),
1527
+ }, (table) => [
1528
+ unique().on(table.recordId, table.role, table.targetType, table.targetExternalId),
1529
+ index("record_relations_by_target_type_target_external_id").on(table.targetType, table.targetExternalId),
1530
+ index("record_relations_by_target_id").on(table.targetId),
1531
+ ]);
1495
1532
  export const proposedActions = sqliteTable("proposed_actions", {
1496
1533
  id: integer("id").primaryKey(),
1497
1534
  kind: text("kind").notNull(),
@@ -35,6 +35,7 @@ import { type SourceMentionStore } from "./sqlite/mention-sources.js";
35
35
  import { type NotesStore } from "./sqlite/notes.js";
36
36
  import { type StoreOptions } from "./sqlite/open-store.js";
37
37
  import { type ProposedActionsStore } from "./sqlite/proposed-actions.js";
38
+ import { type RecordStore } from "./sqlite/records.js";
38
39
  import { type StoreTaskStore } from "./sqlite/tasks.js";
39
40
  import { type SyncStore } from "./sync.js";
40
41
  import { type TagsStore } from "./tags.js";
@@ -98,6 +99,8 @@ export interface MessageStore {
98
99
  readonly facts: FactsStore;
99
100
  /** Invoices, payments and their allocations, in exact minor units; an agent's or an import's wait for the owner. */
100
101
  readonly finance: FinanceStore;
102
+ /** What each import said, by the source's identity; `ingest` (services) is the way in. */
103
+ readonly records: RecordStore;
101
104
  /** What agents concluded: summaries, digests, facts, preferences, each with evidence and a scope. */
102
105
  readonly memories: MemoriesStore;
103
106
  /** What an agent wants done outside the store, waiting for the owner's approval. */
@@ -115,7 +118,6 @@ export interface MessageStore {
115
118
  forAccount(key: AccountKey): AccountStore;
116
119
  close(): Promise<void>;
117
120
  }
118
- export type { PaymentFilter } from "./sqlite/facts.js";
119
121
  export type { ChatHistoryShape, StoredHistorySkip } from "./sqlite/history-skips.js";
120
122
  export { BACKFILL_ON_OPEN, type StoreOptions } from "./sqlite/open-store.js";
121
123
  export { fileFacts, readStoreTables, type TableKind } from "./sqlite/store-tables.js";
@@ -38,6 +38,7 @@ import { notesStoreOver } from "./sqlite/notes.js";
38
38
  import { openStoreContext } from "./sqlite/open-store.js";
39
39
  import { projectAnnotationStoreOver } from "./sqlite/project-transfer/store.js";
40
40
  import { proposedActionsStoreOver } from "./sqlite/proposed-actions.js";
41
+ import { recordStoreOver } from "./sqlite/records.js";
41
42
  import { refSummariesOf } from "./sqlite/ref-summaries.js";
42
43
  import * as stems from "./sqlite/stems.js";
43
44
  import { taskStoreOver } from "./sqlite/tasks.js";
@@ -112,6 +113,7 @@ const storeOver = (context) => {
112
113
  };
113
114
  const facts = once(() => factsStoreOver(context));
114
115
  const finance = once(() => financeStoreOver(context));
116
+ const records = once(() => recordStoreOver(context));
115
117
  const memories = once(() => memoriesStoreOver(context));
116
118
  const proposedActions = once(() => proposedActionsStoreOver(context));
117
119
  const agentActions = once(() => agentActionsStoreOver(context, pruneLogsWhenDue));
@@ -215,6 +217,9 @@ const storeOver = (context) => {
215
217
  get finance() {
216
218
  return finance();
217
219
  },
220
+ get records() {
221
+ return records();
222
+ },
218
223
  get memories() {
219
224
  return memories();
220
225
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wirecat/cli-core",
3
- "version": "0.557.0",
3
+ "version": "0.559.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",
@@ -25,9 +25,11 @@
25
25
  "CHANGELOG.md",
26
26
  "LICENSE",
27
27
  "THIRD_PARTY_NOTICES",
28
- "docs/search/recipes.json"
28
+ "docs/search/recipes.json",
29
+ "schemas"
29
30
  ],
30
31
  "exports": {
32
+ "./schemas/records-envelope.v1.schema.json": "./schemas/records-envelope.v1.schema.json",
31
33
  "./documents": {
32
34
  "types": "./dist/documents.d.ts",
33
35
  "default": "./dist/documents.js"
@@ -0,0 +1,108 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "title": "WireCat records envelope, version 1",
4
+ "description": "Records one source sends to the store. JSONL is the same model: the first line holds schema_version and source, each further line one record.",
5
+ "type": "object",
6
+ "required": ["schema_version", "source", "records"],
7
+ "additionalProperties": false,
8
+ "properties": {
9
+ "schema_version": {
10
+ "const": 1
11
+ },
12
+ "source": {
13
+ "$ref": "#/$defs/source"
14
+ },
15
+ "records": {
16
+ "type": "array",
17
+ "items": {
18
+ "$ref": "#/$defs/record"
19
+ }
20
+ }
21
+ },
22
+ "$defs": {
23
+ "source": {
24
+ "type": "object",
25
+ "required": ["provider", "account", "batch_id"],
26
+ "additionalProperties": false,
27
+ "properties": {
28
+ "provider": {
29
+ "type": "string",
30
+ "pattern": "^[a-z0-9][a-z0-9_-]{0,62}$",
31
+ "description": "The system the records come from"
32
+ },
33
+ "account": {
34
+ "type": "string",
35
+ "minLength": 1,
36
+ "maxLength": 512,
37
+ "description": "The account in that system"
38
+ },
39
+ "batch_id": {
40
+ "type": "string",
41
+ "minLength": 1,
42
+ "maxLength": 512,
43
+ "description": "This import, for the receipt"
44
+ }
45
+ }
46
+ },
47
+ "record": {
48
+ "type": "object",
49
+ "required": ["key", "type", "external_id", "operation"],
50
+ "additionalProperties": false,
51
+ "properties": {
52
+ "key": {
53
+ "type": "string",
54
+ "minLength": 1,
55
+ "maxLength": 512
56
+ },
57
+ "type": {
58
+ "type": "string",
59
+ "pattern": "^(invoice|payment|person|organization|project|custom:[a-z0-9][a-z0-9_-]{0,62})$"
60
+ },
61
+ "external_id": {
62
+ "type": "string",
63
+ "minLength": 1,
64
+ "maxLength": 512
65
+ },
66
+ "operation": {
67
+ "enum": ["upsert", "delete"]
68
+ },
69
+ "fields": {
70
+ "type": "object",
71
+ "description": "What the source says, as data: never secrets, never instructions"
72
+ },
73
+ "revision": {
74
+ "type": "integer",
75
+ "minimum": 0,
76
+ "maximum": 9007199254740991
77
+ },
78
+ "relations": {
79
+ "type": "array",
80
+ "maxItems": 100,
81
+ "items": {
82
+ "$ref": "#/$defs/relation"
83
+ }
84
+ }
85
+ }
86
+ },
87
+ "relation": {
88
+ "type": "object",
89
+ "required": ["role", "type", "external_id"],
90
+ "additionalProperties": false,
91
+ "properties": {
92
+ "role": {
93
+ "type": "string",
94
+ "pattern": "^[a-z0-9][a-z0-9_-]{0,62}$"
95
+ },
96
+ "type": {
97
+ "type": "string",
98
+ "pattern": "^(invoice|payment|person|organization|project|custom:[a-z0-9][a-z0-9_-]{0,62})$"
99
+ },
100
+ "external_id": {
101
+ "type": "string",
102
+ "minLength": 1,
103
+ "maxLength": 512
104
+ }
105
+ }
106
+ }
107
+ }
108
+ }
@@ -1,8 +0,0 @@
1
- import type { PaymentFilter } from "../store/store.js";
2
- /**
3
- * The terms a facts list adds for payments. `state` is the payment's, not `status`, which stays the review status
4
- * (proposed, accepted).
5
- */
6
- export declare const PAYMENT_QUERY_FIELDS: import("@wirecat/cli-base/query").FieldSpec[];
7
- /** The store's payment filter from `queryTerms`' answer; `undefined` when no payment term was given. */
8
- export declare const paymentFilterOf: (terms: Map<string, string>) => PaymentFilter | undefined;
@@ -1,27 +0,0 @@
1
- import { CliError } from "@wirecat/cli-base";
2
- import { PAYMENT_DIRECTIONS, PAYMENT_STATES } from "../meetings/index.js";
3
- import { termField } from "./list-query.js";
4
- /**
5
- * The terms a facts list adds for payments. `state` is the payment's, not `status`, which stays the review status
6
- * (proposed, accepted).
7
- */
8
- export const PAYMENT_QUERY_FIELDS = [
9
- termField("open", "bool", "open:true"),
10
- termField("direction", "enum", "direction:to_us", { values: PAYMENT_DIRECTIONS }),
11
- termField("state", "enum", "state:paid", { values: PAYMENT_STATES }),
12
- ];
13
- /** The store's payment filter from `queryTerms`' answer; `undefined` when no payment term was given. */
14
- export const paymentFilterOf = (terms) => {
15
- const open = terms.get("open");
16
- const direction = terms.get("direction");
17
- const state = terms.get("state");
18
- if (open === undefined && direction === undefined && state === undefined)
19
- return undefined;
20
- if (open !== undefined && open !== "true" && open !== "false")
21
- throw new CliError("validation_error", "open takes true or false");
22
- return {
23
- ...(open === undefined ? {} : { open: open === "true" }),
24
- ...(direction === undefined ? {} : { direction }),
25
- ...(state === undefined ? {} : { state }),
26
- };
27
- };