@perrylink/dsh-einvoice 0.2.0-alpha.0 → 0.2.0-alpha.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.
- package/LICENSE +0 -0
- package/NOTICE +0 -0
- package/README.md +32 -32
- package/THIRD-PARTY-NOTICES +0 -0
- package/cordis.patch.yml +0 -0
- package/lib/adapters/ofd-zip-xml.d.ts +0 -0
- package/lib/adapters/ofd-zip-xml.js +0 -0
- package/lib/core/invoice.d.ts +0 -0
- package/lib/core/invoice.js +0 -0
- package/lib/plugin/index.d.ts +0 -0
- package/lib/plugin/index.js +0 -0
- package/lib/plugin/storage.d.ts +27 -27
- package/lib/plugin/storage.js +0 -0
- package/lib/plugin/tools.d.ts +0 -0
- package/lib/plugin/tools.js +0 -0
- package/lib/registry/parsers.d.ts +0 -0
- package/lib/registry/parsers.js +0 -0
- package/package.json +9 -4
package/LICENSE
CHANGED
|
File without changes
|
package/NOTICE
CHANGED
|
File without changes
|
package/README.md
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
# @perrylink/dsh-einvoice
|
|
2
2
|
|
|
3
|
-
File-level Chinese e-invoice ingest, parse and
|
|
3
|
+
File-level Chinese e-invoice (OFD/XML) ingest, parse, dedup and local archive for DeepSeek Harness.
|
|
4
4
|
|
|
5
|
-
> **Status:
|
|
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. The customer evidence gate (2 enterprises + 1 bookkeeping firm + 100 real invoices) is still PARKED. S1 uses public/open-source and synthetic fixtures; its acceptance rows are `not counted` toward GA. Do not describe this package as GA-ready.
|
|
5
|
+
> **Status: alpha / public-synthetic / partial / not counted / not GA.** No customer evidence, customer data, or production-readiness claim. All acceptance rows are `counted=false`.
|
|
7
6
|
|
|
8
7
|
## Install
|
|
9
8
|
|
|
@@ -12,60 +11,61 @@ dsh plugin --profile <profile> add @perrylink/dsh-einvoice
|
|
|
12
11
|
dsh --profile <profile> --dump-config | grep dsh-einvoice
|
|
13
12
|
```
|
|
14
13
|
|
|
15
|
-
|
|
14
|
+
Requires DSH `>=0.2.1-rc.3 <0.3.0` and Node `>=24.9 <25`.
|
|
16
15
|
|
|
17
|
-
|
|
16
|
+
<details>
|
|
17
|
+
<summary>中文摘要</summary>
|
|
18
|
+
|
|
19
|
+
文件级中国电子发票(OFD/XML)入库、解析、去重与本地归档。 安装:`dsh plugin --profile <profile> add @perrylink/dsh-einvoice`。公开/合成、alpha、非 GA。
|
|
20
|
+
|
|
21
|
+
</details>
|
|
22
|
+
|
|
23
|
+
## Tools
|
|
18
24
|
|
|
19
25
|
| Tool | What it does | Risk |
|
|
20
26
|
|---|---|---|
|
|
21
|
-
| `invoice.ingest` | Ingest one local OFD/XML
|
|
22
|
-
| `invoice.parse` | Parse old OFD `Attachs/original_invoice.xml` or 数电票 `Tags/CustomTag.xml
|
|
23
|
-
| `invoice.query` | Query the
|
|
24
|
-
| `invoice.dedup` | Group duplicates by invoice number or seller+date+total | R0 |
|
|
25
|
-
| `invoice.review_queue` | Queue parsed invoices for manual local review; optional buyer-tax-id mismatch flags
|
|
26
|
-
| `invoice.record_receipt` | Hash a local receipt, append it
|
|
27
|
-
| `invoice.redlink` | Bind a negative red invoice to its blue invoice
|
|
27
|
+
| `invoice.ingest` | Ingest one local OFD/XML, compute SHA-256, store the original, idempotent by bytes | R1 local write |
|
|
28
|
+
| `invoice.parse` | Parse old OFD `Attachs/original_invoice.xml` or 数电票 `Tags/CustomTag.xml`; return eight fields, lines, evidence and unknown fields | R0 |
|
|
29
|
+
| `invoice.query` | Query the local pool by entity, period, lifecycle or text | R0 |
|
|
30
|
+
| `invoice.dedup` | Group duplicates by invoice number or seller + date + total | R0 |
|
|
31
|
+
| `invoice.review_queue` | Queue parsed invoices for manual local review; optional buyer-tax-id mismatch flags | R1 local write |
|
|
32
|
+
| `invoice.record_receipt` | Hash a local receipt, append it and move lifecycle; `verification_source=local_receipt`, `tax_verified=false` | R1 local write |
|
|
33
|
+
| `invoice.redlink` | Bind a negative red invoice to its blue invoice and store deltas | R1 local write |
|
|
28
34
|
| `invoice.archive` | Build a manifest + originals + receipts ZIP under the local archive directory | R1 local write |
|
|
29
35
|
| `invoice.check` | Verify manifest/member hashes, missing files and traversal | R0 |
|
|
30
36
|
| `invoice.restore` | Restore a verified archive into the local restore root | R1 local write |
|
|
31
37
|
|
|
32
|
-
|
|
38
|
+
## Input / output
|
|
33
39
|
|
|
34
|
-
|
|
40
|
+
**Input:** one local OFD/XML invoice per `invoice.ingest` call. **Output:** a local invoice pool, review/receipt state, red/blue links, and a deterministic archive ZIP. `invoice.check` verifies the archive; `invoice.restore` restores it locally.
|
|
35
41
|
|
|
36
42
|
## Configuration
|
|
37
43
|
|
|
38
44
|
| Env | Default | Meaning |
|
|
39
45
|
|---|---|---|
|
|
40
46
|
| `DSH_EINVOICE_HOME` | `$DSH_HOME/storages/dsh-einvoice` | originals directory and local pool base |
|
|
41
|
-
| `DSH_EINVOICE_INPUT_ROOTS` | current working directory | `path.delimiter`-separated allowlist for `invoice.ingest` |
|
|
47
|
+
| `DSH_EINVOICE_INPUT_ROOTS` | `current working directory` | `path.delimiter`-separated allowlist for `invoice.ingest` |
|
|
42
48
|
|
|
43
|
-
|
|
49
|
+
## Limits / non-claims
|
|
44
50
|
|
|
45
|
-
|
|
51
|
+
- No OCR/scanning, tax-bureau verification/receipt, tax filing, 30-year archive compliance, or real-invoice accuracy claim.
|
|
52
|
+
- `invoice.record_receipt` is local-only: `verification_source=local_receipt`, `tax_verified=false`.
|
|
53
|
+
- No IMAP/email fetching, ERP posting, e-signature legal opinion, or Client UI.
|
|
54
|
+
- S1 accepts one local file per `invoice.ingest`; directory batches are not part of this package.
|
|
55
|
+
- Public samples with PII are kept outside the tarball; do not paste raw invoice output into logs or public issues.
|
|
56
|
+
- No customer evidence, customer data, or production-readiness claim; all fixtures are public/synthetic.
|
|
46
57
|
|
|
47
|
-
|
|
48
|
-
- S1 accepts one local file per `invoice.ingest` call; directory batches are S2.
|
|
49
|
-
- `unknown_fields`/`field_evidence` are stored locally and may contain the same sensitive fields as the invoice; keep the pool local and do not paste raw output into logs or public issues.
|
|
50
|
-
- Public samples with PII are kept in `.tmp` only; they are not shipped in the tarball.
|
|
58
|
+
## Public sample
|
|
51
59
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
Errors are thrown as `E_INV_*` (`E_INV_FILE_UNREADABLE`, `E_INV_PATH_NOT_ALLOWED`, `E_INV_OFD_UNSUPPORTED`, `E_INV_XML_SCHEMA_DRIFT`, `E_INV_FIELD_MISSING`, `E_INV_DOC_NOT_FOUND`, `E_INV_DUP_CONFLICT`, `E_INV_STORAGE_FAILED`, `E_INV_UNKNOWN_IMPL`). DSH renders thrown errors as tool errors; they are not returned as successful `{ok:false}` values.
|
|
60
|
+
Synthetic invoice XML/OFD fixtures; `ACCEPTANCE.csv` lists 7 public checks (one is `out_of_scope`). No real invoice is included.
|
|
55
61
|
|
|
56
62
|
## Development
|
|
57
63
|
|
|
58
64
|
```sh
|
|
59
65
|
pnpm install --frozen-lockfile
|
|
60
|
-
pnpm build
|
|
61
|
-
pnpm lint
|
|
62
|
-
pnpm typecheck
|
|
63
|
-
pnpm test
|
|
64
|
-
pnpm gate:sku04
|
|
66
|
+
pnpm build && pnpm lint && pnpm typecheck && pnpm test && pnpm gate:sku04
|
|
65
67
|
```
|
|
66
68
|
|
|
67
|
-
See `docs/architecture.md`, `docs/plugin-development.md`, `docs/configuration.md`, `FIXTURES.md`, `BUILD-PLAN-04.md`.
|
|
68
|
-
|
|
69
69
|
## License
|
|
70
70
|
|
|
71
|
-
Apache-2.0.
|
|
71
|
+
Apache-2.0. See `LICENSE`, `NOTICE`, `THIRD-PARTY-NOTICES`.
|
package/THIRD-PARTY-NOTICES
CHANGED
|
File without changes
|
package/cordis.patch.yml
CHANGED
|
File without changes
|
|
File without changes
|
|
File without changes
|
package/lib/core/invoice.d.ts
CHANGED
|
File without changes
|
package/lib/core/invoice.js
CHANGED
|
File without changes
|
package/lib/plugin/index.d.ts
CHANGED
|
File without changes
|
package/lib/plugin/index.js
CHANGED
|
File without changes
|
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/storage.js
CHANGED
|
File without changes
|
package/lib/plugin/tools.d.ts
CHANGED
|
File without changes
|
package/lib/plugin/tools.js
CHANGED
|
File without changes
|
|
File without changes
|
package/lib/registry/parsers.js
CHANGED
|
File without changes
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@perrylink/dsh-einvoice",
|
|
3
|
-
"version": "0.2.0-alpha.
|
|
4
|
-
"description": "File-level Chinese e-invoice (OFD/XML) ingest, parse and
|
|
3
|
+
"version": "0.2.0-alpha.2",
|
|
4
|
+
"description": "File-level Chinese e-invoice (OFD/XML) ingest, parse, dedup and local archive.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./lib/plugin/index.js",
|
|
7
7
|
"types": "./lib/plugin/index.d.ts",
|
|
@@ -45,7 +45,8 @@
|
|
|
45
45
|
"einvoice",
|
|
46
46
|
"invoice",
|
|
47
47
|
"ofd",
|
|
48
|
-
"perrylink"
|
|
48
|
+
"perrylink",
|
|
49
|
+
"finance"
|
|
49
50
|
],
|
|
50
51
|
"repository": {
|
|
51
52
|
"type": "git",
|
|
@@ -79,6 +80,10 @@
|
|
|
79
80
|
"@deepseek-ai/dsh-util-values": "0.2.1-rc.3",
|
|
80
81
|
"@deepseek-ai/schemastery": "3.18.5",
|
|
81
82
|
"@types/node": "^24.0.0",
|
|
82
|
-
"typescript": "
|
|
83
|
+
"typescript": "7.0.2"
|
|
84
|
+
},
|
|
85
|
+
"homepage": "https://github.com/PerryLink/dsh-einvoice#readme",
|
|
86
|
+
"bugs": {
|
|
87
|
+
"url": "https://github.com/PerryLink/dsh-einvoice/issues"
|
|
83
88
|
}
|
|
84
89
|
}
|