@perrylink/dsh-einvoice 0.1.0-alpha.3 → 0.2.0-alpha.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/README.md +6 -3
- package/lib/plugin/storage.d.ts +27 -27
- package/lib/plugin/tools.js +9 -5
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
File-level Chinese e-invoice ingest, parse and pool for DeepSeek Harness (SKU-04 S1).
|
|
4
4
|
|
|
5
|
-
> **Status:
|
|
5
|
+
> **Status: file-level public demo (0.2.0-alpha.1) — PARTIAL, NOT COUNTED, NOT GA.**
|
|
6
|
+
> This package does **not** implement OCR/scanning, tax-bureau verification/receipt, tax filing, 30-year archive compliance, or real-invoice accuracy claims. `invoice.review_queue` / `invoice.record_receipt` are local-only; the legacy names are deprecated aliases. Customer-evidence work (2 enterprises + 1 bookkeeping firm + 100 real invoices) is **permanently out of scope**. This package is public-only; its acceptance rows are `not counted`. Do not describe it as GA-ready.
|
|
6
7
|
|
|
7
8
|
## Install
|
|
8
9
|
|
|
@@ -21,13 +22,15 @@ The bundle inserts one Host row. It requires the base profile's `tools` and `sto
|
|
|
21
22
|
| `invoice.parse` | Parse old OFD `Attachs/original_invoice.xml` or 数电票 `Tags/CustomTag.xml` + ObjectRef; return eight fields, lines, evidence and unknown fields | R0 |
|
|
22
23
|
| `invoice.query` | Query the invoice pool by entity, period, lifecycle or text | R0 |
|
|
23
24
|
| `invoice.dedup` | Group duplicates by invoice number or seller+date+total | R0 |
|
|
24
|
-
| `invoice.
|
|
25
|
-
| `invoice.
|
|
25
|
+
| `invoice.review_queue` | Queue parsed invoices for manual local review; optional buyer-tax-id mismatch flags. Old `invoice.verify` is a deprecated alias. | R1 local write |
|
|
26
|
+
| `invoice.record_receipt` | Hash a local receipt, append it, move lifecycle to receipt-recorded/quarantined; `verification_source=local_receipt`, `tax_verified=false`; old `invoice.receipt` is a deprecated alias. | R1 local write |
|
|
26
27
|
| `invoice.redlink` | Bind a negative red invoice to its blue invoice; store deltas | R1 local write |
|
|
27
28
|
| `invoice.archive` | Build a manifest + originals + receipts ZIP under the local archive directory | R1 local write |
|
|
28
29
|
| `invoice.check` | Verify manifest/member hashes, missing files and traversal | R0 |
|
|
29
30
|
| `invoice.restore` | Restore a verified archive into the local restore root | R1 local write |
|
|
30
31
|
|
|
32
|
+
Client: deferred; see `CLIENT-DECISION.md`. GA: blocked by the customer evidence gate; see `GA-CHECKLIST.md`.
|
|
33
|
+
|
|
31
34
|
S3 adds red/blue matching, deterministic archive packages, check and restore. S2 verification is manual/local (no tax-bureau network call).
|
|
32
35
|
|
|
33
36
|
## Configuration
|
package/lib/plugin/storage.d.ts
CHANGED
|
@@ -17,10 +17,10 @@ export declare const lineSchema: z.ZodObject<{
|
|
|
17
17
|
}, z.core.$strip>;
|
|
18
18
|
export declare const verificationSchema: z.ZodObject<{
|
|
19
19
|
state: z.ZodEnum<{
|
|
20
|
-
verified: "verified";
|
|
21
|
-
pending: "pending";
|
|
22
20
|
failed: "failed";
|
|
23
21
|
manual: "manual";
|
|
22
|
+
pending: "pending";
|
|
23
|
+
verified: "verified";
|
|
24
24
|
}>;
|
|
25
25
|
queued_at: z.ZodOptional<z.ZodString>;
|
|
26
26
|
updated_at: z.ZodOptional<z.ZodString>;
|
|
@@ -32,8 +32,8 @@ export declare const receiptSchema: z.ZodObject<{
|
|
|
32
32
|
receipt_id: z.ZodString;
|
|
33
33
|
result_code: z.ZodString;
|
|
34
34
|
result: z.ZodEnum<{
|
|
35
|
-
pass: "pass";
|
|
36
35
|
fail: "fail";
|
|
36
|
+
pass: "pass";
|
|
37
37
|
unknown: "unknown";
|
|
38
38
|
}>;
|
|
39
39
|
verified_at: z.ZodString;
|
|
@@ -45,8 +45,8 @@ export declare const receiptSchema: z.ZodObject<{
|
|
|
45
45
|
export declare const redlinkSchema: z.ZodObject<{
|
|
46
46
|
blue_id: z.ZodString;
|
|
47
47
|
mode: z.ZodEnum<{
|
|
48
|
-
manual: "manual";
|
|
49
48
|
auto: "auto";
|
|
49
|
+
manual: "manual";
|
|
50
50
|
}>;
|
|
51
51
|
amount_delta_cents: z.ZodNumber;
|
|
52
52
|
tax_delta_cents: z.ZodNumber;
|
|
@@ -86,18 +86,18 @@ export declare const invoiceSchema: z.ZodObject<{
|
|
|
86
86
|
unknown_fields: z.ZodRecord<z.ZodString, z.ZodUnknown>;
|
|
87
87
|
parser_version: z.ZodString;
|
|
88
88
|
lifecycle: z.ZodEnum<{
|
|
89
|
-
received: "received";
|
|
90
|
-
parsed: "parsed";
|
|
91
|
-
verified: "verified";
|
|
92
89
|
archived: "archived";
|
|
90
|
+
parsed: "parsed";
|
|
93
91
|
quarantined: "quarantined";
|
|
92
|
+
received: "received";
|
|
93
|
+
verified: "verified";
|
|
94
94
|
}>;
|
|
95
95
|
verification: z.ZodOptional<z.ZodObject<{
|
|
96
96
|
state: z.ZodEnum<{
|
|
97
|
-
verified: "verified";
|
|
98
|
-
pending: "pending";
|
|
99
97
|
failed: "failed";
|
|
100
98
|
manual: "manual";
|
|
99
|
+
pending: "pending";
|
|
100
|
+
verified: "verified";
|
|
101
101
|
}>;
|
|
102
102
|
queued_at: z.ZodOptional<z.ZodString>;
|
|
103
103
|
updated_at: z.ZodOptional<z.ZodString>;
|
|
@@ -109,8 +109,8 @@ export declare const invoiceSchema: z.ZodObject<{
|
|
|
109
109
|
receipt_id: z.ZodString;
|
|
110
110
|
result_code: z.ZodString;
|
|
111
111
|
result: z.ZodEnum<{
|
|
112
|
-
pass: "pass";
|
|
113
112
|
fail: "fail";
|
|
113
|
+
pass: "pass";
|
|
114
114
|
unknown: "unknown";
|
|
115
115
|
}>;
|
|
116
116
|
verified_at: z.ZodString;
|
|
@@ -122,8 +122,8 @@ export declare const invoiceSchema: z.ZodObject<{
|
|
|
122
122
|
redlink: z.ZodOptional<z.ZodObject<{
|
|
123
123
|
blue_id: z.ZodString;
|
|
124
124
|
mode: z.ZodEnum<{
|
|
125
|
-
manual: "manual";
|
|
126
125
|
auto: "auto";
|
|
126
|
+
manual: "manual";
|
|
127
127
|
}>;
|
|
128
128
|
amount_delta_cents: z.ZodNumber;
|
|
129
129
|
tax_delta_cents: z.ZodNumber;
|
|
@@ -159,6 +159,7 @@ export declare const finInvoiceSpec: {
|
|
|
159
159
|
doc_id: string;
|
|
160
160
|
entity_id: string;
|
|
161
161
|
invoice_no: string;
|
|
162
|
+
invoice_code?: string | undefined;
|
|
162
163
|
issue_date: string;
|
|
163
164
|
buyer: {
|
|
164
165
|
name: string;
|
|
@@ -175,9 +176,9 @@ export declare const finInvoiceSpec: {
|
|
|
175
176
|
lines: {
|
|
176
177
|
line_no: number;
|
|
177
178
|
description: string;
|
|
178
|
-
amount_cents: number;
|
|
179
179
|
quantity?: string | undefined;
|
|
180
180
|
unit_price_cents?: number | undefined;
|
|
181
|
+
amount_cents: number;
|
|
181
182
|
tax_rate?: string | undefined;
|
|
182
183
|
tax_cents?: number | undefined;
|
|
183
184
|
}[];
|
|
@@ -185,28 +186,19 @@ export declare const finInvoiceSpec: {
|
|
|
185
186
|
field_evidence: Record<string, string>;
|
|
186
187
|
unknown_fields: Record<string, unknown>;
|
|
187
188
|
parser_version: string;
|
|
188
|
-
lifecycle: "
|
|
189
|
-
source_path: string;
|
|
190
|
-
source_sha256: string;
|
|
191
|
-
source_size: number;
|
|
192
|
-
created_at: string;
|
|
193
|
-
updated_at: string;
|
|
194
|
-
run_id: string;
|
|
195
|
-
actor: string;
|
|
196
|
-
evidence_sha256: string;
|
|
197
|
-
invoice_code?: string | undefined;
|
|
189
|
+
lifecycle: "archived" | "parsed" | "quarantined" | "received" | "verified";
|
|
198
190
|
verification?: {
|
|
199
|
-
state: "
|
|
200
|
-
attempts: number;
|
|
191
|
+
state: "failed" | "manual" | "pending" | "verified";
|
|
201
192
|
queued_at?: string | undefined;
|
|
202
193
|
updated_at?: string | undefined;
|
|
194
|
+
attempts: number;
|
|
203
195
|
last_result?: string | undefined;
|
|
204
196
|
manual_reason?: string | undefined;
|
|
205
197
|
} | undefined;
|
|
206
198
|
receipts?: {
|
|
207
199
|
receipt_id: string;
|
|
208
200
|
result_code: string;
|
|
209
|
-
result: "
|
|
201
|
+
result: "fail" | "pass" | "unknown";
|
|
210
202
|
verified_at: string;
|
|
211
203
|
operator: string;
|
|
212
204
|
receipt_sha256: string;
|
|
@@ -215,14 +207,22 @@ export declare const finInvoiceSpec: {
|
|
|
215
207
|
}[] | undefined;
|
|
216
208
|
redlink?: {
|
|
217
209
|
blue_id: string;
|
|
218
|
-
mode: "
|
|
210
|
+
mode: "auto" | "manual";
|
|
219
211
|
amount_delta_cents: number;
|
|
220
212
|
tax_delta_cents: number;
|
|
213
|
+
allocation_cents?: number | undefined;
|
|
221
214
|
bound_at: string;
|
|
222
215
|
bound_by: string;
|
|
223
|
-
allocation_cents?: number | undefined;
|
|
224
216
|
} | undefined;
|
|
217
|
+
source_path: string;
|
|
225
218
|
source_name?: string | undefined;
|
|
219
|
+
source_sha256: string;
|
|
220
|
+
source_size: number;
|
|
221
|
+
created_at: string;
|
|
222
|
+
updated_at: string;
|
|
223
|
+
run_id: string;
|
|
224
|
+
actor: string;
|
|
225
|
+
evidence_sha256: string;
|
|
226
226
|
}>;
|
|
227
227
|
};
|
|
228
228
|
};
|
package/lib/plugin/tools.js
CHANGED
|
@@ -449,7 +449,7 @@ export function createTools(deps) {
|
|
|
449
449
|
},
|
|
450
450
|
});
|
|
451
451
|
const verify = defineTool({
|
|
452
|
-
name: 'invoice.
|
|
452
|
+
name: 'invoice.review_queue',
|
|
453
453
|
description: 'Queue parsed invoices for manual/semi-automatic verification. S2 has no tax-bureau network call: it records a pending local queue and optional entity-tax-id mismatch flags.',
|
|
454
454
|
parameters: {
|
|
455
455
|
invoice_ids: { type: 'array', items: { type: 'string' }, description: 'Optional subset; defaults to parsed invoices' },
|
|
@@ -533,7 +533,7 @@ export function createTools(deps) {
|
|
|
533
533
|
},
|
|
534
534
|
});
|
|
535
535
|
const receipt = defineTool({
|
|
536
|
-
name: 'invoice.
|
|
536
|
+
name: 'invoice.record_receipt',
|
|
537
537
|
description: 'Record a local verification receipt for one parsed invoice: hash the receipt file, append an immutable receipt record, and move the invoice to verified/quarantined. Local R1 write; no tax-bureau write.',
|
|
538
538
|
parameters: {
|
|
539
539
|
invoice_id: { type: 'string', required: true },
|
|
@@ -552,6 +552,8 @@ export function createTools(deps) {
|
|
|
552
552
|
receipt_sha256: { type: 'string', required: true },
|
|
553
553
|
duplicate: { type: 'boolean', required: true },
|
|
554
554
|
lifecycle: { type: 'string', required: true },
|
|
555
|
+
verification_source: { type: 'string', required: true },
|
|
556
|
+
tax_verified: { type: 'boolean', required: true },
|
|
555
557
|
},
|
|
556
558
|
},
|
|
557
559
|
render: (_args, value) => text(`receipt ${value.receipt_id} (${value.duplicate ? 'duplicate' : 'recorded'}), invoice=${value.lifecycle}`),
|
|
@@ -571,7 +573,7 @@ export function createTools(deps) {
|
|
|
571
573
|
const receiptSha = sha256Buffer(buffer);
|
|
572
574
|
const existing = (record.receipts ?? []).find((item) => item.receipt_sha256 === receiptSha);
|
|
573
575
|
if (existing) {
|
|
574
|
-
return { receipt_id: existing.receipt_id, receipt_sha256: receiptSha, duplicate: true, lifecycle: record.lifecycle };
|
|
576
|
+
return { receipt_id: existing.receipt_id, receipt_sha256: receiptSha, duplicate: true, lifecycle: record.lifecycle, verification_source: 'local_receipt', tax_verified: false };
|
|
575
577
|
}
|
|
576
578
|
const now = new Date().toISOString();
|
|
577
579
|
const receiptRecord = {
|
|
@@ -600,7 +602,7 @@ export function createTools(deps) {
|
|
|
600
602
|
updated_at: now,
|
|
601
603
|
};
|
|
602
604
|
await deps.table.put(record.doc_id, updated);
|
|
603
|
-
return { receipt_id: receiptRecord.receipt_id, receipt_sha256: receiptSha, duplicate: false, lifecycle };
|
|
605
|
+
return { receipt_id: receiptRecord.receipt_id, receipt_sha256: receiptSha, duplicate: false, lifecycle, verification_source: 'local_receipt', tax_verified: false };
|
|
604
606
|
},
|
|
605
607
|
});
|
|
606
608
|
const archiveDir = path.join(deps.baseDir, 'archives');
|
|
@@ -891,5 +893,7 @@ export function createTools(deps) {
|
|
|
891
893
|
};
|
|
892
894
|
},
|
|
893
895
|
});
|
|
894
|
-
|
|
896
|
+
const legacyVerify = { ...verify, name: 'invoice.verify', description: 'Deprecated alias for invoice.review_queue; local review queue only, no tax-bureau verification.' };
|
|
897
|
+
const legacyReceipt = { ...receipt, name: 'invoice.receipt', description: 'Deprecated alias for invoice.record_receipt; local receipt only, no tax-bureau verification.' };
|
|
898
|
+
return [ingest, parse, query, dedup, verify, legacyVerify, receipt, legacyReceipt, redlink, archive, check, restore];
|
|
895
899
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@perrylink/dsh-einvoice",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0-alpha.1",
|
|
4
4
|
"description": "File-level Chinese e-invoice (OFD/XML) ingest, parse and pool for DeepSeek Harness (SKU-04 S1).",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./lib/plugin/index.js",
|
|
@@ -79,6 +79,6 @@
|
|
|
79
79
|
"@deepseek-ai/dsh-util-values": "0.2.1-rc.3",
|
|
80
80
|
"@deepseek-ai/schemastery": "3.18.5",
|
|
81
81
|
"@types/node": "^24.0.0",
|
|
82
|
-
"typescript": "
|
|
82
|
+
"typescript": "7.0.2"
|
|
83
83
|
}
|
|
84
84
|
}
|