@fintekkers/ledger-models 0.4.4 → 0.4.5

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/jest.config.js CHANGED
@@ -1,4 +1,14 @@
1
1
  module.exports = {
2
2
  preset: 'ts-jest',
3
- testMatch: ["**/*.test.ts"]
4
- };
3
+ testMatch: ["**/*.test.ts"],
4
+ // Exclude service-tier tests that connect to gRPC (price-service,
5
+ // transaction-service, security-service, position-service,
6
+ // portfolio-service). They pass locally where services are up
7
+ // and fail in CI with `UNAVAILABLE: No connection established`.
8
+ // Run via `npm run test:integration` against a separate config.
9
+ // See processes/test-discipline.md.
10
+ testPathIgnorePatterns: [
11
+ "/node_modules/",
12
+ "node/wrappers/services/[^/]+/.+\\.test\\.ts$",
13
+ ],
14
+ };
@@ -0,0 +1,6 @@
1
+ module.exports = {
2
+ preset: 'ts-jest',
3
+ // Only the gRPC-touching service-tier tests. Requires real
4
+ // services running. See processes/test-discipline.md.
5
+ testMatch: ["**/node/wrappers/services/*/*.test.ts"],
6
+ };
@@ -54,11 +54,6 @@ export class SecurityProto extends jspb.Message {
54
54
  getLegsList(): Array<SecurityProto>;
55
55
  setLegsList(value: Array<SecurityProto>): SecurityProto;
56
56
  addLegs(value?: SecurityProto, index?: number): SecurityProto;
57
-
58
- hasDeletedAt(): boolean;
59
- clearDeletedAt(): void;
60
- getDeletedAt(): fintekkers_models_util_local_timestamp_pb.LocalTimestampProto | undefined;
61
- setDeletedAt(value?: fintekkers_models_util_local_timestamp_pb.LocalTimestampProto): SecurityProto;
62
57
  getAssetClass(): string;
63
58
  setAssetClass(value: string): SecurityProto;
64
59
  getIssuerName(): string;
@@ -141,7 +136,6 @@ export namespace SecurityProto {
141
136
  productType: fintekkers_models_security_product_type_pb.ProductTypeProto,
142
137
  instrumentType: fintekkers_models_security_instrument_type_pb.InstrumentTypeProto,
143
138
  legsList: Array<SecurityProto.AsObject>,
144
- deletedAt?: fintekkers_models_util_local_timestamp_pb.LocalTimestampProto.AsObject,
145
139
  assetClass: string,
146
140
  issuerName: string,
147
141
  settlementCurrency?: SecurityProto.AsObject,
@@ -324,7 +324,6 @@ proto.fintekkers.models.security.SecurityProto.toObject = function(includeInstan
324
324
  instrumentType: jspb.Message.getFieldWithDefault(msg, 16, 0),
325
325
  legsList: jspb.Message.toObjectList(msg.getLegsList(),
326
326
  proto.fintekkers.models.security.SecurityProto.toObject, includeInstance),
327
- deletedAt: (f = msg.getDeletedAt()) && fintekkers_models_util_local_timestamp_pb.LocalTimestampProto.toObject(includeInstance, f),
328
327
  assetClass: jspb.Message.getFieldWithDefault(msg, 11, ""),
329
328
  issuerName: jspb.Message.getFieldWithDefault(msg, 12, ""),
330
329
  settlementCurrency: (f = msg.getSettlementCurrency()) && proto.fintekkers.models.security.SecurityProto.toObject(includeInstance, f),
@@ -421,11 +420,6 @@ proto.fintekkers.models.security.SecurityProto.deserializeBinaryFromReader = fun
421
420
  reader.readMessage(value,proto.fintekkers.models.security.SecurityProto.deserializeBinaryFromReader);
422
421
  msg.addLegs(value);
423
422
  break;
424
- case 15:
425
- var value = new fintekkers_models_util_local_timestamp_pb.LocalTimestampProto;
426
- reader.readMessage(value,fintekkers_models_util_local_timestamp_pb.LocalTimestampProto.deserializeBinaryFromReader);
427
- msg.setDeletedAt(value);
428
- break;
429
423
  case 11:
430
424
  var value = /** @type {string} */ (reader.readString());
431
425
  msg.setAssetClass(value);
@@ -596,14 +590,6 @@ proto.fintekkers.models.security.SecurityProto.serializeBinaryToWriter = functio
596
590
  proto.fintekkers.models.security.SecurityProto.serializeBinaryToWriter
597
591
  );
598
592
  }
599
- f = message.getDeletedAt();
600
- if (f != null) {
601
- writer.writeMessage(
602
- 15,
603
- f,
604
- fintekkers_models_util_local_timestamp_pb.LocalTimestampProto.serializeBinaryToWriter
605
- );
606
- }
607
593
  f = message.getAssetClass();
608
594
  if (f.length > 0) {
609
595
  writer.writeString(
@@ -991,43 +977,6 @@ proto.fintekkers.models.security.SecurityProto.prototype.clearLegsList = functio
991
977
  };
992
978
 
993
979
 
994
- /**
995
- * optional fintekkers.models.util.LocalTimestampProto deleted_at = 15;
996
- * @return {?proto.fintekkers.models.util.LocalTimestampProto}
997
- */
998
- proto.fintekkers.models.security.SecurityProto.prototype.getDeletedAt = function() {
999
- return /** @type{?proto.fintekkers.models.util.LocalTimestampProto} */ (
1000
- jspb.Message.getWrapperField(this, fintekkers_models_util_local_timestamp_pb.LocalTimestampProto, 15));
1001
- };
1002
-
1003
-
1004
- /**
1005
- * @param {?proto.fintekkers.models.util.LocalTimestampProto|undefined} value
1006
- * @return {!proto.fintekkers.models.security.SecurityProto} returns this
1007
- */
1008
- proto.fintekkers.models.security.SecurityProto.prototype.setDeletedAt = function(value) {
1009
- return jspb.Message.setWrapperField(this, 15, value);
1010
- };
1011
-
1012
-
1013
- /**
1014
- * Clears the message field making it undefined.
1015
- * @return {!proto.fintekkers.models.security.SecurityProto} returns this
1016
- */
1017
- proto.fintekkers.models.security.SecurityProto.prototype.clearDeletedAt = function() {
1018
- return this.setDeletedAt(undefined);
1019
- };
1020
-
1021
-
1022
- /**
1023
- * Returns whether this field is set.
1024
- * @return {boolean}
1025
- */
1026
- proto.fintekkers.models.security.SecurityProto.prototype.hasDeletedAt = function() {
1027
- return jspb.Message.getField(this, 15) != null;
1028
- };
1029
-
1030
-
1031
980
  /**
1032
981
  * optional string asset_class = 11;
1033
982
  * @return {string}
@@ -138,6 +138,19 @@ declare class Security {
138
138
  */
139
139
  protected getBondLikeDetails(): any | undefined;
140
140
  getIssuerName(): string;
141
+ /**
142
+ * Time-based soft-delete check. A Security is considered deleted iff it
143
+ * carries a `valid_to` that has already elapsed at `asOf`. A future-dated
144
+ * `valid_to` means the row is still live today and becomes deleted
145
+ * automatically when `asOf` catches up. An unset `valid_to` is always
146
+ * active.
147
+ *
148
+ * Canonical soft-delete check across the platform — the predecessor
149
+ * `SecurityProto.deleted_at` field has been removed (tag 15 reserved).
150
+ * See /specs/soft-delete-validto-collapse.md
151
+ * (FinTekkers/second-brain#316).
152
+ */
153
+ isDeleted(asOf?: Date): boolean;
141
154
  equals(other: Security): boolean;
142
155
  }
143
156
  export default Security;
@@ -0,0 +1,89 @@
1
+ "use strict";
2
+ // Time-based soft-delete tests for the Security wrapper.
3
+ //
4
+ // Phase A of /specs/soft-delete-validto-collapse.md
5
+ // (FinTekkers/second-brain#316). The SecurityProto.deleted_at field has been
6
+ // removed (tag 15 reserved). The single canonical soft-delete check is
7
+ // Security.isDeleted(asOf), which honours valid_to with a time-based
8
+ // comparison.
9
+ var __importDefault = (this && this.__importDefault) || function (mod) {
10
+ return (mod && mod.__esModule) ? mod : { "default": mod };
11
+ };
12
+ Object.defineProperty(exports, "__esModule", { value: true });
13
+ const security_1 = __importDefault(require("./security"));
14
+ const security_pb_1 = require("../../../fintekkers/models/security/security_pb");
15
+ const local_timestamp_pb_1 = require("../../../fintekkers/models/util/local_timestamp_pb");
16
+ const timestamp_pb_1 = require("google-protobuf/google/protobuf/timestamp_pb");
17
+ function localTimestamp(seconds) {
18
+ const ts = new timestamp_pb_1.Timestamp();
19
+ ts.setSeconds(seconds);
20
+ ts.setNanos(0);
21
+ const lt = new local_timestamp_pb_1.LocalTimestampProto();
22
+ lt.setTimestamp(ts);
23
+ lt.setTimeZone('UTC');
24
+ return lt;
25
+ }
26
+ function securityWithValidTo(seconds) {
27
+ const proto = new security_pb_1.SecurityProto();
28
+ if (seconds !== null) {
29
+ proto.setValidTo(localTimestamp(seconds));
30
+ }
31
+ return new security_1.default(proto);
32
+ }
33
+ describe('Security.isDeleted (Phase A — validTo time-based check)', () => {
34
+ test('null validTo is never deleted', () => {
35
+ const sec = securityWithValidTo(null);
36
+ expect(sec.isDeleted()).toBe(false);
37
+ expect(sec.isDeleted(new Date('2999-01-01T00:00:00Z'))).toBe(false);
38
+ });
39
+ test('past validTo is deleted now', () => {
40
+ const past = Math.floor(Date.now() / 1000) - 86400; // yesterday
41
+ const sec = securityWithValidTo(past);
42
+ expect(sec.isDeleted()).toBe(true);
43
+ });
44
+ test('future validTo is not yet deleted but becomes deleted when asOf catches up', () => {
45
+ const future = Math.floor(Date.now() / 1000) + 86400; // tomorrow
46
+ const sec = securityWithValidTo(future);
47
+ expect(sec.isDeleted()).toBe(false);
48
+ const later = new Date((future + 1) * 1000);
49
+ expect(sec.isDeleted(later)).toBe(true);
50
+ });
51
+ test('asOf parameter switches the answer', () => {
52
+ // validTo fixed at 2026-01-01 UTC
53
+ const cutoff = Math.floor(Date.UTC(2026, 0, 1) / 1000);
54
+ const sec = securityWithValidTo(cutoff);
55
+ expect(sec.isDeleted(new Date(Date.UTC(2025, 5, 1)))).toBe(false);
56
+ expect(sec.isDeleted(new Date(Date.UTC(2026, 5, 1)))).toBe(true);
57
+ });
58
+ test('proto round-trip with legacy deleted_at bytes is silently dropped', () => {
59
+ // Build canonical bytes then append a tag-15 LocalTimestampProto.
60
+ // proto3 must ignore unknown fields; tag 15 is reserved on the new
61
+ // schema so the value is dropped. See spec §4.2.
62
+ const base = new security_pb_1.SecurityProto();
63
+ base.setIssuerName('legacy-issuer');
64
+ const canonical = base.serializeBinary();
65
+ // Inner Timestamp: field 1 (seconds), varint, value=1700000000
66
+ // key = (1<<3)|0 = 0x08
67
+ const innerTs = [0x08];
68
+ let v = 1700000000;
69
+ while (v >= 0x80) {
70
+ innerTs.push((v & 0x7F) | 0x80);
71
+ v >>>= 7;
72
+ }
73
+ innerTs.push(v);
74
+ // LocalTimestampProto: field 1 (timestamp), length-delim
75
+ const outer = [0x0A, innerTs.length, ...innerTs];
76
+ // SecurityProto.deleted_at: field 15, length-delim
77
+ // key = (15<<3)|2 = 0x7A
78
+ const legacy = [0x7A, outer.length, ...outer];
79
+ const combined = new Uint8Array(canonical.length + legacy.length);
80
+ combined.set(canonical, 0);
81
+ combined.set(legacy, canonical.length);
82
+ // Must not throw.
83
+ const reparsed = security_pb_1.SecurityProto.deserializeBinary(combined);
84
+ expect(reparsed.getIssuerName()).toBe('legacy-issuer');
85
+ // The legacy tag must NOT be silently mapped onto valid_to.
86
+ expect(reparsed.hasValidTo()).toBe(false);
87
+ });
88
+ });
89
+ //# sourceMappingURL=security.isDeleted.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"security.isDeleted.test.js","sourceRoot":"","sources":["security.isDeleted.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,96 @@
1
+ // Time-based soft-delete tests for the Security wrapper.
2
+ //
3
+ // Phase A of /specs/soft-delete-validto-collapse.md
4
+ // (FinTekkers/second-brain#316). The SecurityProto.deleted_at field has been
5
+ // removed (tag 15 reserved). The single canonical soft-delete check is
6
+ // Security.isDeleted(asOf), which honours valid_to with a time-based
7
+ // comparison.
8
+
9
+ import Security from './security';
10
+ import { SecurityProto } from '../../../fintekkers/models/security/security_pb';
11
+ import { LocalTimestampProto } from '../../../fintekkers/models/util/local_timestamp_pb';
12
+ import { Timestamp } from 'google-protobuf/google/protobuf/timestamp_pb';
13
+
14
+ function localTimestamp(seconds: number): LocalTimestampProto {
15
+ const ts = new Timestamp();
16
+ ts.setSeconds(seconds);
17
+ ts.setNanos(0);
18
+ const lt = new LocalTimestampProto();
19
+ lt.setTimestamp(ts);
20
+ lt.setTimeZone('UTC');
21
+ return lt;
22
+ }
23
+
24
+ function securityWithValidTo(seconds: number | null): Security {
25
+ const proto = new SecurityProto();
26
+ if (seconds !== null) {
27
+ proto.setValidTo(localTimestamp(seconds));
28
+ }
29
+ return new Security(proto);
30
+ }
31
+
32
+ describe('Security.isDeleted (Phase A — validTo time-based check)', () => {
33
+ test('null validTo is never deleted', () => {
34
+ const sec = securityWithValidTo(null);
35
+ expect(sec.isDeleted()).toBe(false);
36
+ expect(sec.isDeleted(new Date('2999-01-01T00:00:00Z'))).toBe(false);
37
+ });
38
+
39
+ test('past validTo is deleted now', () => {
40
+ const past = Math.floor(Date.now() / 1000) - 86_400; // yesterday
41
+ const sec = securityWithValidTo(past);
42
+ expect(sec.isDeleted()).toBe(true);
43
+ });
44
+
45
+ test('future validTo is not yet deleted but becomes deleted when asOf catches up', () => {
46
+ const future = Math.floor(Date.now() / 1000) + 86_400; // tomorrow
47
+ const sec = securityWithValidTo(future);
48
+ expect(sec.isDeleted()).toBe(false);
49
+ const later = new Date((future + 1) * 1000);
50
+ expect(sec.isDeleted(later)).toBe(true);
51
+ });
52
+
53
+ test('asOf parameter switches the answer', () => {
54
+ // validTo fixed at 2026-01-01 UTC
55
+ const cutoff = Math.floor(Date.UTC(2026, 0, 1) / 1000);
56
+ const sec = securityWithValidTo(cutoff);
57
+ expect(sec.isDeleted(new Date(Date.UTC(2025, 5, 1)))).toBe(false);
58
+ expect(sec.isDeleted(new Date(Date.UTC(2026, 5, 1)))).toBe(true);
59
+ });
60
+
61
+ test('proto round-trip with legacy deleted_at bytes is silently dropped', () => {
62
+ // Build canonical bytes then append a tag-15 LocalTimestampProto.
63
+ // proto3 must ignore unknown fields; tag 15 is reserved on the new
64
+ // schema so the value is dropped. See spec §4.2.
65
+ const base = new SecurityProto();
66
+ base.setIssuerName('legacy-issuer');
67
+ const canonical = base.serializeBinary();
68
+
69
+ // Inner Timestamp: field 1 (seconds), varint, value=1700000000
70
+ // key = (1<<3)|0 = 0x08
71
+ const innerTs: number[] = [0x08];
72
+ let v = 1_700_000_000;
73
+ while (v >= 0x80) {
74
+ innerTs.push((v & 0x7F) | 0x80);
75
+ v >>>= 7;
76
+ }
77
+ innerTs.push(v);
78
+
79
+ // LocalTimestampProto: field 1 (timestamp), length-delim
80
+ const outer: number[] = [0x0A, innerTs.length, ...innerTs];
81
+
82
+ // SecurityProto.deleted_at: field 15, length-delim
83
+ // key = (15<<3)|2 = 0x7A
84
+ const legacy: number[] = [0x7A, outer.length, ...outer];
85
+
86
+ const combined = new Uint8Array(canonical.length + legacy.length);
87
+ combined.set(canonical, 0);
88
+ combined.set(legacy, canonical.length);
89
+
90
+ // Must not throw.
91
+ const reparsed = SecurityProto.deserializeBinary(combined);
92
+ expect(reparsed.getIssuerName()).toBe('legacy-issuer');
93
+ // The legacy tag must NOT be silently mapped onto valid_to.
94
+ expect(reparsed.hasValidTo()).toBe(false);
95
+ });
96
+ });
@@ -318,6 +318,30 @@ class Security {
318
318
  this.assertNotLink('issuerName');
319
319
  return this.proto.getIssuerName();
320
320
  }
321
+ /**
322
+ * Time-based soft-delete check. A Security is considered deleted iff it
323
+ * carries a `valid_to` that has already elapsed at `asOf`. A future-dated
324
+ * `valid_to` means the row is still live today and becomes deleted
325
+ * automatically when `asOf` catches up. An unset `valid_to` is always
326
+ * active.
327
+ *
328
+ * Canonical soft-delete check across the platform — the predecessor
329
+ * `SecurityProto.deleted_at` field has been removed (tag 15 reserved).
330
+ * See /specs/soft-delete-validto-collapse.md
331
+ * (FinTekkers/second-brain#316).
332
+ */
333
+ isDeleted(asOf = new Date()) {
334
+ if (!this.proto.hasValidTo())
335
+ return false;
336
+ const validToProto = this.proto.getValidTo();
337
+ if (!validToProto)
338
+ return false;
339
+ const ts = validToProto.getTimestamp();
340
+ if (!ts)
341
+ return false;
342
+ const validToMs = ts.getSeconds() * 1000 + Math.floor(ts.getNanos() / 1e6);
343
+ return validToMs < asOf.getTime();
344
+ }
321
345
  equals(other) {
322
346
  if (other instanceof Security) {
323
347
  return this.getID().equals(other.getID());
@@ -1 +1 @@
1
- {"version":3,"file":"security.js","sourceRoot":"","sources":["security.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"security.js","sourceRoot":"","sources":["security.ts"],"names":[],"mappings":"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"}
@@ -348,6 +348,28 @@ class Security {
348
348
  return this.proto.getIssuerName();
349
349
  }
350
350
 
351
+ /**
352
+ * Time-based soft-delete check. A Security is considered deleted iff it
353
+ * carries a `valid_to` that has already elapsed at `asOf`. A future-dated
354
+ * `valid_to` means the row is still live today and becomes deleted
355
+ * automatically when `asOf` catches up. An unset `valid_to` is always
356
+ * active.
357
+ *
358
+ * Canonical soft-delete check across the platform — the predecessor
359
+ * `SecurityProto.deleted_at` field has been removed (tag 15 reserved).
360
+ * See /specs/soft-delete-validto-collapse.md
361
+ * (FinTekkers/second-brain#316).
362
+ */
363
+ isDeleted(asOf: Date = new Date()): boolean {
364
+ if (!this.proto.hasValidTo()) return false;
365
+ const validToProto = this.proto.getValidTo();
366
+ if (!validToProto) return false;
367
+ const ts = validToProto.getTimestamp();
368
+ if (!ts) return false;
369
+ const validToMs = ts.getSeconds() * 1000 + Math.floor(ts.getNanos() / 1e6);
370
+ return validToMs < asOf.getTime();
371
+ }
372
+
351
373
  equals(other: Security): boolean {
352
374
  if (other instanceof Security) {
353
375
  return this.getID().equals(other.getID());
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@fintekkers/ledger-models",
3
3
  "todo": "Replace the version with build script version number",
4
- "version": "0.4.4",
4
+ "version": "0.4.5",
5
5
  "description": "ledger model protos ",
6
6
  "authors": [
7
7
  "David Doherty",
@@ -21,6 +21,7 @@
21
21
  "publishConfigNotes": "This package.json does not have a publish config defining the registry because we currently publish to both Github packages & npmjs, so the registry is in the ../.github/workflows/publish.yml files at runtime",
22
22
  "scripts": {
23
23
  "test": "jest",
24
+ "test:integration": "jest --config jest.integration.config.js",
24
25
  "start": "node index.js"
25
26
  },
26
27
  "devDependencies": {