@luca-financial/luca-schema 3.2.0 → 3.3.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/CHANGELOG.md CHANGED
@@ -5,6 +5,25 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [3.3.1] - 2026-04-05
9
+
10
+ ### Changed
11
+
12
+ - Require `isSameSign` on both `transactionLink` and `recurringTransactionLink` so linked amounts can explicitly indicate same-sign versus opposite-sign matching behavior.
13
+ - Update bundled examples, fixtures, tests, and README documentation to reflect the new required link-sign behavior flag.
14
+
15
+ ## [3.3.0] - 2026-04-05
16
+
17
+ ### Added
18
+
19
+ - Add support for linking related recurring transactions with a new `recurringTransactionLink` schema.
20
+ - Add optional `recurringTransactionLinks` support to the aggregate Luca Schema, schema exports, enums, validator metadata, generated types, and bundled example data.
21
+ - Add validation coverage for recurring transaction links in both entity-level and aggregate/example tests.
22
+
23
+ ### Changed
24
+
25
+ - Update README and example documentation to describe recurring transaction links and their scheduled-transfer use cases.
26
+
8
27
  ## [3.2.0] - 2026-04-04
9
28
 
10
29
  ### Added
package/README.md CHANGED
@@ -210,6 +210,23 @@ const transactionSplit = {
210
210
  };
211
211
  ```
212
212
 
213
+ ### RecurringTransactionLink
214
+
215
+ Validates links between related recurring transactions, such as scheduled transfer legs recorded in separate accounts.
216
+
217
+ ```typescript
218
+ const recurringTransactionLink = {
219
+ id: string;
220
+ sourceRecurringTransactionId: string;
221
+ destinationRecurringTransactionId: string;
222
+ isSameSign: boolean;
223
+ createdAt: string;
224
+ updatedAt: string | null;
225
+ deletedAt?: string | null;
226
+ version?: number;
227
+ };
228
+ ```
229
+
213
230
  ### TransactionLink
214
231
 
215
232
  Validates links between related transactions, such as transfers recorded in separate accounts.
@@ -219,6 +236,7 @@ const transactionLink = {
219
236
  id: string;
220
237
  sourceTransactionId: string;
221
238
  destinationTransactionId: string;
239
+ isSameSign: boolean;
222
240
  createdAt: string;
223
241
  updatedAt: string | null;
224
242
  deletedAt?: string | null;
@@ -226,7 +244,7 @@ const transactionLink = {
226
244
  };
227
245
  ```
228
246
 
229
- Cross-transaction rules like matching dates, matching amounts, or opposite signs are not enforced by this schema and should be handled in application logic.
247
+ `isSameSign` indicates whether linked amounts should share the same sign (`true`) or use opposite signs (`false`) while still matching by absolute value. Cross-transaction rules like matching dates or verifying absolute-value equality are not enforced by this schema and should be handled in application logic.
230
248
 
231
249
  ### LucaSchema
232
250
 
@@ -240,6 +258,7 @@ const lucaSchema = {
240
258
  statements: Statement[];
241
259
  recurringTransactions: RecurringTransaction[];
242
260
  recurringTransactionEvents: RecurringTransactionEvent[];
261
+ recurringTransactionLinks?: RecurringTransactionLink[];
243
262
  transactions: Transaction[];
244
263
  transactionLinks?: TransactionLink[];
245
264
  transactionSplits: TransactionSplit[];
@@ -270,7 +289,7 @@ import {
270
289
  - `validate(schemaKey, data)` → `{ valid: boolean, errors: AjvError[] }`
271
290
  - `validateCollection(schemaKey, array)` → `{ valid: boolean, errors: [{ index, entity, errors }] }`
272
291
  - `getDateFieldPaths(schemaKey)` → `string[]` of `format: date` fields for a schema key
273
- - `getDateFieldPathsByCollection()` → `{ accounts, categories, statements, recurringTransactions, recurringTransactionEvents, transactions, transactionLinks, transactionSplits }`
292
+ - `getDateFieldPathsByCollection()` → `{ accounts, categories, statements, recurringTransactions, recurringTransactionEvents, recurringTransactionLinks, transactions, transactionLinks, transactionSplits }`
274
293
  - `getValidFields(schemaKey)` → `Set<string>` of all fields (includes common fields when applicable)
275
294
  - `getRequiredFields(schemaKey)` → `Set<string>` of required fields (includes common required fields)
276
295
  - `stripInvalidFields(schemaKey, data)` → new object with only schema-defined keys
@@ -526,7 +526,47 @@ export type RecurringTransactionID = string;
526
526
  * The date when the occurrence is expected.
527
527
  */
528
528
  export type ExpectedDate = string;
529
- export type Transaction = Common5 & {
529
+ /**
530
+ * Links two related recurring transactions, such as mirrored transfer schedules recorded in separate accounts.
531
+ */
532
+ export type RecurringTransactionLink = Common5 & {
533
+ sourceRecurringTransactionId: SourceRecurringTransactionID;
534
+ destinationRecurringTransactionId: DestinationRecurringTransactionID;
535
+ isSameSign: IsSameSign;
536
+ };
537
+ /**
538
+ * UUID for the item
539
+ */
540
+ export type ID5 = string;
541
+ /**
542
+ * The timestamp of the creation of the item
543
+ */
544
+ export type DateCreated5 = string;
545
+ /**
546
+ * The timestamp of the last update or null if the item has not been updated yet
547
+ */
548
+ export type LastUpdated5 = string | null;
549
+ /**
550
+ * The timestamp of when the item was soft-deleted
551
+ */
552
+ export type DateDeleted5 = string | null;
553
+ /**
554
+ * Version number for optimistic concurrency control
555
+ */
556
+ export type Version5 = number;
557
+ /**
558
+ * UUID of the source recurring transaction in the link.
559
+ */
560
+ export type SourceRecurringTransactionID = string;
561
+ /**
562
+ * UUID of the destination recurring transaction in the link.
563
+ */
564
+ export type DestinationRecurringTransactionID = string;
565
+ /**
566
+ * Whether the linked recurring transactions are expected to have matching signs. When false, the linked recurring transactions are expected to have opposite signs.
567
+ */
568
+ export type IsSameSign = boolean;
569
+ export type Transaction = Common6 & {
530
570
  accountId: AccountID2;
531
571
  date: Date;
532
572
  authorizedAt?: AuthorizedAt;
@@ -556,23 +596,23 @@ export type Transaction = Common5 & {
556
596
  /**
557
597
  * UUID for the item
558
598
  */
559
- export type ID5 = string;
599
+ export type ID6 = string;
560
600
  /**
561
601
  * The timestamp of the creation of the item
562
602
  */
563
- export type DateCreated5 = string;
603
+ export type DateCreated6 = string;
564
604
  /**
565
605
  * The timestamp of the last update or null if the item has not been updated yet
566
606
  */
567
- export type LastUpdated5 = string | null;
607
+ export type LastUpdated6 = string | null;
568
608
  /**
569
609
  * The timestamp of when the item was soft-deleted
570
610
  */
571
- export type DateDeleted5 = string | null;
611
+ export type DateDeleted6 = string | null;
572
612
  /**
573
613
  * Version number for optimistic concurrency control
574
614
  */
575
- export type Version5 = number;
615
+ export type Version6 = number;
576
616
  /**
577
617
  * ID of the account this transaction belongs to
578
618
  */
@@ -620,30 +660,31 @@ export type AggregationServiceID1 = string | null;
620
660
  /**
621
661
  * Links two related transactions, such as transfer legs recorded in separate accounts.
622
662
  */
623
- export type TransactionLink = Common6 & {
663
+ export type TransactionLink = Common7 & {
624
664
  sourceTransactionId: SourceTransactionID;
625
665
  destinationTransactionId: DestinationTransactionID;
666
+ isSameSign: IsSameSign1;
626
667
  };
627
668
  /**
628
669
  * UUID for the item
629
670
  */
630
- export type ID6 = string;
671
+ export type ID7 = string;
631
672
  /**
632
673
  * The timestamp of the creation of the item
633
674
  */
634
- export type DateCreated6 = string;
675
+ export type DateCreated7 = string;
635
676
  /**
636
677
  * The timestamp of the last update or null if the item has not been updated yet
637
678
  */
638
- export type LastUpdated6 = string | null;
679
+ export type LastUpdated7 = string | null;
639
680
  /**
640
681
  * The timestamp of when the item was soft-deleted
641
682
  */
642
- export type DateDeleted6 = string | null;
683
+ export type DateDeleted7 = string | null;
643
684
  /**
644
685
  * Version number for optimistic concurrency control
645
686
  */
646
- export type Version6 = number;
687
+ export type Version7 = number;
647
688
  /**
648
689
  * UUID of the source transaction in the link.
649
690
  */
@@ -652,10 +693,14 @@ export type SourceTransactionID = string;
652
693
  * UUID of the destination transaction in the link.
653
694
  */
654
695
  export type DestinationTransactionID = string;
696
+ /**
697
+ * Whether the linked transactions are expected to have matching signs. When false, the linked transactions are expected to have opposite signs.
698
+ */
699
+ export type IsSameSign1 = boolean;
655
700
  /**
656
701
  * Defines a split within a transaction.
657
702
  */
658
- export type TransactionSplit = Common7 & {
703
+ export type TransactionSplit = Common8 & {
659
704
  transactionId: TransactionID;
660
705
  amount: Amount2;
661
706
  categoryId: CategoryID2;
@@ -665,23 +710,23 @@ export type TransactionSplit = Common7 & {
665
710
  /**
666
711
  * UUID for the item
667
712
  */
668
- export type ID7 = string;
713
+ export type ID8 = string;
669
714
  /**
670
715
  * The timestamp of the creation of the item
671
716
  */
672
- export type DateCreated7 = string;
717
+ export type DateCreated8 = string;
673
718
  /**
674
719
  * The timestamp of the last update or null if the item has not been updated yet
675
720
  */
676
- export type LastUpdated7 = string | null;
721
+ export type LastUpdated8 = string | null;
677
722
  /**
678
723
  * The timestamp of when the item was soft-deleted
679
724
  */
680
- export type DateDeleted7 = string | null;
725
+ export type DateDeleted8 = string | null;
681
726
  /**
682
727
  * Version number for optimistic concurrency control
683
728
  */
684
- export type Version7 = number;
729
+ export type Version8 = number;
685
730
  /**
686
731
  * The identifier of the parent transaction.
687
732
  */
@@ -731,6 +776,10 @@ export interface LucaSchema {
731
776
  * List of recurring transaction events
732
777
  */
733
778
  recurringTransactionEvents: RecurringTransactionEvent[];
779
+ /**
780
+ * List of links between related recurring transactions
781
+ */
782
+ recurringTransactionLinks?: RecurringTransactionLink[];
734
783
  /**
735
784
  * List of transactions
736
785
  */
@@ -824,6 +873,16 @@ export interface Common7 {
824
873
  deletedAt?: DateDeleted7;
825
874
  version?: Version7;
826
875
  }
876
+ /**
877
+ * Common properties for all schemas
878
+ */
879
+ export interface Common8 {
880
+ id: ID8;
881
+ createdAt: DateCreated8;
882
+ updatedAt: LastUpdated8;
883
+ deletedAt?: DateDeleted8;
884
+ version?: Version8;
885
+ }
827
886
 
828
887
  /**
829
888
  * Defines recurring financial transactions within the application.
@@ -975,6 +1034,58 @@ export interface Common {
975
1034
  version?: Version;
976
1035
  }
977
1036
 
1037
+ /**
1038
+ * Links two related recurring transactions, such as mirrored transfer schedules recorded in separate accounts.
1039
+ */
1040
+ export type RecurringTransactionLink = Common & {
1041
+ sourceRecurringTransactionId: SourceRecurringTransactionID;
1042
+ destinationRecurringTransactionId: DestinationRecurringTransactionID;
1043
+ isSameSign: IsSameSign;
1044
+ };
1045
+ /**
1046
+ * UUID for the item
1047
+ */
1048
+ export type ID = string;
1049
+ /**
1050
+ * The timestamp of the creation of the item
1051
+ */
1052
+ export type DateCreated = string;
1053
+ /**
1054
+ * The timestamp of the last update or null if the item has not been updated yet
1055
+ */
1056
+ export type LastUpdated = string | null;
1057
+ /**
1058
+ * The timestamp of when the item was soft-deleted
1059
+ */
1060
+ export type DateDeleted = string | null;
1061
+ /**
1062
+ * Version number for optimistic concurrency control
1063
+ */
1064
+ export type Version = number;
1065
+ /**
1066
+ * UUID of the source recurring transaction in the link.
1067
+ */
1068
+ export type SourceRecurringTransactionID = string;
1069
+ /**
1070
+ * UUID of the destination recurring transaction in the link.
1071
+ */
1072
+ export type DestinationRecurringTransactionID = string;
1073
+ /**
1074
+ * Whether the linked recurring transactions are expected to have matching signs. When false, the linked recurring transactions are expected to have opposite signs.
1075
+ */
1076
+ export type IsSameSign = boolean;
1077
+
1078
+ /**
1079
+ * Common properties for all schemas
1080
+ */
1081
+ export interface Common {
1082
+ id: ID;
1083
+ createdAt: DateCreated;
1084
+ updatedAt: LastUpdated;
1085
+ deletedAt?: DateDeleted;
1086
+ version?: Version;
1087
+ }
1088
+
978
1089
  /**
979
1090
  * Defines the schema for credit card statements.
980
1091
  */
@@ -1161,6 +1272,7 @@ export interface Common {
1161
1272
  export type TransactionLink = Common & {
1162
1273
  sourceTransactionId: SourceTransactionID;
1163
1274
  destinationTransactionId: DestinationTransactionID;
1275
+ isSameSign: IsSameSign;
1164
1276
  };
1165
1277
  /**
1166
1278
  * UUID for the item
@@ -1190,6 +1302,10 @@ export type SourceTransactionID = string;
1190
1302
  * UUID of the destination transaction in the link.
1191
1303
  */
1192
1304
  export type DestinationTransactionID = string;
1305
+ /**
1306
+ * Whether the linked transactions are expected to have matching signs. When false, the linked transactions are expected to have opposite signs.
1307
+ */
1308
+ export type IsSameSign = boolean;
1193
1309
 
1194
1310
  /**
1195
1311
  * Common properties for all schemas
package/dist/esm/index.js CHANGED
@@ -6,6 +6,7 @@ import {
6
6
  lucaSchema as lucaSchemaJson,
7
7
  recurringTransaction,
8
8
  recurringTransactionEvent,
9
+ recurringTransactionLink,
9
10
  statement,
10
11
  transaction,
11
12
  transactionLink,
@@ -30,6 +31,7 @@ const schemas = {
30
31
  statement,
31
32
  recurringTransaction,
32
33
  recurringTransactionEvent,
34
+ recurringTransactionLink,
33
35
  transaction,
34
36
  transactionLink,
35
37
  transactionSplit,
@@ -44,6 +46,7 @@ export const statementSchema = schemas.statement;
44
46
  export const recurringTransactionSchema = schemas.recurringTransaction;
45
47
  export const recurringTransactionEventSchema =
46
48
  schemas.recurringTransactionEvent;
49
+ export const recurringTransactionLinkSchema = schemas.recurringTransactionLink;
47
50
  export const transactionSchema = schemas.transaction;
48
51
  export const transactionLinkSchema = schemas.transactionLink;
49
52
  export const transactionSplitSchema = schemas.transactionSplit;
@@ -8,6 +8,7 @@ import lucaSchemaJson from './schemas/lucaSchema.json' with { type: 'json' };
8
8
  import statementSchemaJson from './schemas/statement.json' with { type: 'json' };
9
9
  import recurringTransactionSchemaJson from './schemas/recurringTransaction.json' with { type: 'json' };
10
10
  import recurringTransactionEventSchemaJson from './schemas/recurringTransactionEvent.json' with { type: 'json' };
11
+ import recurringTransactionLinkSchemaJson from './schemas/recurringTransactionLink.json' with { type: 'json' };
11
12
  import transactionSchemaJson from './schemas/transaction.json' with { type: 'json' };
12
13
  import transactionLinkSchemaJson from './schemas/transactionLink.json' with { type: 'json' };
13
14
  import transactionSplitSchemaJson from './schemas/transactionSplit.json' with { type: 'json' };
@@ -19,6 +20,7 @@ const schemas = {
19
20
  statement: statementSchemaJson,
20
21
  recurringTransaction: recurringTransactionSchemaJson,
21
22
  recurringTransactionEvent: recurringTransactionEventSchemaJson,
23
+ recurringTransactionLink: recurringTransactionLinkSchemaJson,
22
24
  transaction: transactionSchemaJson,
23
25
  transactionLink: transactionLinkSchemaJson,
24
26
  transactionSplit: transactionSplitSchemaJson
@@ -194,6 +196,7 @@ export function getDateFieldPaths(schemaKey) {
194
196
  * statements: Array<string>,
195
197
  * recurringTransactions: Array<string>,
196
198
  * recurringTransactionEvents: Array<string>,
199
+ * recurringTransactionLinks: Array<string>,
197
200
  * transactions: Array<string>,
198
201
  * transactionLinks: Array<string>,
199
202
  * transactionSplits: Array<string>
@@ -206,6 +209,7 @@ export function getDateFieldPathsByCollection() {
206
209
  statements: getDateFieldPaths('statement'),
207
210
  recurringTransactions: getDateFieldPaths('recurringTransaction'),
208
211
  recurringTransactionEvents: getDateFieldPaths('recurringTransactionEvent'),
212
+ recurringTransactionLinks: getDateFieldPaths('recurringTransactionLink'),
209
213
  transactions: getDateFieldPaths('transaction'),
210
214
  transactionLinks: getDateFieldPaths('transactionLink'),
211
215
  transactionSplits: getDateFieldPaths('transactionSplit')
@@ -10,6 +10,7 @@
10
10
  "STATEMENT": "statement",
11
11
  "RECURRING_TRANSACTION": "recurringTransaction",
12
12
  "RECURRING_TRANSACTION_EVENT": "recurringTransactionEvent",
13
+ "RECURRING_TRANSACTION_LINK": "recurringTransactionLink",
13
14
  "TRANSACTION": "transaction",
14
15
  "TRANSACTION_LINK": "transactionLink",
15
16
  "TRANSACTION_SPLIT": "transactionSplit"
@@ -5,6 +5,7 @@ import lucaSchema from './lucaSchema.json' with { type: 'json' };
5
5
  import statement from './statement.json' with { type: 'json' };
6
6
  import recurringTransaction from './recurringTransaction.json' with { type: 'json' };
7
7
  import recurringTransactionEvent from './recurringTransactionEvent.json' with { type: 'json' };
8
+ import recurringTransactionLink from './recurringTransactionLink.json' with { type: 'json' };
8
9
  import transaction from './transaction.json' with { type: 'json' };
9
10
  import transactionLink from './transactionLink.json' with { type: 'json' };
10
11
  import transactionSplit from './transactionSplit.json' with { type: 'json' };
@@ -18,6 +19,7 @@ export {
18
19
  statement,
19
20
  recurringTransaction,
20
21
  recurringTransactionEvent,
22
+ recurringTransactionLink,
21
23
  transaction,
22
24
  transactionLink,
23
25
  transactionSplit,
@@ -32,6 +34,7 @@ export default {
32
34
  statement,
33
35
  recurringTransaction,
34
36
  recurringTransactionEvent,
37
+ recurringTransactionLink,
35
38
  transaction,
36
39
  transactionLink,
37
40
  transactionSplit,
@@ -60,6 +60,14 @@
60
60
  "$ref": "./recurringTransactionEvent.json"
61
61
  }
62
62
  },
63
+ "recurringTransactionLinks": {
64
+ "type": "array",
65
+ "description": "List of links between related recurring transactions",
66
+ "uniqueItems": true,
67
+ "items": {
68
+ "$ref": "./recurringTransactionLink.json"
69
+ }
70
+ },
63
71
  "transactions": {
64
72
  "type": "array",
65
73
  "description": "List of transactions",
@@ -0,0 +1,37 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://raw.githubusercontent.com/LucaFinancial/LucaSchema/main/src/schemas/recurringTransactionLink.json",
4
+ "title": "Recurring Transaction Link",
5
+ "description": "Links two related recurring transactions, such as mirrored transfer schedules recorded in separate accounts.",
6
+ "type": "object",
7
+ "allOf": [
8
+ {
9
+ "$ref": "./common.json"
10
+ }
11
+ ],
12
+ "properties": {
13
+ "sourceRecurringTransactionId": {
14
+ "type": "string",
15
+ "title": "Source Recurring Transaction ID",
16
+ "format": "uuid",
17
+ "description": "UUID of the source recurring transaction in the link."
18
+ },
19
+ "destinationRecurringTransactionId": {
20
+ "type": "string",
21
+ "title": "Destination Recurring Transaction ID",
22
+ "format": "uuid",
23
+ "description": "UUID of the destination recurring transaction in the link."
24
+ },
25
+ "isSameSign": {
26
+ "type": "boolean",
27
+ "title": "Is Same Sign",
28
+ "description": "Whether the linked recurring transactions are expected to have matching signs. When false, the linked recurring transactions are expected to have opposite signs."
29
+ }
30
+ },
31
+ "unevaluatedProperties": false,
32
+ "required": [
33
+ "sourceRecurringTransactionId",
34
+ "destinationRecurringTransactionId",
35
+ "isSameSign"
36
+ ]
37
+ }
@@ -21,8 +21,13 @@
21
21
  "title": "Destination Transaction ID",
22
22
  "format": "uuid",
23
23
  "description": "UUID of the destination transaction in the link."
24
+ },
25
+ "isSameSign": {
26
+ "type": "boolean",
27
+ "title": "Is Same Sign",
28
+ "description": "Whether the linked transactions are expected to have matching signs. When false, the linked transactions are expected to have opposite signs."
24
29
  }
25
30
  },
26
31
  "unevaluatedProperties": false,
27
- "required": ["sourceTransactionId", "destinationTransactionId"]
32
+ "required": ["sourceTransactionId", "destinationTransactionId", "isSameSign"]
28
33
  }
package/dist/index.d.ts CHANGED
@@ -526,7 +526,47 @@ export type RecurringTransactionID = string;
526
526
  * The date when the occurrence is expected.
527
527
  */
528
528
  export type ExpectedDate = string;
529
- export type Transaction = Common5 & {
529
+ /**
530
+ * Links two related recurring transactions, such as mirrored transfer schedules recorded in separate accounts.
531
+ */
532
+ export type RecurringTransactionLink = Common5 & {
533
+ sourceRecurringTransactionId: SourceRecurringTransactionID;
534
+ destinationRecurringTransactionId: DestinationRecurringTransactionID;
535
+ isSameSign: IsSameSign;
536
+ };
537
+ /**
538
+ * UUID for the item
539
+ */
540
+ export type ID5 = string;
541
+ /**
542
+ * The timestamp of the creation of the item
543
+ */
544
+ export type DateCreated5 = string;
545
+ /**
546
+ * The timestamp of the last update or null if the item has not been updated yet
547
+ */
548
+ export type LastUpdated5 = string | null;
549
+ /**
550
+ * The timestamp of when the item was soft-deleted
551
+ */
552
+ export type DateDeleted5 = string | null;
553
+ /**
554
+ * Version number for optimistic concurrency control
555
+ */
556
+ export type Version5 = number;
557
+ /**
558
+ * UUID of the source recurring transaction in the link.
559
+ */
560
+ export type SourceRecurringTransactionID = string;
561
+ /**
562
+ * UUID of the destination recurring transaction in the link.
563
+ */
564
+ export type DestinationRecurringTransactionID = string;
565
+ /**
566
+ * Whether the linked recurring transactions are expected to have matching signs. When false, the linked recurring transactions are expected to have opposite signs.
567
+ */
568
+ export type IsSameSign = boolean;
569
+ export type Transaction = Common6 & {
530
570
  accountId: AccountID2;
531
571
  date: Date;
532
572
  authorizedAt?: AuthorizedAt;
@@ -556,23 +596,23 @@ export type Transaction = Common5 & {
556
596
  /**
557
597
  * UUID for the item
558
598
  */
559
- export type ID5 = string;
599
+ export type ID6 = string;
560
600
  /**
561
601
  * The timestamp of the creation of the item
562
602
  */
563
- export type DateCreated5 = string;
603
+ export type DateCreated6 = string;
564
604
  /**
565
605
  * The timestamp of the last update or null if the item has not been updated yet
566
606
  */
567
- export type LastUpdated5 = string | null;
607
+ export type LastUpdated6 = string | null;
568
608
  /**
569
609
  * The timestamp of when the item was soft-deleted
570
610
  */
571
- export type DateDeleted5 = string | null;
611
+ export type DateDeleted6 = string | null;
572
612
  /**
573
613
  * Version number for optimistic concurrency control
574
614
  */
575
- export type Version5 = number;
615
+ export type Version6 = number;
576
616
  /**
577
617
  * ID of the account this transaction belongs to
578
618
  */
@@ -620,30 +660,31 @@ export type AggregationServiceID1 = string | null;
620
660
  /**
621
661
  * Links two related transactions, such as transfer legs recorded in separate accounts.
622
662
  */
623
- export type TransactionLink = Common6 & {
663
+ export type TransactionLink = Common7 & {
624
664
  sourceTransactionId: SourceTransactionID;
625
665
  destinationTransactionId: DestinationTransactionID;
666
+ isSameSign: IsSameSign1;
626
667
  };
627
668
  /**
628
669
  * UUID for the item
629
670
  */
630
- export type ID6 = string;
671
+ export type ID7 = string;
631
672
  /**
632
673
  * The timestamp of the creation of the item
633
674
  */
634
- export type DateCreated6 = string;
675
+ export type DateCreated7 = string;
635
676
  /**
636
677
  * The timestamp of the last update or null if the item has not been updated yet
637
678
  */
638
- export type LastUpdated6 = string | null;
679
+ export type LastUpdated7 = string | null;
639
680
  /**
640
681
  * The timestamp of when the item was soft-deleted
641
682
  */
642
- export type DateDeleted6 = string | null;
683
+ export type DateDeleted7 = string | null;
643
684
  /**
644
685
  * Version number for optimistic concurrency control
645
686
  */
646
- export type Version6 = number;
687
+ export type Version7 = number;
647
688
  /**
648
689
  * UUID of the source transaction in the link.
649
690
  */
@@ -652,10 +693,14 @@ export type SourceTransactionID = string;
652
693
  * UUID of the destination transaction in the link.
653
694
  */
654
695
  export type DestinationTransactionID = string;
696
+ /**
697
+ * Whether the linked transactions are expected to have matching signs. When false, the linked transactions are expected to have opposite signs.
698
+ */
699
+ export type IsSameSign1 = boolean;
655
700
  /**
656
701
  * Defines a split within a transaction.
657
702
  */
658
- export type TransactionSplit = Common7 & {
703
+ export type TransactionSplit = Common8 & {
659
704
  transactionId: TransactionID;
660
705
  amount: Amount2;
661
706
  categoryId: CategoryID2;
@@ -665,23 +710,23 @@ export type TransactionSplit = Common7 & {
665
710
  /**
666
711
  * UUID for the item
667
712
  */
668
- export type ID7 = string;
713
+ export type ID8 = string;
669
714
  /**
670
715
  * The timestamp of the creation of the item
671
716
  */
672
- export type DateCreated7 = string;
717
+ export type DateCreated8 = string;
673
718
  /**
674
719
  * The timestamp of the last update or null if the item has not been updated yet
675
720
  */
676
- export type LastUpdated7 = string | null;
721
+ export type LastUpdated8 = string | null;
677
722
  /**
678
723
  * The timestamp of when the item was soft-deleted
679
724
  */
680
- export type DateDeleted7 = string | null;
725
+ export type DateDeleted8 = string | null;
681
726
  /**
682
727
  * Version number for optimistic concurrency control
683
728
  */
684
- export type Version7 = number;
729
+ export type Version8 = number;
685
730
  /**
686
731
  * The identifier of the parent transaction.
687
732
  */
@@ -731,6 +776,10 @@ export interface LucaSchema {
731
776
  * List of recurring transaction events
732
777
  */
733
778
  recurringTransactionEvents: RecurringTransactionEvent[];
779
+ /**
780
+ * List of links between related recurring transactions
781
+ */
782
+ recurringTransactionLinks?: RecurringTransactionLink[];
734
783
  /**
735
784
  * List of transactions
736
785
  */
@@ -824,6 +873,16 @@ export interface Common7 {
824
873
  deletedAt?: DateDeleted7;
825
874
  version?: Version7;
826
875
  }
876
+ /**
877
+ * Common properties for all schemas
878
+ */
879
+ export interface Common8 {
880
+ id: ID8;
881
+ createdAt: DateCreated8;
882
+ updatedAt: LastUpdated8;
883
+ deletedAt?: DateDeleted8;
884
+ version?: Version8;
885
+ }
827
886
 
828
887
  /**
829
888
  * Defines recurring financial transactions within the application.
@@ -975,6 +1034,58 @@ export interface Common {
975
1034
  version?: Version;
976
1035
  }
977
1036
 
1037
+ /**
1038
+ * Links two related recurring transactions, such as mirrored transfer schedules recorded in separate accounts.
1039
+ */
1040
+ export type RecurringTransactionLink = Common & {
1041
+ sourceRecurringTransactionId: SourceRecurringTransactionID;
1042
+ destinationRecurringTransactionId: DestinationRecurringTransactionID;
1043
+ isSameSign: IsSameSign;
1044
+ };
1045
+ /**
1046
+ * UUID for the item
1047
+ */
1048
+ export type ID = string;
1049
+ /**
1050
+ * The timestamp of the creation of the item
1051
+ */
1052
+ export type DateCreated = string;
1053
+ /**
1054
+ * The timestamp of the last update or null if the item has not been updated yet
1055
+ */
1056
+ export type LastUpdated = string | null;
1057
+ /**
1058
+ * The timestamp of when the item was soft-deleted
1059
+ */
1060
+ export type DateDeleted = string | null;
1061
+ /**
1062
+ * Version number for optimistic concurrency control
1063
+ */
1064
+ export type Version = number;
1065
+ /**
1066
+ * UUID of the source recurring transaction in the link.
1067
+ */
1068
+ export type SourceRecurringTransactionID = string;
1069
+ /**
1070
+ * UUID of the destination recurring transaction in the link.
1071
+ */
1072
+ export type DestinationRecurringTransactionID = string;
1073
+ /**
1074
+ * Whether the linked recurring transactions are expected to have matching signs. When false, the linked recurring transactions are expected to have opposite signs.
1075
+ */
1076
+ export type IsSameSign = boolean;
1077
+
1078
+ /**
1079
+ * Common properties for all schemas
1080
+ */
1081
+ export interface Common {
1082
+ id: ID;
1083
+ createdAt: DateCreated;
1084
+ updatedAt: LastUpdated;
1085
+ deletedAt?: DateDeleted;
1086
+ version?: Version;
1087
+ }
1088
+
978
1089
  /**
979
1090
  * Defines the schema for credit card statements.
980
1091
  */
@@ -1161,6 +1272,7 @@ export interface Common {
1161
1272
  export type TransactionLink = Common & {
1162
1273
  sourceTransactionId: SourceTransactionID;
1163
1274
  destinationTransactionId: DestinationTransactionID;
1275
+ isSameSign: IsSameSign;
1164
1276
  };
1165
1277
  /**
1166
1278
  * UUID for the item
@@ -1190,6 +1302,10 @@ export type SourceTransactionID = string;
1190
1302
  * UUID of the destination transaction in the link.
1191
1303
  */
1192
1304
  export type DestinationTransactionID = string;
1305
+ /**
1306
+ * Whether the linked transactions are expected to have matching signs. When false, the linked transactions are expected to have opposite signs.
1307
+ */
1308
+ export type IsSameSign = boolean;
1193
1309
 
1194
1310
  /**
1195
1311
  * Common properties for all schemas
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@luca-financial/luca-schema",
3
- "version": "3.2.0",
3
+ "version": "3.3.1",
4
4
  "description": "Schemas for the Luca Ledger application",
5
5
  "author": "Johnathan Aspinwall",
6
6
  "main": "dist/esm/index.js",