@abyss-project/tools 1.0.1 → 1.0.3

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.
@@ -7,6 +7,8 @@ export interface IRecentContentItem {
7
7
  title: string;
8
8
  updatedAt: string;
9
9
  createdByUserId: string;
10
+ /** Slug for board navigation (only boards expose a navigable slug). */
11
+ slug?: string;
10
12
  }
11
13
 
12
14
  export interface IRecentOrganizationData {
@@ -1,267 +1,267 @@
1
- // ──────────────────────────────────────────────
2
- // RCB (Relevé de Compte Bancaire) DTOs.
3
- // Mirror server-side Sequelize models, dates serialized as ISO strings.
4
- // ──────────────────────────────────────────────
5
-
6
- export type RcbExtractionMode = 'auto' | 'hint' | 'template';
7
- export type RcbProcessingMode = 'sync' | 'queue';
8
- export type RcbExtractionStatus = 'pending' | 'completed' | 'failed' | 'cached';
9
-
10
- export type RcbFeedbackIssueType =
11
- | 'missing_record'
12
- | 'wrong_sign'
13
- | 'wrong_amount'
14
- | 'wrong_date'
15
- | 'wrong_description'
16
- | 'duplicate'
17
- | 'other';
18
-
19
- export type RcbFeedbackStatus = 'open' | 'triaged' | 'fixed' | 'closed';
20
-
21
- export type RcbUsageEventType =
22
- | 'extract.sync.success'
23
- | 'extract.sync.cached'
24
- | 'extract.sync.failed'
25
- | 'extract.queue.enqueued'
26
- | 'extract.queue.success'
27
- | 'extract.queue.cached'
28
- | 'extract.queue.failed'
29
- | 'template.run.success'
30
- | 'template.run.failed';
31
-
32
- export interface IRcbBankHint {
33
- bank: string;
34
- version?: string;
35
- }
36
-
37
- export interface IRcbTransaction {
38
- date?: string;
39
- description?: string;
40
- amount?: number;
41
- balance?: number;
42
- valueDate?: string;
43
- bookingDate?: string;
44
- reference?: string;
45
- [k: string]: unknown;
46
- }
47
-
48
- export interface IRcbExtractionMetadata {
49
- iban?: string;
50
- bic?: string;
51
- bank?: string;
52
- accountHolder?: string;
53
- periodStart?: string;
54
- periodEnd?: string;
55
- openingBalance?: number;
56
- closingBalance?: number;
57
- currency?: string;
58
- [k: string]: unknown;
59
- }
60
-
61
- export interface IRcbFile {
62
- id: string;
63
- userId: string;
64
- applicationId: string | null;
65
- pdfHash: string;
66
- pdfSizeBytes: number;
67
- pdfMimeType: string;
68
- pdfPageCount: number | null;
69
- pdfFilename: string | null;
70
- applicationFileId: string | null;
71
- userExternalId: string | null;
72
- userMetadata: Record<string, unknown> | null;
73
- detectedBank: string | null;
74
- detectedVersion: string | null;
75
- detectedIban: string | null;
76
- detectedBic: string | null;
77
- detectedCurrency: string | null;
78
- createdAt: string;
79
- updatedAt: string;
80
- }
81
-
82
- // Structured warning emitted by the extraction orchestrator. The `code`
83
- // is the i18n key suffix, `data` carries numeric/string values the UI
84
- // formats locally (currencies, dates, etc.).
85
- export enum RcbWarningCode {
86
- NO_RECORDS = 'no_records',
87
- NO_IBAN = 'no_iban',
88
- NO_BALANCES = 'no_balances',
89
- BALANCE_MISMATCH = 'balance_mismatch',
90
- }
91
-
92
- export interface IRcbWarning {
93
- code: RcbWarningCode;
94
- data?: {
95
- actualCents?: number;
96
- expectedCents?: number;
97
- currency?: string;
98
- };
99
- }
100
-
101
- export interface IRcbExtraction {
102
- id: string;
103
- fileId: string;
104
- mode: RcbExtractionMode;
105
- hintBank: string | null;
106
- hintVersion: string | null;
107
- templateId: string | null;
108
- templateVersion: number | null;
109
- status: RcbExtractionStatus;
110
- strategyUsed: string | null;
111
- confidence: number | null;
112
- recordsCount: number | null;
113
- balanceValidated: boolean | null;
114
- durationMs: number | null;
115
- error: string | null;
116
- recordsJson: IRcbTransaction[] | null;
117
- metadataJson: IRcbExtractionMetadata | null;
118
- warningsJson: IRcbWarning[] | null;
119
- tags: string[] | null;
120
- note: string | null;
121
- shareToken: string | null;
122
- shareExpiresAt: string | null;
123
- createdAt: string;
124
- }
125
-
126
- export interface IRcbTemplate {
127
- id: string;
128
- userId: string;
129
- name: string;
130
- description: string | null;
131
- isActive: boolean;
132
- createdAt: string;
133
- updatedAt: string;
134
- }
135
-
136
- /**
137
- * Spatial zone on a PDF page (PDF coords: origin bottom-left, points).
138
- * Restricts regex matching to a specific rectangle.
139
- */
140
- export interface IRcbTemplateZone {
141
- name: string;
142
- page: number; // 1-indexed
143
- x: number;
144
- y: number;
145
- w: number;
146
- h: number;
147
- }
148
-
149
- /**
150
- * Typed shape of the template DSL JSON stored in `templateJson`. Mirrors
151
- * `TemplateDSL` server-side. UI editors should narrow `templateJson` to this
152
- * shape via `templateJson as IRcbTemplateDsl`.
153
- */
154
- export interface IRcbTemplateDsl {
155
- regex_iban?: string;
156
- regex_bic?: string;
157
- period?: { regex: string };
158
- balance?: { opening_regex?: string; closing_regex?: string };
159
- transactions?: {
160
- row_pattern: string;
161
- date_format?: string;
162
- amount_locale?: 'fr' | 'en';
163
- sign_rule?: 'explicit' | 'keyword';
164
- };
165
- skip_patterns?: string[];
166
- zones?: IRcbTemplateZone[];
167
- }
168
-
169
- export interface IRcbTemplateVersion {
170
- id: string;
171
- templateId: string;
172
- version: number;
173
- templateJson: Record<string, unknown>;
174
- comment: string | null;
175
- createdAt: string;
176
- }
177
-
178
- export interface IRcbFeedback {
179
- id: string;
180
- extractionId: string;
181
- userId: string;
182
- issueType: RcbFeedbackIssueType;
183
- description: string | null;
184
- status: RcbFeedbackStatus;
185
- createdAt: string;
186
- }
187
-
188
- export interface IRcbWebhookDelivery {
189
- id: string;
190
- userId: string | null;
191
- organizationId: string | null;
192
- projectId: string | null;
193
- createdByUserId: string | null;
194
- webhookId: string | null;
195
- jobId: string | null;
196
- event: string;
197
- url: string;
198
- payloadJson: Record<string, unknown>;
199
- attempts: number;
200
- lastStatus: number | null;
201
- lastError: string | null;
202
- deliveredAt: string | null;
203
- createdAt: string;
204
- updatedAt: string;
205
- }
206
-
207
- // Webhook event identifier. Values mirror AbyssApplicationEvent's RCB_*
208
- // entries so a logger.log(applicationEvent: ...) and a webhook delivery
209
- // can never drift.
210
- export enum RcbWebhookEvent {
211
- EXTRACT_COMPLETED = 'rcb.extract.completed',
212
- EXTRACT_FAILED = 'rcb.extract.failed',
213
- EXTRACT_LOW_CONFIDENCE = 'rcb.extract.low-confidence',
214
- EXTRACT_BALANCE_KO = 'rcb.extract.balance-ko',
215
- FILE_ARCHIVED = 'rcb.file.archived',
216
- SHARE_MINTED = 'rcb.share.minted',
217
- SHARE_REVOKED = 'rcb.share.revoked',
218
- FEEDBACK_SUBMITTED = 'rcb.feedback.submitted',
219
- JOB_FAILED = 'rcb.job.failed',
220
- EXPORT_COMPLETED = 'rcb.export.completed',
221
- EXPORT_FAILED = 'rcb.export.failed',
222
- }
223
-
224
- export const RCB_WEBHOOK_EVENTS: RcbWebhookEvent[] =
225
- Object.values(RcbWebhookEvent);
226
-
227
- export interface IRcbWebhook {
228
- id: string;
229
- userId: string | null;
230
- organizationId: string | null;
231
- projectId: string | null;
232
- createdByUserId: string | null;
233
- webhookUrl: string;
234
- webhookSecret: string;
235
- isEnabled: boolean;
236
- name: string;
237
- description: string;
238
- scopes: RcbWebhookEvent[];
239
- consecutiveFailures: number;
240
- createdAt: string;
241
- updatedAt: string;
242
- }
243
-
244
- export interface IRcbQuota {
245
- userId: string;
246
- tier: string;
247
- monthlyExtractCap: number | null;
248
- monthlyExtractedCap: number | null;
249
- monthlyBytesCap: number | null;
250
- queueOnlyAboveCount: number | null;
251
- createdAt: string;
252
- updatedAt: string;
253
- }
254
-
255
- export interface IRcbBankVersion {
256
- id: string;
257
- bank: string;
258
- version: string;
259
- validFrom: string | null;
260
- validTo: string | null;
261
- detectorJson: Record<string, unknown>;
262
- parserKind: string;
263
- configJson: Record<string, unknown>;
264
- isActive: boolean;
265
- createdAt: string;
266
- updatedAt: string;
267
- }
1
+ // ──────────────────────────────────────────────
2
+ // RCB (Relevé de Compte Bancaire) DTOs.
3
+ // Mirror server-side Sequelize models, dates serialized as ISO strings.
4
+ // ──────────────────────────────────────────────
5
+
6
+ export type RcbExtractionMode = 'auto' | 'hint' | 'template';
7
+ export type RcbProcessingMode = 'sync' | 'queue';
8
+ export type RcbExtractionStatus = 'pending' | 'completed' | 'failed' | 'cached';
9
+
10
+ export type RcbFeedbackIssueType =
11
+ | 'missing_record'
12
+ | 'wrong_sign'
13
+ | 'wrong_amount'
14
+ | 'wrong_date'
15
+ | 'wrong_description'
16
+ | 'duplicate'
17
+ | 'other';
18
+
19
+ export type RcbFeedbackStatus = 'open' | 'triaged' | 'fixed' | 'closed';
20
+
21
+ export type RcbUsageEventType =
22
+ | 'extract.sync.success'
23
+ | 'extract.sync.cached'
24
+ | 'extract.sync.failed'
25
+ | 'extract.queue.enqueued'
26
+ | 'extract.queue.success'
27
+ | 'extract.queue.cached'
28
+ | 'extract.queue.failed'
29
+ | 'template.run.success'
30
+ | 'template.run.failed';
31
+
32
+ export interface IRcbBankHint {
33
+ bank: string;
34
+ version?: string;
35
+ }
36
+
37
+ export interface IRcbTransaction {
38
+ date?: string;
39
+ description?: string;
40
+ amount?: number;
41
+ balance?: number;
42
+ valueDate?: string;
43
+ bookingDate?: string;
44
+ reference?: string;
45
+ [k: string]: unknown;
46
+ }
47
+
48
+ export interface IRcbExtractionMetadata {
49
+ iban?: string;
50
+ bic?: string;
51
+ bank?: string;
52
+ accountHolder?: string;
53
+ periodStart?: string;
54
+ periodEnd?: string;
55
+ openingBalance?: number;
56
+ closingBalance?: number;
57
+ currency?: string;
58
+ [k: string]: unknown;
59
+ }
60
+
61
+ export interface IRcbFile {
62
+ id: string;
63
+ userId: string;
64
+ applicationId: string | null;
65
+ pdfHash: string;
66
+ pdfSizeBytes: number;
67
+ pdfMimeType: string;
68
+ pdfPageCount: number | null;
69
+ pdfFilename: string | null;
70
+ applicationFileId: string | null;
71
+ userExternalId: string | null;
72
+ userMetadata: Record<string, unknown> | null;
73
+ detectedBank: string | null;
74
+ detectedVersion: string | null;
75
+ detectedIban: string | null;
76
+ detectedBic: string | null;
77
+ detectedCurrency: string | null;
78
+ createdAt: string;
79
+ updatedAt: string;
80
+ }
81
+
82
+ // Structured warning emitted by the extraction orchestrator. The `code`
83
+ // is the i18n key suffix, `data` carries numeric/string values the UI
84
+ // formats locally (currencies, dates, etc.).
85
+ export enum RcbWarningCode {
86
+ NO_RECORDS = 'no_records',
87
+ NO_IBAN = 'no_iban',
88
+ NO_BALANCES = 'no_balances',
89
+ BALANCE_MISMATCH = 'balance_mismatch',
90
+ }
91
+
92
+ export interface IRcbWarning {
93
+ code: RcbWarningCode;
94
+ data?: {
95
+ actualCents?: number;
96
+ expectedCents?: number;
97
+ currency?: string;
98
+ };
99
+ }
100
+
101
+ export interface IRcbExtraction {
102
+ id: string;
103
+ fileId: string;
104
+ mode: RcbExtractionMode;
105
+ hintBank: string | null;
106
+ hintVersion: string | null;
107
+ templateId: string | null;
108
+ templateVersion: number | null;
109
+ status: RcbExtractionStatus;
110
+ strategyUsed: string | null;
111
+ confidence: number | null;
112
+ recordsCount: number | null;
113
+ balanceValidated: boolean | null;
114
+ durationMs: number | null;
115
+ error: string | null;
116
+ recordsJson: IRcbTransaction[] | null;
117
+ metadataJson: IRcbExtractionMetadata | null;
118
+ warningsJson: IRcbWarning[] | null;
119
+ tags: string[] | null;
120
+ note: string | null;
121
+ shareToken: string | null;
122
+ shareExpiresAt: string | null;
123
+ createdAt: string;
124
+ }
125
+
126
+ export interface IRcbTemplate {
127
+ id: string;
128
+ userId: string;
129
+ name: string;
130
+ description: string | null;
131
+ isActive: boolean;
132
+ createdAt: string;
133
+ updatedAt: string;
134
+ }
135
+
136
+ /**
137
+ * Spatial zone on a PDF page (PDF coords: origin bottom-left, points).
138
+ * Restricts regex matching to a specific rectangle.
139
+ */
140
+ export interface IRcbTemplateZone {
141
+ name: string;
142
+ page: number; // 1-indexed
143
+ x: number;
144
+ y: number;
145
+ w: number;
146
+ h: number;
147
+ }
148
+
149
+ /**
150
+ * Typed shape of the template DSL JSON stored in `templateJson`. Mirrors
151
+ * `TemplateDSL` server-side. UI editors should narrow `templateJson` to this
152
+ * shape via `templateJson as IRcbTemplateDsl`.
153
+ */
154
+ export interface IRcbTemplateDsl {
155
+ regex_iban?: string;
156
+ regex_bic?: string;
157
+ period?: { regex: string };
158
+ balance?: { opening_regex?: string; closing_regex?: string };
159
+ transactions?: {
160
+ row_pattern: string;
161
+ date_format?: string;
162
+ amount_locale?: 'fr' | 'en';
163
+ sign_rule?: 'explicit' | 'keyword';
164
+ };
165
+ skip_patterns?: string[];
166
+ zones?: IRcbTemplateZone[];
167
+ }
168
+
169
+ export interface IRcbTemplateVersion {
170
+ id: string;
171
+ templateId: string;
172
+ version: number;
173
+ templateJson: Record<string, unknown>;
174
+ comment: string | null;
175
+ createdAt: string;
176
+ }
177
+
178
+ export interface IRcbFeedback {
179
+ id: string;
180
+ extractionId: string;
181
+ userId: string;
182
+ issueType: RcbFeedbackIssueType;
183
+ description: string | null;
184
+ status: RcbFeedbackStatus;
185
+ createdAt: string;
186
+ }
187
+
188
+ export interface IRcbWebhookDelivery {
189
+ id: string;
190
+ userId: string | null;
191
+ organizationId: string | null;
192
+ projectId: string | null;
193
+ createdByUserId: string | null;
194
+ webhookId: string | null;
195
+ jobId: string | null;
196
+ event: string;
197
+ url: string;
198
+ payloadJson: Record<string, unknown>;
199
+ attempts: number;
200
+ lastStatus: number | null;
201
+ lastError: string | null;
202
+ deliveredAt: string | null;
203
+ createdAt: string;
204
+ updatedAt: string;
205
+ }
206
+
207
+ // Webhook event identifier. Values mirror AbyssApplicationEvent's RCB_*
208
+ // entries so a logger.log(applicationEvent: ...) and a webhook delivery
209
+ // can never drift.
210
+ export enum RcbWebhookEvent {
211
+ EXTRACT_COMPLETED = 'rcb.extract.completed',
212
+ EXTRACT_FAILED = 'rcb.extract.failed',
213
+ EXTRACT_LOW_CONFIDENCE = 'rcb.extract.low-confidence',
214
+ EXTRACT_BALANCE_KO = 'rcb.extract.balance-ko',
215
+ FILE_ARCHIVED = 'rcb.file.archived',
216
+ SHARE_MINTED = 'rcb.share.minted',
217
+ SHARE_REVOKED = 'rcb.share.revoked',
218
+ FEEDBACK_SUBMITTED = 'rcb.feedback.submitted',
219
+ JOB_FAILED = 'rcb.job.failed',
220
+ EXPORT_COMPLETED = 'rcb.export.completed',
221
+ EXPORT_FAILED = 'rcb.export.failed',
222
+ }
223
+
224
+ export const RCB_WEBHOOK_EVENTS: RcbWebhookEvent[] =
225
+ Object.values(RcbWebhookEvent);
226
+
227
+ export interface IRcbWebhook {
228
+ id: string;
229
+ userId: string | null;
230
+ organizationId: string | null;
231
+ projectId: string | null;
232
+ createdByUserId: string | null;
233
+ webhookUrl: string;
234
+ webhookSecret: string;
235
+ isEnabled: boolean;
236
+ name: string;
237
+ description: string;
238
+ scopes: RcbWebhookEvent[];
239
+ consecutiveFailures: number;
240
+ createdAt: string;
241
+ updatedAt: string;
242
+ }
243
+
244
+ export interface IRcbQuota {
245
+ userId: string;
246
+ tier: string;
247
+ monthlyExtractCap: number | null;
248
+ monthlyExtractedCap: number | null;
249
+ monthlyBytesCap: number | null;
250
+ queueOnlyAboveCount: number | null;
251
+ createdAt: string;
252
+ updatedAt: string;
253
+ }
254
+
255
+ export interface IRcbBankVersion {
256
+ id: string;
257
+ bank: string;
258
+ version: string;
259
+ validFrom: string | null;
260
+ validTo: string | null;
261
+ detectorJson: Record<string, unknown>;
262
+ parserKind: string;
263
+ configJson: Record<string, unknown>;
264
+ isActive: boolean;
265
+ createdAt: string;
266
+ updatedAt: string;
267
+ }
@@ -1,30 +1,30 @@
1
- // ──────────────────────────────────────────────
2
- // RCB webhook signature verification (server-side helper for receivers).
3
- //
4
- // AbyssTools RCB queue signs every webhook delivery with HMAC-SHA256 of
5
- // the raw JSON body using the secret provided at extract time. Receivers
6
- // compare the X-RCB-Signature header (format `sha256=<hex>`) against the
7
- // same computation. Constant-time compare prevents timing attacks.
8
- //
9
- // Lazy-requires `crypto` so the SDK stays browser-compatible when this
10
- // utility is never invoked (browsers won't receive webhooks anyway).
11
- // ──────────────────────────────────────────────
12
-
13
- export interface VerifyRcbWebhookInput {
14
- rawBody: string | Buffer;
15
- signatureHeader: string | undefined;
16
- secret: string;
17
- }
18
-
19
- export function verifyRcbWebhook(input: VerifyRcbWebhookInput): boolean {
20
- if (!input.signatureHeader || !input.secret) return false;
21
- // eslint-disable-next-line @typescript-eslint/no-var-requires
22
- const crypto = require('crypto');
23
- const provided = input.signatureHeader.replace(/^sha256=/, '');
24
- const computed: string = crypto
25
- .createHmac('sha256', input.secret)
26
- .update(input.rawBody)
27
- .digest('hex');
28
- if (provided.length !== computed.length) return false;
29
- return crypto.timingSafeEqual(Buffer.from(provided, 'hex'), Buffer.from(computed, 'hex'));
30
- }
1
+ // ──────────────────────────────────────────────
2
+ // RCB webhook signature verification (server-side helper for receivers).
3
+ //
4
+ // AbyssTools RCB queue signs every webhook delivery with HMAC-SHA256 of
5
+ // the raw JSON body using the secret provided at extract time. Receivers
6
+ // compare the X-RCB-Signature header (format `sha256=<hex>`) against the
7
+ // same computation. Constant-time compare prevents timing attacks.
8
+ //
9
+ // Lazy-requires `crypto` so the SDK stays browser-compatible when this
10
+ // utility is never invoked (browsers won't receive webhooks anyway).
11
+ // ──────────────────────────────────────────────
12
+
13
+ export interface VerifyRcbWebhookInput {
14
+ rawBody: string | Buffer;
15
+ signatureHeader: string | undefined;
16
+ secret: string;
17
+ }
18
+
19
+ export function verifyRcbWebhook(input: VerifyRcbWebhookInput): boolean {
20
+ if (!input.signatureHeader || !input.secret) return false;
21
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
22
+ const crypto = require('crypto');
23
+ const provided = input.signatureHeader.replace(/^sha256=/, '');
24
+ const computed: string = crypto
25
+ .createHmac('sha256', input.secret)
26
+ .update(input.rawBody)
27
+ .digest('hex');
28
+ if (provided.length !== computed.length) return false;
29
+ return crypto.timingSafeEqual(Buffer.from(provided, 'hex'), Buffer.from(computed, 'hex'));
30
+ }
File without changes