@acosmi/sdk-ts 1.4.2 → 1.5.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/CHANGELOG.md +178 -0
- package/README.md +200 -25
- package/dist/browser/index.mjs +521 -2
- package/dist/browser/index.mjs.map +1 -1
- package/dist/index.mjs +521 -2
- package/dist/index.mjs.map +1 -1
- package/dist/node/index.cjs +527 -1
- package/dist/node/index.cjs.map +1 -1
- package/dist/node/index.d.cts +1083 -32
- package/dist/node/index.d.ts +1083 -32
- package/dist/node/index.mjs +521 -2
- package/dist/node/index.mjs.map +1 -1
- package/docs/compliance.md +457 -2
- package/examples/auth-oauth-flow.ts +6 -2
- package/examples/compliance-evidence-timestamp.ts +3 -1
- package/examples/core-chat.ts +5 -2
- package/package.json +1 -1
package/docs/compliance.md
CHANGED
|
@@ -90,6 +90,17 @@ Report scopes are split by action:
|
|
|
90
90
|
again) so the new scope is granted.
|
|
91
91
|
- `ScopeComplianceReportsPublish` — `publishReport` (also requires step-up).
|
|
92
92
|
|
|
93
|
+
Contract-template scopes (added in v1.5.0; originally planned as v1.10.0 — see
|
|
94
|
+
CHANGELOG §"S5:合同模板") are split by direction and do not require step-up:
|
|
95
|
+
|
|
96
|
+
- `ScopeComplianceContractTemplateRead` — `getContractTemplate`,
|
|
97
|
+
`listContractTemplates`, `listContractTemplateVersions`.
|
|
98
|
+
- `ScopeComplianceContractTemplateWrite` — `createContractTemplate`,
|
|
99
|
+
`updateContractTemplate`, `deleteContractTemplate`,
|
|
100
|
+
`uploadContractTemplatePdf`, `publishContractTemplate`,
|
|
101
|
+
`archiveContractTemplate`. Tokens issued before v1.5.0 do **not** carry these
|
|
102
|
+
scopes; existing users must re-authorize so the new scopes are granted.
|
|
103
|
+
|
|
93
104
|
## Base URL
|
|
94
105
|
|
|
95
106
|
`Client` keeps the existing model gateway path under `/api/v4`. Compliance uses
|
|
@@ -231,6 +242,403 @@ if (view.status === 'SUCCESS') {
|
|
|
231
242
|
}
|
|
232
243
|
```
|
|
233
244
|
|
|
245
|
+
## Paginated Lists
|
|
246
|
+
|
|
247
|
+
Since v1.5.0 (originally planned as v1.6.0 — see CHANGELOG §"S1:6 个分页列表")
|
|
248
|
+
the SDK exposes paginated list reads against the backend
|
|
249
|
+
compliance gateway (`GET .../page`). Each returns a yudao `PageResult<T>`
|
|
250
|
+
(`{ total, list }` — the single SDK-wide pagination result shape, an alias of
|
|
251
|
+
`YudaoPageResult<T>`):
|
|
252
|
+
|
|
253
|
+
```ts
|
|
254
|
+
import type { PageResult, EvidenceAssetPageItem } from '@acosmi/sdk-ts';
|
|
255
|
+
|
|
256
|
+
client.compliance.listEvidenceAssets(req?, signal?): Promise<PageResult<EvidenceAssetPageItem>>;
|
|
257
|
+
client.compliance.listTimestamps(req?, signal?): Promise<PageResult<TimestampPageItem>>;
|
|
258
|
+
client.compliance.listEvidencePackages(req?, signal?): Promise<PageResult<EvidencePackagePageItem>>;
|
|
259
|
+
client.compliance.listReports(req?, signal?): Promise<PageResult<ReportPageItem>>;
|
|
260
|
+
client.compliance.listSigningEnvelopes(req?, signal?): Promise<PageResult<SigningEnvelopePageItem>>;
|
|
261
|
+
client.compliance.listSealApprovals(req?, signal?): Promise<PageResult<SealApprovalPageItem>>;
|
|
262
|
+
client.compliance.listSealUses(req?, signal?): Promise<PageResult<SealUsePageItem>>;
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
The request argument is optional. It extends the shared `PageRequest`
|
|
266
|
+
(`pageNo`, `pageSize`, `sortBy`, `sortDirection` — all optional; omitted values
|
|
267
|
+
let the backend pick defaults) plus per-method filters:
|
|
268
|
+
|
|
269
|
+
| Method | Endpoint | Filters (all optional) |
|
|
270
|
+
| --- | --- | --- |
|
|
271
|
+
| `listEvidenceAssets` | `GET /compliance/evidence/assets/page` | `assetType`, `status`, `createTimeStart`, `createTimeEnd` |
|
|
272
|
+
| `listTimestamps` | `GET /compliance/timestamps/page` | `provider`, `verificationStatus`, `createTimeStart`, `createTimeEnd` |
|
|
273
|
+
| `listEvidencePackages` | `GET /compliance/evidence/packages/page` | `status`, `createTimeStart`, `createTimeEnd` |
|
|
274
|
+
| `listReports` | `GET /compliance/reports/page` | `status`, `createTimeStart`, `createTimeEnd` |
|
|
275
|
+
| `listSigningEnvelopes` | `GET /compliance/signing-envelopes/page` | `status`, `createTimeStart`, `createTimeEnd` |
|
|
276
|
+
| `listSealApprovals` | `GET /compliance/seal-approvals/page` | `status`, `createTimeStart`, `createTimeEnd` |
|
|
277
|
+
| `listSealUses` | `GET /compliance/seal-uses/page` | `sealId`, `envelopeId`, `usageStatus`, `createTimeStart`, `createTimeEnd` |
|
|
278
|
+
|
|
279
|
+
`createTimeStart` / `createTimeEnd` are caller-supplied datetime **strings**. The
|
|
280
|
+
backend parses them as `yyyy-MM-dd HH:mm:ss` (for example
|
|
281
|
+
`'2026-05-01 00:00:00'`). The SDK passes them through verbatim — it does not
|
|
282
|
+
validate the format or convert time zones.
|
|
283
|
+
|
|
284
|
+
```ts
|
|
285
|
+
const page = await client.compliance.listSealApprovals({
|
|
286
|
+
pageNo: 1,
|
|
287
|
+
pageSize: 20,
|
|
288
|
+
status: 'PENDING',
|
|
289
|
+
createTimeStart: '2026-05-01 00:00:00',
|
|
290
|
+
createTimeEnd: '2026-05-22 23:59:59',
|
|
291
|
+
});
|
|
292
|
+
|
|
293
|
+
console.log(page.total, page.list.length);
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
These are authenticated GET reads, so they follow the same read semantics as
|
|
297
|
+
`getEvidenceAsset` / `getReport`: one safe `401` refresh-and-replay retry.
|
|
298
|
+
|
|
299
|
+
`listSealApprovals` is distinct from `listPendingSealApprovals` — the latter
|
|
300
|
+
returns only pending approvals as a plain array; `listSealApprovals` is paginated
|
|
301
|
+
and supports status / time filtering.
|
|
302
|
+
|
|
303
|
+
The `*PageItem` types (`EvidenceAssetPageItem`, `TimestampPageItem`,
|
|
304
|
+
`EvidencePackagePageItem`, `ReportPageItem`, `SigningEnvelopePageItem`,
|
|
305
|
+
`SealApprovalPageItem`, `SealUsePageItem`) are the SDK-safe subset of the
|
|
306
|
+
corresponding detail view plus a `createTime` (ISO-8601) field. They never
|
|
307
|
+
expose provider raw payloads, certificates, storage keys, or contract originals.
|
|
308
|
+
|
|
309
|
+
`listSealUses` (compliance gateway S6) returns one row per **seal use** — the
|
|
310
|
+
real `provider`-side seal application that fires after envelope / contract /
|
|
311
|
+
seal / approval are linked. It is orthogonal to the envelope domain status and
|
|
312
|
+
to the seal-approval workflow:
|
|
313
|
+
|
|
314
|
+
- `listSigningEnvelopes` → high-level envelope domain state.
|
|
315
|
+
- `listSealApprovals` → the approval workflow on an envelope (`PENDING` →
|
|
316
|
+
`APPROVED` / `REJECTED` / `CANCELED`).
|
|
317
|
+
- `listSealUses` → the actual seal-application execution
|
|
318
|
+
(`invokedAt` → `consumedAt`, with `failureReason` on terminal failure).
|
|
319
|
+
|
|
320
|
+
`SealUsePageItem` fields: `id` (number), `envelopeId` (number), `contractId`
|
|
321
|
+
(number), `sealId` (number), `usageStatus` (string), `signLocationType`
|
|
322
|
+
(string?), `invokedAt` (string?), `consumedAt` (string?), `failureReason`
|
|
323
|
+
(string?), `createTime` (string — ISO-8601).
|
|
324
|
+
|
|
325
|
+
`listSealUses` reuses the existing read scope
|
|
326
|
+
`ScopeComplianceContractSigningRead` (`compliance:contract_signing:read`); it
|
|
327
|
+
does not introduce a new scope. The seal authorization surface and the full
|
|
328
|
+
seal CRUD (gap-register U-3 / U-11) remain backend-deferred behind the CFCA
|
|
329
|
+
private jar and the W3 gate, and are not exposed as SDK methods in this
|
|
330
|
+
release.
|
|
331
|
+
|
|
332
|
+
## Capabilities And Operation Projection
|
|
333
|
+
|
|
334
|
+
Since v1.5.0 (originally planned as v1.7.0 — see CHANGELOG §"S2:capabilities +
|
|
335
|
+
operations 投影") the SDK exposes the compliance gateway S2 reads: a capability gate
|
|
336
|
+
query and an operation-projection view.
|
|
337
|
+
|
|
338
|
+
```ts
|
|
339
|
+
client.compliance.getCapabilities(signal?): Promise<ComplianceCapability[]>;
|
|
340
|
+
client.compliance.getFeatureGate(action, signal?): Promise<ComplianceCapability | undefined>;
|
|
341
|
+
client.compliance.listOperations(req?, signal?): Promise<PageResult<OperationPageItem>>;
|
|
342
|
+
client.compliance.getOperation(id, signal?): Promise<OperationDetail>;
|
|
343
|
+
```
|
|
344
|
+
|
|
345
|
+
All four are authenticated GET reads — they follow the same read semantics as
|
|
346
|
+
`getReport` / `getEvidenceAsset`: one safe `401` refresh-and-replay retry.
|
|
347
|
+
|
|
348
|
+
### Capabilities
|
|
349
|
+
|
|
350
|
+
`getCapabilities` returns one `ComplianceCapability` entry per high-risk /
|
|
351
|
+
billed action: `signEnvelope`, `createH5SigningUrl`, `publishReport`,
|
|
352
|
+
`approveSealApproval`, `executeSealUse`, `createSeal`.
|
|
353
|
+
|
|
354
|
+
```ts
|
|
355
|
+
const caps = await client.compliance.getCapabilities();
|
|
356
|
+
for (const cap of caps) {
|
|
357
|
+
console.log(cap.action, cap.executable, cap.state, cap.requiredScopes);
|
|
358
|
+
}
|
|
359
|
+
```
|
|
360
|
+
|
|
361
|
+
`ComplianceCapability` fields: `action` (string), `executable` (boolean),
|
|
362
|
+
`state` (`executable` / `scope_missing` / `not_provisioned` /
|
|
363
|
+
`step_up_required` / `gate_closed` / `unknown` — reuses the cross-domain
|
|
364
|
+
`FeatureGateState` open union), `requiredScopes` (string[]), `requiredStepUp`
|
|
365
|
+
(boolean), `reason` (string).
|
|
366
|
+
|
|
367
|
+
Query the capability **before** invoking a high-risk action and gate the UI on
|
|
368
|
+
it. When the capability cannot be fetched, fail-closed — treat the action as
|
|
369
|
+
`executable: false`.
|
|
370
|
+
|
|
371
|
+
`getFeatureGate` is a convenience that fetches `getCapabilities` and returns the
|
|
372
|
+
entry whose `action` matches (or `undefined` when none match). **Each call makes
|
|
373
|
+
one network request.** To gate several actions, call `getCapabilities` once and
|
|
374
|
+
look them up locally instead of calling `getFeatureGate` repeatedly.
|
|
375
|
+
|
|
376
|
+
```ts
|
|
377
|
+
const gate = await client.compliance.getFeatureGate('publishReport');
|
|
378
|
+
if (!gate || !gate.executable) {
|
|
379
|
+
if (gate?.state === 'step_up_required') {
|
|
380
|
+
await promptUserToReauthenticate();
|
|
381
|
+
}
|
|
382
|
+
return; // fail-closed
|
|
383
|
+
}
|
|
384
|
+
```
|
|
385
|
+
|
|
386
|
+
### Operation Projection
|
|
387
|
+
|
|
388
|
+
The operation projection describes the progress of a single operation — it is
|
|
389
|
+
orthogonal to a fulfillment object's domain status.
|
|
390
|
+
|
|
391
|
+
```ts
|
|
392
|
+
const page = await client.compliance.listOperations({
|
|
393
|
+
pageNo: 1,
|
|
394
|
+
pageSize: 20,
|
|
395
|
+
status: 'failed',
|
|
396
|
+
createTimeStart: '2026-05-01 00:00:00',
|
|
397
|
+
createTimeEnd: '2026-05-22 23:59:59',
|
|
398
|
+
});
|
|
399
|
+
|
|
400
|
+
for (const op of page.list) {
|
|
401
|
+
console.log(op.id, op.operationId, op.status, op.terminal, op.retryable);
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
const detail = await client.compliance.getOperation(page.list[0].id);
|
|
405
|
+
```
|
|
406
|
+
|
|
407
|
+
`listOperations` (`GET /compliance/operations/page`) returns a yudao
|
|
408
|
+
`PageResult<OperationPageItem>`. Its request extends the shared `PageRequest`
|
|
409
|
+
plus the optional `status` / `createTimeStart` / `createTimeEnd` filters.
|
|
410
|
+
`getOperation` (`GET /compliance/operations/{id}`) takes the numeric **row id**
|
|
411
|
+
(not the `operationId` idempotency key) and returns `OperationDetail`.
|
|
412
|
+
|
|
413
|
+
`OperationPageItem` / `OperationDetail` fields: `id` (number), `operationId`
|
|
414
|
+
(string — the idempotency key), `status` (string), `terminal` (boolean),
|
|
415
|
+
`retryable` (boolean), `attemptCount` (number), `businessNo` (string?),
|
|
416
|
+
`contractNo` (string?), `sealId` (number?), `reconciliationStatus` (string?),
|
|
417
|
+
`nextRetryAt` (string?), `requestedAt` (string?), `respondedAt` (string?),
|
|
418
|
+
`createTime` (string). Time fields are ISO-8601. These views never expose
|
|
419
|
+
provider raw payloads, certificates, storage keys, or contract originals.
|
|
420
|
+
|
|
421
|
+
`createTimeStart` / `createTimeEnd` are caller-supplied datetime strings parsed
|
|
422
|
+
by the backend as `yyyy-MM-dd HH:mm:ss`; the SDK passes them through verbatim.
|
|
423
|
+
|
|
424
|
+
## TSA Readonly Views
|
|
425
|
+
|
|
426
|
+
Since v1.5.0 (originally planned as v1.8.0 — see CHANGELOG §"S3:TSA readonly
|
|
427
|
+
视图") the SDK exposes the compliance gateway S3 reads: two timestamp
|
|
428
|
+
authority (TSA) readonly views.
|
|
429
|
+
|
|
430
|
+
```ts
|
|
431
|
+
client.compliance.listTsaProviders(signal?): Promise<TsaProvider[]>;
|
|
432
|
+
client.compliance.getTsaStats(signal?): Promise<TsaStats>;
|
|
433
|
+
```
|
|
434
|
+
|
|
435
|
+
Both are authenticated GET reads — they follow the same read semantics as
|
|
436
|
+
`getReport` / `getCapabilities`: one safe `401` refresh-and-replay retry.
|
|
437
|
+
|
|
438
|
+
`listTsaProviders` (`GET /compliance/timestamps/providers`) returns one
|
|
439
|
+
`TsaProvider` entry per configured TSA provider.
|
|
440
|
+
|
|
441
|
+
```ts
|
|
442
|
+
const providers = await client.compliance.listTsaProviders();
|
|
443
|
+
for (const p of providers) {
|
|
444
|
+
console.log(p.name, p.environment, p.available);
|
|
445
|
+
}
|
|
446
|
+
```
|
|
447
|
+
|
|
448
|
+
`TsaProvider` fields: `name` (string), `environment` (string — for example
|
|
449
|
+
`production` / `sandbox`), `available` (boolean). It is a readonly view — it
|
|
450
|
+
never exposes provider endpoints, credentials, certificates, or other internal
|
|
451
|
+
integration material.
|
|
452
|
+
|
|
453
|
+
`getTsaStats` (`GET /compliance/timestamps/stats`) returns a readonly
|
|
454
|
+
aggregation: the total timestamp count plus a per-verification-status count map.
|
|
455
|
+
|
|
456
|
+
```ts
|
|
457
|
+
const stats = await client.compliance.getTsaStats();
|
|
458
|
+
console.log(stats.total);
|
|
459
|
+
console.log(stats.byVerificationStatus.VERIFIED ?? 0);
|
|
460
|
+
```
|
|
461
|
+
|
|
462
|
+
`TsaStats` fields: `total` (number), `byVerificationStatus`
|
|
463
|
+
(`Record<string, number>` — keys are verification-status enum names such as
|
|
464
|
+
`VERIFIED` / `PENDING` / `FAILED`, values are counts). The map may be empty
|
|
465
|
+
when no timestamps exist.
|
|
466
|
+
|
|
467
|
+
## Envelope Completion
|
|
468
|
+
|
|
469
|
+
Since v1.5.0 (originally planned as v1.9.0 — see CHANGELOG §"S4:envelope 收尾
|
|
470
|
+
+ void") the SDK exposes the compliance gateway S4 envelope-completion
|
|
471
|
+
surface: two readonly views and one write.
|
|
472
|
+
|
|
473
|
+
```ts
|
|
474
|
+
client.compliance.listEnvelopeContracts(envelopeId, signal?): Promise<EnvelopeContractItem[]>;
|
|
475
|
+
client.compliance.listEnvelopeProviderRequests(envelopeId, signal?): Promise<OperationPageItem[]>;
|
|
476
|
+
client.compliance.voidEnvelope(envelopeId, req, options?): Promise<boolean>;
|
|
477
|
+
```
|
|
478
|
+
|
|
479
|
+
`listEnvelopeContracts` (`GET /compliance/signing-envelopes/{id}/contracts`)
|
|
480
|
+
and `listEnvelopeProviderRequests`
|
|
481
|
+
(`GET /compliance/signing-envelopes/{id}/provider-requests`) are authenticated
|
|
482
|
+
GET reads — they follow the same read semantics as `getReport` /
|
|
483
|
+
`getCapabilities`: one safe `401` refresh-and-replay retry. Both return a plain
|
|
484
|
+
array (not a `PageResult`).
|
|
485
|
+
|
|
486
|
+
```ts
|
|
487
|
+
const contracts = await client.compliance.listEnvelopeContracts(envelopeId);
|
|
488
|
+
for (const c of contracts) {
|
|
489
|
+
console.log(c.contractNo, c.title, c.status, c.contentHash);
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
const providerRequests =
|
|
493
|
+
await client.compliance.listEnvelopeProviderRequests(envelopeId);
|
|
494
|
+
for (const op of providerRequests) {
|
|
495
|
+
console.log(op.operationId, op.status, op.terminal, op.retryable);
|
|
496
|
+
}
|
|
497
|
+
```
|
|
498
|
+
|
|
499
|
+
`EnvelopeContractItem` fields: `id` (number), `envelopeId` (number),
|
|
500
|
+
`contractNo` (string), `title` (string), `mimeType` (string), `size` (number),
|
|
501
|
+
`hashAlgorithm` (string), `contentHash` (string), `signedContentHash`
|
|
502
|
+
(string?), `status` (string), `createTime` (string — ISO-8601). It is a
|
|
503
|
+
SDK-safe view — it never exposes contract originals, storage keys, or provider
|
|
504
|
+
raw payloads.
|
|
505
|
+
|
|
506
|
+
`listEnvelopeProviderRequests` **reuses** the operation-projection type
|
|
507
|
+
`OperationPageItem` (see *Capabilities And Operation Projection*); it describes
|
|
508
|
+
the progress of each provider request, orthogonal to the envelope's domain
|
|
509
|
+
status.
|
|
510
|
+
|
|
511
|
+
`voidEnvelope` (`POST /compliance/signing-envelopes/{id}/void`) is a **write**.
|
|
512
|
+
It follows the compliance write rules — it accepts the `Idempotency-Key`
|
|
513
|
+
header, does not auto-retry on 5xx / timeouts, and does not refresh/replay on
|
|
514
|
+
`401`. The void reason is required and is sent in the JSON body:
|
|
515
|
+
|
|
516
|
+
```ts
|
|
517
|
+
const voided = await client.compliance.voidEnvelope(
|
|
518
|
+
envelopeId,
|
|
519
|
+
{ reason: 'signed in error' },
|
|
520
|
+
{ idempotencyKey: voidKey },
|
|
521
|
+
);
|
|
522
|
+
```
|
|
523
|
+
|
|
524
|
+
`VoidEnvelopeRequest` is `{ reason: string }`. Persist the idempotency key on
|
|
525
|
+
the caller side and reuse it when resuming the same void action.
|
|
526
|
+
|
|
527
|
+
Envelope completion actions beyond this S4 subset — send, remind, authorize,
|
|
528
|
+
download, and token — are deferred backend-side and are not exposed as SDK
|
|
529
|
+
methods in this release.
|
|
530
|
+
|
|
531
|
+
## Contract Templates
|
|
532
|
+
|
|
533
|
+
Since v1.5.0 (originally planned as v1.10.0 — see CHANGELOG §"S5:合同模板")
|
|
534
|
+
the SDK exposes the compliance gateway S5 contract-template
|
|
535
|
+
surface: a `DRAFT` → `PUBLISHED` → `ARCHIVED` lifecycle with PDF upload, field
|
|
536
|
+
overlay, and immutable version snapshots.
|
|
537
|
+
|
|
538
|
+
```ts
|
|
539
|
+
client.compliance.createContractTemplate(req, options?): Promise<ContractTemplateResp>;
|
|
540
|
+
client.compliance.updateContractTemplate(id, req, options?): Promise<ContractTemplateResp>;
|
|
541
|
+
client.compliance.deleteContractTemplate(id, options?): Promise<void>;
|
|
542
|
+
client.compliance.getContractTemplate(id, signal?): Promise<ContractTemplateResp>;
|
|
543
|
+
client.compliance.listContractTemplates(req?, signal?): Promise<PageResult<ContractTemplatePageItem>>;
|
|
544
|
+
client.compliance.uploadContractTemplatePdf(id, req, options?): Promise<ContractTemplateResp>;
|
|
545
|
+
client.compliance.publishContractTemplate(id, options?): Promise<ContractTemplateResp>;
|
|
546
|
+
client.compliance.archiveContractTemplate(id, options?): Promise<ContractTemplateResp>;
|
|
547
|
+
client.compliance.listContractTemplateVersions(id, signal?): Promise<ContractTemplateVersion[]>;
|
|
548
|
+
```
|
|
549
|
+
|
|
550
|
+
Lifecycle:
|
|
551
|
+
|
|
552
|
+
```ts
|
|
553
|
+
// 1) Create in DRAFT.
|
|
554
|
+
const tpl = await client.compliance.createContractTemplate(
|
|
555
|
+
{ name: 'Mutual NDA', description: 'standard NDA' },
|
|
556
|
+
{ idempotencyKey: createKey },
|
|
557
|
+
);
|
|
558
|
+
|
|
559
|
+
// 2) Upload PDF body (base64-encoded). pdfHash / pdfPageCount come back on the
|
|
560
|
+
// returned ContractTemplateResp.
|
|
561
|
+
const withPdf = await client.compliance.uploadContractTemplatePdf(
|
|
562
|
+
tpl.id,
|
|
563
|
+
{ pdfBase64: readPdfBase64() },
|
|
564
|
+
{ idempotencyKey: uploadKey },
|
|
565
|
+
);
|
|
566
|
+
|
|
567
|
+
// 3) Edit the field overlay (signatures / seals / text / date / check). Only
|
|
568
|
+
// allowed while the template is still DRAFT.
|
|
569
|
+
await client.compliance.updateContractTemplate(
|
|
570
|
+
tpl.id,
|
|
571
|
+
{
|
|
572
|
+
fields: [
|
|
573
|
+
{
|
|
574
|
+
key: 'sig-partyA',
|
|
575
|
+
type: 'signature',
|
|
576
|
+
label: 'Party A signature',
|
|
577
|
+
page: 1,
|
|
578
|
+
x: 100,
|
|
579
|
+
y: 200,
|
|
580
|
+
width: 80,
|
|
581
|
+
height: 30,
|
|
582
|
+
assignedRole: 'partyA',
|
|
583
|
+
order: 0,
|
|
584
|
+
required: true,
|
|
585
|
+
},
|
|
586
|
+
],
|
|
587
|
+
},
|
|
588
|
+
{ idempotencyKey: updateKey },
|
|
589
|
+
);
|
|
590
|
+
|
|
591
|
+
// 4) Publish — DRAFT → PUBLISHED. currentVersion increments and the fields +
|
|
592
|
+
// pdfHash are frozen into the version table.
|
|
593
|
+
const published = await client.compliance.publishContractTemplate(tpl.id, {
|
|
594
|
+
idempotencyKey: publishKey,
|
|
595
|
+
});
|
|
596
|
+
|
|
597
|
+
// 5) Optionally archive a published template — PUBLISHED → ARCHIVED. Archived
|
|
598
|
+
// templates are read-only.
|
|
599
|
+
await client.compliance.archiveContractTemplate(tpl.id, {
|
|
600
|
+
idempotencyKey: archiveKey,
|
|
601
|
+
});
|
|
602
|
+
```
|
|
603
|
+
|
|
604
|
+
`createContractTemplate`, `updateContractTemplate`, `deleteContractTemplate`,
|
|
605
|
+
`uploadContractTemplatePdf`, `publishContractTemplate`, and
|
|
606
|
+
`archiveContractTemplate` are **writes**. They follow the compliance write
|
|
607
|
+
rules — they accept the `Idempotency-Key` header, do not auto-retry on 5xx /
|
|
608
|
+
timeouts, and do not refresh/replay on `401`. Persist the idempotency key on
|
|
609
|
+
the caller side and reuse it when resuming the same action (especially
|
|
610
|
+
`uploadContractTemplatePdf`, which costs bandwidth to retry).
|
|
611
|
+
|
|
612
|
+
`updateContractTemplate` and `deleteContractTemplate` are **DRAFT-only**. The
|
|
613
|
+
backend refuses both on `PUBLISHED` / `ARCHIVED` templates — for a published
|
|
614
|
+
template, switch to `archiveContractTemplate` instead of deleting it.
|
|
615
|
+
|
|
616
|
+
`uploadContractTemplatePdf` takes `{ pdfBase64 }` in the request body. The SDK
|
|
617
|
+
does not parse the PDF, validate geometry, or compute the hash on the
|
|
618
|
+
client — those happen on the backend. `pdfHash` and `pdfPageCount` come back on
|
|
619
|
+
the returned `ContractTemplateResp`.
|
|
620
|
+
|
|
621
|
+
`getContractTemplate`, `listContractTemplates`, and
|
|
622
|
+
`listContractTemplateVersions` are authenticated GET reads — they follow the
|
|
623
|
+
same read semantics as `getReport` / `getCapabilities`: one safe `401`
|
|
624
|
+
refresh-and-replay retry.
|
|
625
|
+
|
|
626
|
+
`listContractTemplates` returns a `PageResult<ContractTemplatePageItem>`. The
|
|
627
|
+
list-item view deliberately omits `fields` to avoid large-object N+1 on the
|
|
628
|
+
list endpoint — the field overlay is only present on the detail
|
|
629
|
+
(`ContractTemplateResp`) and on each version snapshot
|
|
630
|
+
(`ContractTemplateVersion`).
|
|
631
|
+
|
|
632
|
+
`listContractTemplateVersions` returns a plain array (not a `PageResult`).
|
|
633
|
+
Every `publishContractTemplate` call appends one immutable
|
|
634
|
+
`ContractTemplateVersion` — capturing the template's `name`, `pdfHash`,
|
|
635
|
+
`fields`, and `statusAtSnapshot` at publish time — and is the offline-review
|
|
636
|
+
ground truth for the version.
|
|
637
|
+
|
|
638
|
+
The 9 methods do **not** require step-up. They require the new
|
|
639
|
+
`ScopeComplianceContractTemplateRead` (reads) or
|
|
640
|
+
`ScopeComplianceContractTemplateWrite` (writes) scope.
|
|
641
|
+
|
|
234
642
|
## Error Classification
|
|
235
643
|
|
|
236
644
|
Compliance business errors are returned as numeric Java error codes in the
|
|
@@ -252,6 +660,16 @@ switch (info.key) {
|
|
|
252
660
|
`CompliancePollError` is used by polling helpers for terminal failure, timeout,
|
|
253
661
|
abort, and unknown states.
|
|
254
662
|
|
|
663
|
+
Since v1.5.0, `complianceErrorToRetryAdvice(info)` projects a `ComplianceErrorInfo`
|
|
664
|
+
into the cross-domain `RetryAdvice` model (`retryable` / `retryAfter` /
|
|
665
|
+
`sameIdempotencyKeyRequired` / `manualActionRequired` / `reason` / messages /
|
|
666
|
+
`supportCode`). It is an additive, read-only projection — it does not modify or
|
|
667
|
+
replace `ComplianceErrorInfo`; `classifyComplianceError` is unchanged. The
|
|
668
|
+
`reason` field is a normalized mapping of the existing error-code registries, not
|
|
669
|
+
a new code set. Terminal errors advise a fresh idempotency key
|
|
670
|
+
(`sameIdempotencyKeyRequired: false`); step-up errors advise re-authenticating
|
|
671
|
+
and retrying with the same key.
|
|
672
|
+
|
|
255
673
|
## Method Status
|
|
256
674
|
|
|
257
675
|
Each `client.compliance.*` method has one of four maturity grades. Treat this
|
|
@@ -261,9 +679,9 @@ for them.
|
|
|
261
679
|
|
|
262
680
|
| Status | Methods | Meaning |
|
|
263
681
|
| --- | --- | --- |
|
|
264
|
-
| `production-ready` | `createEvidenceAsset`, `getEvidenceAsset`, `verifyEvidencePublic`, `issueTimestamp`, `issueTimestampForAsset`, `getTimestamp`, `verifyTimestamp`, `waitForTimestampVerified`, `buildEvidencePackage`, `createReport`, `getReport`, `downloadReport`, `createSigningEnvelope`, `getSigningEnvelope`, `syncSigningEnvelopeStatus`, `submitSealApproval`, `rejectSealApproval`, `cancelSealApproval`, `listPendingSealApprovals`, `getSealApproval`, `getProviderRequest`, `waitForProviderRequestTerminal`, `classifyError` | Backend endpoint, scope, DTO contract, SDK tests and docs are all closed. Safe to call in production. |
|
|
682
|
+
| `production-ready` | `createEvidenceAsset`, `getEvidenceAsset`, `verifyEvidencePublic`, `listEvidenceAssets`, `listEvidencePackages`, `issueTimestamp`, `issueTimestampForAsset`, `getTimestamp`, `verifyTimestamp`, `waitForTimestampVerified`, `listTimestamps`, `listTsaProviders`, `getTsaStats`, `buildEvidencePackage`, `createReport`, `getReport`, `downloadReport`, `listReports`, `createSigningEnvelope`, `getSigningEnvelope`, `syncSigningEnvelopeStatus`, `listSigningEnvelopes`, `listEnvelopeContracts`, `listEnvelopeProviderRequests`, `voidEnvelope`, `createContractTemplate`, `updateContractTemplate`, `deleteContractTemplate`, `getContractTemplate`, `listContractTemplates`, `uploadContractTemplatePdf`, `publishContractTemplate`, `archiveContractTemplate`, `listContractTemplateVersions`, `submitSealApproval`, `rejectSealApproval`, `cancelSealApproval`, `listPendingSealApprovals`, `getSealApproval`, `listSealApprovals`, `listSealUses`, `getProviderRequest`, `waitForProviderRequestTerminal`, `getCapabilities`, `getFeatureGate`, `listOperations`, `getOperation`, `classifyError` | Backend endpoint, scope, DTO contract, SDK tests and docs are all closed. Safe to call in production. |
|
|
265
683
|
| `gated` | `publishReport`, `signEnvelope`, `createH5SigningUrl`, `approveSealApproval` | SDK exposes the method, but the backend fails-closed (`COMPLIANCE_STEP_UP_REQUIRED` / `ENVELOPE_GATE_CLOSED`) until step-up and the W3 gate chain are ready. The SDK does not retry and does not fake success — surface the typed error as "feature not yet open". |
|
|
266
|
-
| `draft contract` |
|
|
684
|
+
| `draft contract` | binary download helpers | Type drafts only — not exposed as callable capability in this release. |
|
|
267
685
|
| `internal-only` | distribution billing (`reserve` / `commit` / `cancel` / `reconcile` / `refund`), provider raw payloads, provider callbacks, CFCA controlled materials | Server-side S2S only. Never part of the SDK call surface; no SDK method exists for these. |
|
|
268
686
|
|
|
269
687
|
`submitSealApproval` is `production-ready`: the backend enforces
|
|
@@ -271,6 +689,43 @@ for them.
|
|
|
271
689
|
with the same key returns the original approval id instead of creating a
|
|
272
690
|
duplicate. Persist the idempotency key on the caller side.
|
|
273
691
|
|
|
692
|
+
`getCapabilities`, `getFeatureGate`, `listOperations`, and `getOperation` are
|
|
693
|
+
`production-ready` against the compliance gateway S2 (`G2`) contract — endpoint,
|
|
694
|
+
DTO, SDK tests, and docs are closed. They are read-only GET projections and do
|
|
695
|
+
not themselves carry step-up or gate state; `getCapabilities` *reports* whether
|
|
696
|
+
the gated actions are currently executable.
|
|
697
|
+
|
|
698
|
+
`listTsaProviders` and `getTsaStats` are `production-ready` against the
|
|
699
|
+
compliance gateway S3 (`G3`) contract — endpoint, DTO, SDK tests, and docs are
|
|
700
|
+
closed. They are read-only GET projections of timestamp authority state and
|
|
701
|
+
aggregate counts; they carry no step-up or gate state.
|
|
702
|
+
|
|
703
|
+
`listEnvelopeContracts`, `listEnvelopeProviderRequests`, and `voidEnvelope` are
|
|
704
|
+
`production-ready` against the compliance gateway S4 (`G4`) contract — endpoint,
|
|
705
|
+
DTO, SDK tests, and docs are closed. The two `list*` methods are read-only GET
|
|
706
|
+
projections; `voidEnvelope` is a write that accepts `Idempotency-Key`, does not
|
|
707
|
+
auto-retry, and does not refresh/replay on `401`. Send / remind / authorize /
|
|
708
|
+
download / token actions are deferred backend-side and have no SDK method.
|
|
709
|
+
|
|
710
|
+
The 9 contract-template methods — `createContractTemplate`,
|
|
711
|
+
`updateContractTemplate`, `deleteContractTemplate`, `getContractTemplate`,
|
|
712
|
+
`listContractTemplates`, `uploadContractTemplatePdf`,
|
|
713
|
+
`publishContractTemplate`, `archiveContractTemplate`,
|
|
714
|
+
`listContractTemplateVersions` — are `production-ready` against the compliance
|
|
715
|
+
gateway S5 (`G5`) contract: endpoint, DTO, SDK tests, and docs are closed. Reads
|
|
716
|
+
are GET (one safe `401` refresh-and-replay); writes accept `Idempotency-Key`,
|
|
717
|
+
do not auto-retry, and do not refresh/replay on `401`. None of them require
|
|
718
|
+
step-up. `updateContractTemplate` and `deleteContractTemplate` are
|
|
719
|
+
DRAFT-only — the backend refuses both on `PUBLISHED` / `ARCHIVED` templates.
|
|
720
|
+
|
|
721
|
+
`listSealUses` is `production-ready` against the compliance gateway S6 (`G6`)
|
|
722
|
+
contract — endpoint, DTO, SDK tests, and docs are closed. It is a read-only
|
|
723
|
+
GET projection (one safe `401` refresh-and-replay) and reuses the existing
|
|
724
|
+
`ScopeComplianceContractSigningRead` scope; no new scope is introduced. The
|
|
725
|
+
broader seal authorization layer and seal CRUD surface (gap-register U-3 /
|
|
726
|
+
U-11) remain backend-deferred behind the CFCA private jar and the W3 gate;
|
|
727
|
+
they are intentionally **not** exposed as SDK methods in this release.
|
|
728
|
+
|
|
274
729
|
## Safety Boundary
|
|
275
730
|
|
|
276
731
|
Do not place any of the following in SDK code, tests, examples, docs, git
|
|
@@ -11,8 +11,12 @@
|
|
|
11
11
|
// 说明:
|
|
12
12
|
// - 大多数场景直接用 `client.login(appName, scopes)` 即可(内部封装了下面全部步骤)。
|
|
13
13
|
// 本示例演示底层 helper,适用于需要自定义授权流程 / 自管 token 的 CLI。
|
|
14
|
-
// - authorize 仅在 Node 环境可用(需要本地 HTTP 回调 server
|
|
15
|
-
//
|
|
14
|
+
// - authorize 仅在 Node 环境可用(需要本地 HTTP 回调 server)。
|
|
15
|
+
// - 浏览器侧(无 loopback server)请改用 v1.4.0+ Web OAuth 原语:
|
|
16
|
+
// discoverWebOAuthMetadata + registerWebOAuthClient +
|
|
17
|
+
// createWebAuthorizationRequest + completeWebAuthorizationRequest,
|
|
18
|
+
// 由调用方实现 popup / 同窗口 redirect handler,SDK 负责 PKCE / state 校验 / token 兑换。
|
|
19
|
+
// 浏览器 token 刷新可配 Config.browserRefreshMode / refreshProxyURL (v1.4.1+) 规避 issuer CORS 403。
|
|
16
20
|
|
|
17
21
|
import {
|
|
18
22
|
discover,
|
|
@@ -22,6 +22,7 @@ import {
|
|
|
22
22
|
ScopeComplianceTimestampIssue,
|
|
23
23
|
ScopeComplianceTimestampVerify,
|
|
24
24
|
ScopeComplianceReportsRead,
|
|
25
|
+
ScopeComplianceReportsWrite,
|
|
25
26
|
} from '@acosmi/sdk-ts';
|
|
26
27
|
|
|
27
28
|
// 模拟持久化的 Idempotency-Key 存储;生产环境应落 DB / 本地文件 / 业务订单表。
|
|
@@ -51,7 +52,8 @@ async function main() {
|
|
|
51
52
|
ScopeComplianceEvidenceWrite,
|
|
52
53
|
ScopeComplianceTimestampIssue,
|
|
53
54
|
ScopeComplianceTimestampVerify,
|
|
54
|
-
ScopeComplianceReportsRead,
|
|
55
|
+
ScopeComplianceReportsRead, // getReport / downloadReport
|
|
56
|
+
ScopeComplianceReportsWrite, // createReport(v1.3.2 起从 read 切到独立 write scope)
|
|
55
57
|
]);
|
|
56
58
|
|
|
57
59
|
// 1) 本地 sha256 (用户业务内容)
|
package/examples/core-chat.ts
CHANGED
|
@@ -8,9 +8,12 @@
|
|
|
8
8
|
// 5. 流式 chatStreamWithUsage 并聚合 usage / 结算事件
|
|
9
9
|
//
|
|
10
10
|
// 说明:
|
|
11
|
-
// - SDK 自动按 ManagedModel 的
|
|
12
|
-
// 或 OpenAI adapter
|
|
11
|
+
// - SDK 自动按 ManagedModel 的 preferred_format / supported_formats(snake_case
|
|
12
|
+
// wire 字段)选 Anthropic 或 OpenAI adapter,调用方无需关心。详见
|
|
13
|
+
// src/models/adapters/index.ts:getAdapterForModel。
|
|
13
14
|
// - 金额 / 余额字段是 string(避免 JS number 精度损失),不要做浮点运算。
|
|
15
|
+
// - ChatRequest 走 snake_case wire 字段(max_tokens 等),与上游 Go json tag 对齐;
|
|
16
|
+
// ManagedModel 顶层多为 camelCase(modelId / isEnabled / inputModalities)。
|
|
14
17
|
|
|
15
18
|
import { Client, allScopes, FileTokenStore } from '@acosmi/sdk-ts';
|
|
16
19
|
|
package/package.json
CHANGED