@artu-ai/compliance-sdk 0.4.1 → 0.4.2

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 (110) hide show
  1. package/package.json +3 -4
  2. package/src/errors/api.ts +0 -305
  3. package/src/errors/base.ts +0 -127
  4. package/src/errors/index.ts +0 -63
  5. package/src/errors/upload.ts +0 -204
  6. package/src/errors/validation.ts +0 -163
  7. package/src/exports/base.ts +0 -139
  8. package/src/exports/index.ts +0 -187
  9. package/src/exports/mexico/actividad-vulnerable/avi.ts +0 -207
  10. package/src/exports/mexico/actividad-vulnerable/jys.ts +0 -214
  11. package/src/exports/mexico/actividad-vulnerable/tsc.ts +0 -202
  12. package/src/exports/mexico/index.ts +0 -215
  13. package/src/models/Address.ts +0 -235
  14. package/src/models/BankAccount.ts +0 -235
  15. package/src/models/Client.ts +0 -363
  16. package/src/models/ContactMethod.ts +0 -197
  17. package/src/models/Document.ts +0 -355
  18. package/src/models/LinkedClient.ts +0 -84
  19. package/src/models/Report.ts +0 -193
  20. package/src/models/ReportItem.ts +0 -211
  21. package/src/models/Transaction.ts +0 -219
  22. package/src/models/base.ts +0 -56
  23. package/src/models/index.ts +0 -148
  24. package/src/models/mex/MexAddress.ts +0 -184
  25. package/src/models/mex/MexBankAccount.ts +0 -121
  26. package/src/models/mex/MexClient.ts +0 -177
  27. package/src/models/mex/MexDocument.ts +0 -890
  28. package/src/models/mex/MexReport.ts +0 -99
  29. package/src/models/mex/MexReportItem.ts +0 -79
  30. package/src/models/mex/MexTransaction.ts +0 -105
  31. package/src/models/mex/actividad-vulnerable/MexActividadVulnerableClient.ts +0 -66
  32. package/src/models/mex/actividad-vulnerable/MexActividadVulnerableReport.ts +0 -73
  33. package/src/models/mex/actividad-vulnerable/MexActividadVulnerableReportItem.ts +0 -74
  34. package/src/models/mex/actividad-vulnerable/MexActividadVulnerableTransaction.ts +0 -50
  35. package/src/models/mex/actividad-vulnerable/avi/MexAVIClient.ts +0 -80
  36. package/src/models/mex/actividad-vulnerable/avi/MexAVIReport.ts +0 -114
  37. package/src/models/mex/actividad-vulnerable/avi/MexAVIReportItem.ts +0 -105
  38. package/src/models/mex/actividad-vulnerable/avi/MexAVITransaction.ts +0 -157
  39. package/src/models/mex/actividad-vulnerable/index.ts +0 -78
  40. package/src/models/mex/actividad-vulnerable/jys/MexJYSClient.ts +0 -73
  41. package/src/models/mex/actividad-vulnerable/jys/MexJYSReport.ts +0 -114
  42. package/src/models/mex/actividad-vulnerable/jys/MexJYSReportItem.ts +0 -105
  43. package/src/models/mex/actividad-vulnerable/jys/MexJYSTransaction.ts +0 -178
  44. package/src/models/mex/actividad-vulnerable/tsc/MexTSCClient.ts +0 -73
  45. package/src/models/mex/actividad-vulnerable/tsc/MexTSCReport.ts +0 -114
  46. package/src/models/mex/actividad-vulnerable/tsc/MexTSCReportItem.ts +0 -105
  47. package/src/models/mex/actividad-vulnerable/tsc/MexTSCTransaction.ts +0 -104
  48. package/src/models/mex/index.ts +0 -57
  49. package/src/models/types.ts +0 -196
  50. package/src/namespaces/index.ts +0 -29
  51. package/src/namespaces/mexico/actividad-vulnerable/avi/index.ts +0 -62
  52. package/src/namespaces/mexico/actividad-vulnerable/index.ts +0 -79
  53. package/src/namespaces/mexico/actividad-vulnerable/jys/index.ts +0 -72
  54. package/src/namespaces/mexico/actividad-vulnerable/tsc/index.ts +0 -60
  55. package/src/namespaces/mexico/index.ts +0 -325
  56. package/src/resources/addresses.ts +0 -391
  57. package/src/resources/bank-accounts.ts +0 -417
  58. package/src/resources/base.ts +0 -327
  59. package/src/resources/clients.ts +0 -808
  60. package/src/resources/contact-methods.ts +0 -412
  61. package/src/resources/documents.ts +0 -688
  62. package/src/resources/index.ts +0 -40
  63. package/src/resources/mex/actividad-vulnerable/avi/clients.ts +0 -559
  64. package/src/resources/mex/actividad-vulnerable/avi/index.ts +0 -7
  65. package/src/resources/mex/actividad-vulnerable/avi/reports.ts +0 -609
  66. package/src/resources/mex/actividad-vulnerable/avi/transactions.ts +0 -404
  67. package/src/resources/mex/actividad-vulnerable/index.ts +0 -12
  68. package/src/resources/mex/actividad-vulnerable/jys/clients.ts +0 -445
  69. package/src/resources/mex/actividad-vulnerable/jys/index.ts +0 -7
  70. package/src/resources/mex/actividad-vulnerable/jys/reports.ts +0 -591
  71. package/src/resources/mex/actividad-vulnerable/jys/transactions.ts +0 -395
  72. package/src/resources/mex/actividad-vulnerable/tsc/clients.ts +0 -445
  73. package/src/resources/mex/actividad-vulnerable/tsc/index.ts +0 -7
  74. package/src/resources/mex/actividad-vulnerable/tsc/reports.ts +0 -591
  75. package/src/resources/mex/actividad-vulnerable/tsc/transactions.ts +0 -404
  76. package/src/resources/mex/addresses.ts +0 -493
  77. package/src/resources/mex/bank-accounts.ts +0 -283
  78. package/src/resources/mex/clients.ts +0 -758
  79. package/src/resources/mex/ebr.ts +0 -621
  80. package/src/resources/mex/index.ts +0 -23
  81. package/src/resources/mex/reports.ts +0 -643
  82. package/src/resources/mex/transactions.ts +0 -422
  83. package/src/resources/reports.ts +0 -515
  84. package/src/resources/transactions.ts +0 -358
  85. package/src/sdk/ComplianceSDK.ts +0 -812
  86. package/src/sdk/base.ts +0 -43
  87. package/src/sdk/index.ts +0 -98
  88. package/src/sdk/mex/ComplianceSDK.ts +0 -147
  89. package/src/sdk/mex/actividad-vulnerable/avi/ComplianceSDK.ts +0 -55
  90. package/src/sdk/mex/actividad-vulnerable/avi/index.ts +0 -16
  91. package/src/sdk/mex/actividad-vulnerable/avi/types.ts +0 -86
  92. package/src/sdk/mex/actividad-vulnerable/index.ts +0 -58
  93. package/src/sdk/mex/actividad-vulnerable/jys/ComplianceSDK.ts +0 -54
  94. package/src/sdk/mex/actividad-vulnerable/jys/index.ts +0 -16
  95. package/src/sdk/mex/actividad-vulnerable/jys/types.ts +0 -86
  96. package/src/sdk/mex/actividad-vulnerable/tsc/ComplianceSDK.ts +0 -54
  97. package/src/sdk/mex/actividad-vulnerable/tsc/index.ts +0 -16
  98. package/src/sdk/mex/actividad-vulnerable/tsc/types.ts +0 -86
  99. package/src/sdk/mex/index.ts +0 -66
  100. package/src/sdk/mex/types.ts +0 -88
  101. package/src/sdk/resource-registry.ts +0 -204
  102. package/src/sdk/sdk-registry.ts +0 -99
  103. package/src/sdk/types.ts +0 -304
  104. package/src/utils/environment.ts +0 -187
  105. package/src/utils/filters.ts +0 -412
  106. package/src/utils/index.ts +0 -134
  107. package/src/utils/pagination.ts +0 -143
  108. package/src/utils/session.ts +0 -303
  109. package/src/utils/trpc-client.ts +0 -242
  110. package/src/utils/upload.ts +0 -388
@@ -1,355 +0,0 @@
1
- /**
2
- * Document model
3
- *
4
- * Represents a file uploaded for a client.
5
- * Supports jurisdiction-specific document types (MX, US).
6
- */
7
-
8
- import { BaseModel } from "./base";
9
- import {
10
- DocumentStatus,
11
- DocumentCategory,
12
- Jurisdiction,
13
- type DocumentResponse,
14
- } from "@artu-ai/shared";
15
-
16
- // ─────────────────────────────────────────────────────────────────
17
- // Types
18
- // ─────────────────────────────────────────────────────────────────
19
-
20
- /**
21
- * Document data as returned by the API.
22
- * Uses the centralized type from @artu-ai/shared.
23
- */
24
- export type DocumentData = DocumentResponse;
25
-
26
- // ─────────────────────────────────────────────────────────────────
27
- // Document Model
28
- // ─────────────────────────────────────────────────────────────────
29
-
30
- /**
31
- * Document model - represents an uploaded file.
32
- *
33
- * @example
34
- * ```typescript
35
- * const doc = await sdk.documents.retrieve("doc_123");
36
- *
37
- * console.log(doc.filename); // "passport.pdf"
38
- * console.log(doc.formattedSize); // "2.5 MB"
39
- * console.log(doc.isAvailable); // true
40
- *
41
- * if (doc.isMexico) {
42
- * console.log(doc.type); // "ine_front" | "rfc" | etc.
43
- * }
44
- * ```
45
- */
46
- export class Document extends BaseModel<DocumentData> {
47
- // ─────────────────────────────────────────────────────────────────
48
- // Core Properties
49
- // ─────────────────────────────────────────────────────────────────
50
-
51
- /**
52
- * Unique identifier for the document
53
- */
54
- get id(): string {
55
- return this._data.id;
56
- }
57
-
58
- /**
59
- * ID of the client this document belongs to
60
- */
61
- get clientId(): string {
62
- return this._data.clientId;
63
- }
64
-
65
- /**
66
- * Jurisdiction for this document (MX, US)
67
- */
68
- get jurisdiction(): Jurisdiction {
69
- return this._data.jurisdiction;
70
- }
71
-
72
- /**
73
- * Document type (jurisdiction-specific)
74
- */
75
- get type(): string {
76
- return this._data.type;
77
- }
78
-
79
- /**
80
- * Document category (identity, address, financial, etc.)
81
- */
82
- get category(): DocumentCategory {
83
- return this._data.category;
84
- }
85
-
86
- /**
87
- * Document status
88
- */
89
- get status(): DocumentStatus {
90
- return this._data.status;
91
- }
92
-
93
- // ─────────────────────────────────────────────────────────────────
94
- // File Properties
95
- // ─────────────────────────────────────────────────────────────────
96
-
97
- /**
98
- * Whether a file is attached to this document
99
- */
100
- get hasFile(): boolean {
101
- return !!this._data.filename;
102
- }
103
-
104
- /**
105
- * Original filename (undefined if no file attached)
106
- */
107
- get filename(): string | undefined {
108
- return this._data.filename ?? undefined;
109
- }
110
-
111
- /**
112
- * MIME content type (undefined if no file attached)
113
- */
114
- get contentType(): string | undefined {
115
- return this._data.contentType ?? undefined;
116
- }
117
-
118
- /**
119
- * File size in bytes (undefined if no file attached)
120
- */
121
- get size(): number | undefined {
122
- return this._data.size ?? undefined;
123
- }
124
-
125
- /**
126
- * Human-readable file size (e.g., "2.5 MB")
127
- * Returns undefined if no file attached
128
- */
129
- get formattedSize(): string | undefined {
130
- if (this._data.size === undefined || this._data.size === null)
131
- return undefined;
132
- return formatBytes(this._data.size);
133
- }
134
-
135
- /**
136
- * File extension derived from filename
137
- * Returns empty string if no file or no extension
138
- */
139
- get extension(): string {
140
- if (!this.filename) return "";
141
- const parts = this.filename.split(".");
142
- const ext = parts.at(-1);
143
- if (!ext || parts.length <= 1) return "";
144
- return ext.toLowerCase();
145
- }
146
-
147
- // ─────────────────────────────────────────────────────────────────
148
- // Status Helpers
149
- // ─────────────────────────────────────────────────────────────────
150
-
151
- /**
152
- * Whether the document is ready for download
153
- */
154
- get isAvailable(): boolean {
155
- return (
156
- this.status === DocumentStatus.Uploaded ||
157
- this.status === DocumentStatus.Verified
158
- );
159
- }
160
-
161
- /**
162
- * Whether the document is pending upload
163
- */
164
- get isPending(): boolean {
165
- return this.status === DocumentStatus.PendingUpload;
166
- }
167
-
168
- /**
169
- * Whether the document has been verified
170
- */
171
- get isVerified(): boolean {
172
- return this.status === DocumentStatus.Verified;
173
- }
174
-
175
- /**
176
- * Whether the document was rejected
177
- */
178
- get isRejected(): boolean {
179
- return this.status === DocumentStatus.Rejected;
180
- }
181
-
182
- /**
183
- * Whether the document has expired
184
- */
185
- get isExpired(): boolean {
186
- if (this.status === DocumentStatus.Expired) return true;
187
- if (!this._data.expiresAt) return false;
188
- return new Date(this._data.expiresAt) < new Date();
189
- }
190
-
191
- // ─────────────────────────────────────────────────────────────────
192
- // Validity
193
- // ─────────────────────────────────────────────────────────────────
194
-
195
- /**
196
- * Document expiration date, if set
197
- */
198
- get expiresAt(): Date | undefined {
199
- return this._data.expiresAt ? new Date(this._data.expiresAt) : undefined;
200
- }
201
-
202
- /**
203
- * Days until document expires (negative if already expired)
204
- */
205
- get daysUntilExpiry(): number | undefined {
206
- if (!this.expiresAt) return undefined;
207
- const now = new Date();
208
- const diffTime = this.expiresAt.getTime() - now.getTime();
209
- return Math.ceil(diffTime / (1000 * 60 * 60 * 24));
210
- }
211
-
212
- // ─────────────────────────────────────────────────────────────────
213
- // Fields
214
- // ─────────────────────────────────────────────────────────────────
215
-
216
- /**
217
- * Document-specific fields (extracted or provided data)
218
- *
219
- * For typed fields, use jurisdiction-specific document models:
220
- * - MexIneFrontDocument.ineFields
221
- * - MexPassportDocument.passportFields
222
- * - etc.
223
- */
224
- get fields(): Record<string, unknown> | undefined {
225
- return (this._data as DocumentData & { fields?: Record<string, unknown> })
226
- .fields;
227
- }
228
-
229
- /**
230
- * Get a specific field value
231
- */
232
- getField<T = unknown>(key: string): T | undefined {
233
- return this.fields?.[key] as T | undefined;
234
- }
235
-
236
- // ─────────────────────────────────────────────────────────────────
237
- // Metadata
238
- // ─────────────────────────────────────────────────────────────────
239
-
240
- /**
241
- * External ID
242
- */
243
- get externalId(): string | undefined {
244
- return this._data.externalId ?? undefined;
245
- }
246
-
247
- /**
248
- * Custom metadata attached to the document
249
- */
250
- get metadata(): Record<string, unknown> | undefined {
251
- return this._data.metadata;
252
- }
253
-
254
- /**
255
- * Get a specific metadata value
256
- */
257
- getMetadata<T = unknown>(key: string): T | undefined {
258
- return this.metadata?.[key] as T | undefined;
259
- }
260
-
261
- // ─────────────────────────────────────────────────────────────────
262
- // Timestamps
263
- // ─────────────────────────────────────────────────────────────────
264
-
265
- /**
266
- * When the document was created
267
- */
268
- get createdAt(): Date {
269
- return new Date(this._data.createdAt);
270
- }
271
-
272
- /**
273
- * When the document was last updated
274
- */
275
- get updatedAt(): Date {
276
- return new Date(this._data.updatedAt);
277
- }
278
-
279
- // ─────────────────────────────────────────────────────────────────
280
- // Jurisdiction Type Guards
281
- // ─────────────────────────────────────────────────────────────────
282
-
283
- /**
284
- * Whether this is a Mexico document
285
- */
286
- get isMexico(): boolean {
287
- return this._data.jurisdiction === Jurisdiction.Mexico;
288
- }
289
-
290
- // ─────────────────────────────────────────────────────────────────
291
- // Category Helpers
292
- // ─────────────────────────────────────────────────────────────────
293
-
294
- /**
295
- * Whether this is an identity document
296
- */
297
- get isIdentityDocument(): boolean {
298
- return this.category === DocumentCategory.Identity;
299
- }
300
-
301
- /**
302
- * Whether this is an address proof document
303
- */
304
- get isAddressProof(): boolean {
305
- return this.category === DocumentCategory.Address;
306
- }
307
-
308
- /**
309
- * Whether this is a financial document
310
- */
311
- get isFinancialDocument(): boolean {
312
- return this.category === DocumentCategory.Financial;
313
- }
314
-
315
- /**
316
- * Whether this is an incorporation document
317
- */
318
- get isIncorporationDocument(): boolean {
319
- return this.category === DocumentCategory.Incorporation;
320
- }
321
-
322
- /**
323
- * Whether this is a tax document
324
- */
325
- get isTaxDocument(): boolean {
326
- return this.category === DocumentCategory.Tax;
327
- }
328
- }
329
-
330
- // ─────────────────────────────────────────────────────────────────
331
- // Helpers
332
- // ─────────────────────────────────────────────────────────────────
333
-
334
- /**
335
- * Format bytes into human-readable string
336
- */
337
- function formatBytes(bytes: number): string {
338
- if (bytes === 0) return "0 bytes";
339
-
340
- const units = ["bytes", "KB", "MB", "GB"];
341
- let size = bytes;
342
- let unitIndex = 0;
343
-
344
- while (size >= 1024 && unitIndex < units.length - 1) {
345
- size /= 1024;
346
- unitIndex++;
347
- }
348
-
349
- // Show decimals only for KB and larger
350
- if (unitIndex === 0) {
351
- return `${size} ${units[unitIndex]}`;
352
- }
353
-
354
- return `${size.toFixed(1)} ${units[unitIndex]}`;
355
- }
@@ -1,84 +0,0 @@
1
- /**
2
- * LinkedClient Model
3
- *
4
- * Represents a client-to-client relationship with metadata.
5
- */
6
-
7
- import type { ClientRelationshipType, LinkedClientResponse } from "@artu-ai/shared";
8
- import { BaseModel } from "./base";
9
- import { Client, type ClientData } from "./Client";
10
-
11
- /**
12
- * Data structure for linked client.
13
- */
14
- export type LinkedClientData = LinkedClientResponse;
15
-
16
- /**
17
- * LinkedClient model class.
18
- *
19
- * Provides typed access to linked client data including:
20
- * - Relationship type (legal_representative, controlling_beneficiary, etc.)
21
- * - The linked client
22
- * - Metadata for the relationship
23
- * - Timestamps
24
- *
25
- * @example
26
- * ```typescript
27
- * const linkedClients = await sdk.clients.listLinkedClients(companyId);
28
- * for (const linkedClient of linkedClients) {
29
- * console.log(linkedClient.id, linkedClient.relationshipType);
30
- * console.log(linkedClient.client.name);
31
- * console.log(linkedClient.metadata);
32
- * }
33
- * ```
34
- */
35
- export class LinkedClient extends BaseModel<LinkedClientData> {
36
- /**
37
- * Unique identifier for this relationship
38
- */
39
- get id(): string {
40
- return this._data.id;
41
- }
42
-
43
- /**
44
- * Type of relationship between the parent and child client.
45
- */
46
- get relationshipType(): ClientRelationshipType {
47
- return this._data.relationshipType;
48
- }
49
-
50
- /**
51
- * The linked (child) client.
52
- */
53
- get client(): Client {
54
- return new Client(this._data.client as ClientData);
55
- }
56
-
57
- /**
58
- * Optional metadata for the relationship.
59
- */
60
- get metadata(): Record<string, unknown> | undefined {
61
- return this._data.metadata;
62
- }
63
-
64
- /**
65
- * When the relationship was created.
66
- */
67
- get createdAt(): string {
68
- return this._data.createdAt;
69
- }
70
-
71
- /**
72
- * When the relationship was last updated.
73
- */
74
- get updatedAt(): string {
75
- return this._data.updatedAt;
76
- }
77
- }
78
-
79
- /**
80
- * Type guard for LinkedClient model.
81
- */
82
- export function isLinkedClient(obj: unknown): obj is LinkedClient {
83
- return obj instanceof LinkedClient;
84
- }
@@ -1,193 +0,0 @@
1
- /**
2
- * Base Report Model
3
- *
4
- * Pure data model with no API calls.
5
- * Provides type-safe access to common report properties.
6
- */
7
-
8
- import { BaseModel } from "./base";
9
- import { ReportStatus } from "@artu-ai/shared";
10
- import type { BaseReport, Report as ReportSchema } from "@artu-ai/shared";
11
-
12
- // ===========================
13
- // Types
14
- // ===========================
15
-
16
- /**
17
- * Report data as returned from the API.
18
- */
19
- export type ReportData = ReportSchema;
20
-
21
- // ===========================
22
- // Report Model
23
- // ===========================
24
-
25
- /**
26
- * Base Report Model.
27
- *
28
- * Pure data model with no API calls.
29
- * Extended by jurisdiction-specific models (MexReport, etc.).
30
- *
31
- * @example
32
- * ```typescript
33
- * const report = await sdk.reports.retrieve("report_123");
34
- * console.log(report.type);
35
- * console.log(report.status);
36
- * ```
37
- */
38
- export class Report extends BaseModel<ReportData> {
39
- // ─────────────────────────────────────────────────────────────────
40
- // Identity
41
- // ─────────────────────────────────────────────────────────────────
42
-
43
- /**
44
- * Unique identifier
45
- */
46
- get id(): string {
47
- return this._data.id;
48
- }
49
-
50
- /**
51
- * Organization ID
52
- */
53
- get organizationId(): string {
54
- return this._data.organizationId;
55
- }
56
-
57
- /**
58
- * Environment (test or live)
59
- */
60
- get environment(): "test" | "live" {
61
- return this._data.environment;
62
- }
63
-
64
- // ─────────────────────────────────────────────────────────────────
65
- // Status
66
- // ─────────────────────────────────────────────────────────────────
67
-
68
- /**
69
- * Report status
70
- */
71
- get status(): ReportStatus {
72
- return this._data.status;
73
- }
74
-
75
- /**
76
- * Number of items in the report
77
- */
78
- get itemCount(): number {
79
- return this._data.itemCount;
80
- }
81
-
82
- /**
83
- * Whether the report is in draft status
84
- */
85
- get isDraft(): boolean {
86
- return this._data.status === ReportStatus.Draft;
87
- }
88
-
89
- /**
90
- * Whether the report has been validated successfully
91
- */
92
- get isValid(): boolean {
93
- return this._data.status === ReportStatus.Valid;
94
- }
95
-
96
- /**
97
- * Whether the report failed validation
98
- */
99
- get isInvalid(): boolean {
100
- return this._data.status === ReportStatus.Invalid;
101
- }
102
-
103
- /**
104
- * Whether the report has been submitted
105
- */
106
- get isSubmitted(): boolean {
107
- return this._data.status === ReportStatus.Submitted;
108
- }
109
-
110
- /**
111
- * Whether the report can be edited
112
- */
113
- get canEdit(): boolean {
114
- return [
115
- ReportStatus.Draft,
116
- ReportStatus.Valid,
117
- ReportStatus.Invalid,
118
- ].includes(this._data.status);
119
- }
120
-
121
- /**
122
- * Whether the report can be validated/generated
123
- */
124
- get canGenerate(): boolean {
125
- return [ReportStatus.Draft, ReportStatus.Valid].includes(this._data.status);
126
- }
127
-
128
- // ─────────────────────────────────────────────────────────────────
129
- // Jurisdiction
130
- // ─────────────────────────────────────────────────────────────────
131
-
132
- /**
133
- * Raw jurisdiction data object
134
- */
135
- get jurisdictions(): BaseReport["jurisdictions"] {
136
- return this._data.jurisdictions ?? {};
137
- }
138
-
139
- // ─────────────────────────────────────────────────────────────────
140
- // Metadata
141
- // ─────────────────────────────────────────────────────────────────
142
-
143
- /**
144
- * External ID for integration with other systems
145
- */
146
- get externalId(): string | undefined {
147
- return this._data.externalId;
148
- }
149
-
150
- /**
151
- * Custom metadata
152
- */
153
- get metadata(): Record<string, unknown> | undefined {
154
- return this._data.metadata;
155
- }
156
-
157
- // ─────────────────────────────────────────────────────────────────
158
- // Timestamps
159
- // ─────────────────────────────────────────────────────────────────
160
-
161
- /**
162
- * When the report was created
163
- */
164
- get createdAt(): Date {
165
- return new Date(this._data.createdAt);
166
- }
167
-
168
- /**
169
- * When the report was last updated
170
- */
171
- get updatedAt(): Date {
172
- return new Date(this._data.updatedAt);
173
- }
174
-
175
- // ─────────────────────────────────────────────────────────────────
176
- // String Representation
177
- // ─────────────────────────────────────────────────────────────────
178
-
179
- override toString(): string {
180
- return `Report(${this.id}, ${this.status})`;
181
- }
182
- }
183
-
184
- // ===========================
185
- // Type Guards
186
- // ===========================
187
-
188
- /**
189
- * Check if value is any type of Report model
190
- */
191
- export function isReport(value: unknown): value is Report {
192
- return value instanceof Report;
193
- }