@proveanything/smartlinks 1.6.7 → 1.7.0
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/dist/api/attestation.d.ts +22 -0
- package/dist/api/attestation.js +22 -0
- package/dist/api/attestations.d.ts +292 -0
- package/dist/api/attestations.js +405 -0
- package/dist/api/containers.d.ts +236 -0
- package/dist/api/containers.js +316 -0
- package/dist/api/index.d.ts +2 -0
- package/dist/api/index.js +2 -0
- package/dist/api/tags.d.ts +20 -1
- package/dist/api/tags.js +30 -0
- package/dist/docs/API_SUMMARY.md +701 -7
- package/dist/docs/app-manifest.md +430 -0
- package/dist/docs/attestations.md +498 -0
- package/dist/docs/container-tracking.md +437 -0
- package/dist/docs/deep-link-discovery.md +6 -6
- package/dist/docs/executor.md +554 -0
- package/dist/index.d.ts +3 -0
- package/dist/openapi.yaml +3110 -1323
- package/dist/types/appManifest.d.ts +152 -0
- package/dist/types/attestation.d.ts +12 -0
- package/dist/types/attestations.d.ts +237 -0
- package/dist/types/attestations.js +11 -0
- package/dist/types/containers.d.ts +186 -0
- package/dist/types/containers.js +10 -0
- package/dist/types/tags.d.ts +47 -3
- package/docs/API_SUMMARY.md +701 -7
- package/docs/app-manifest.md +430 -0
- package/docs/attestations.md +498 -0
- package/docs/container-tracking.md +437 -0
- package/docs/deep-link-discovery.md +6 -6
- package/docs/executor.md +554 -0
- package/openapi.yaml +3110 -1323
- package/package.json +1 -1
|
@@ -55,6 +55,129 @@ export interface AppContainerComponent {
|
|
|
55
55
|
optional?: string[];
|
|
56
56
|
};
|
|
57
57
|
}
|
|
58
|
+
/**
|
|
59
|
+
* A single navigable state exposed by a SmartLinks app.
|
|
60
|
+
* Used in both `app.manifest.json` (static routes) and `appConfig.linkable` (dynamic content entries).
|
|
61
|
+
*
|
|
62
|
+
* @example
|
|
63
|
+
* // In app.manifest.json — static routes, declared at build time
|
|
64
|
+
* { "title": "Gallery", "path": "/gallery" }
|
|
65
|
+
* { "title": "Advanced Settings", "path": "/settings", "params": { "tab": "advanced" } }
|
|
66
|
+
*
|
|
67
|
+
* // In appConfig.linkable — dynamic content, synced at runtime
|
|
68
|
+
* { "title": "About Us", "params": { "pageId": "about-us" } }
|
|
69
|
+
*/
|
|
70
|
+
export interface DeepLinkEntry {
|
|
71
|
+
/** Human-readable label shown in menus and offered to AI agents */
|
|
72
|
+
title: string;
|
|
73
|
+
/**
|
|
74
|
+
* Hash route path within the app (optional).
|
|
75
|
+
* Defaults to "/" if omitted.
|
|
76
|
+
* @example "/gallery"
|
|
77
|
+
*/
|
|
78
|
+
path?: string;
|
|
79
|
+
/**
|
|
80
|
+
* App-specific query params appended to the hash route URL.
|
|
81
|
+
* Do NOT include platform context params (collectionId, appId, productId, etc.) —
|
|
82
|
+
* those are injected by the platform automatically.
|
|
83
|
+
*/
|
|
84
|
+
params?: Record<string, string>;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Context object passed to every executor factory function.
|
|
88
|
+
*/
|
|
89
|
+
export interface ExecutorContext {
|
|
90
|
+
collectionId: string;
|
|
91
|
+
appId: string;
|
|
92
|
+
/** Pre-initialised SmartLinks SDK — passed in to avoid duplicate instances */
|
|
93
|
+
SL: any;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Input passed to an executor's `getSEO()` function.
|
|
97
|
+
* The server pre-fetches collection/product/proof and passes them in;
|
|
98
|
+
* avoid making extra SL calls inside getSEO() to stay within the 200ms budget.
|
|
99
|
+
*/
|
|
100
|
+
export interface SEOInput {
|
|
101
|
+
collectionId: string;
|
|
102
|
+
appId: string;
|
|
103
|
+
productId?: string;
|
|
104
|
+
proofId?: string;
|
|
105
|
+
SL: any;
|
|
106
|
+
/** Pre-fetched collection object */
|
|
107
|
+
collection?: Record<string, any>;
|
|
108
|
+
/** Pre-fetched product object */
|
|
109
|
+
product?: Record<string, any>;
|
|
110
|
+
/** Pre-fetched proof object */
|
|
111
|
+
proof?: Record<string, any>;
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Return value from an executor's `getSEO()` function.
|
|
115
|
+
* Singular fields (title, description, ogImage) use highest-priority-wins merging across apps.
|
|
116
|
+
* Additive fields (jsonLd, contentSummary, topics) are merged from all apps on the page.
|
|
117
|
+
*/
|
|
118
|
+
export interface SEOResult {
|
|
119
|
+
/** Page title — singular, highest `meta.seo.priority` wins */
|
|
120
|
+
title?: string;
|
|
121
|
+
/** Meta description — singular */
|
|
122
|
+
description?: string;
|
|
123
|
+
/** Open Graph image URL — singular */
|
|
124
|
+
ogImage?: string;
|
|
125
|
+
/** JSON-LD structured data — additive, concatenated from all apps */
|
|
126
|
+
jsonLd?: Record<string, any> | Record<string, any>[];
|
|
127
|
+
/** Plain text summary for AI crawlers — additive, concatenated */
|
|
128
|
+
contentSummary?: string;
|
|
129
|
+
/** Topic tags — additive, merged and deduplicated */
|
|
130
|
+
topics?: string[];
|
|
131
|
+
}
|
|
132
|
+
/** A single section returned by an executor's `getLLMContent()` function */
|
|
133
|
+
export interface LLMContentSection {
|
|
134
|
+
/** Section heading displayed in the rendered HTML and read by AI crawlers */
|
|
135
|
+
heading: string;
|
|
136
|
+
/** Markdown content */
|
|
137
|
+
content: string;
|
|
138
|
+
/** Sort order — lower numbers appear first (default: 100) */
|
|
139
|
+
order?: number;
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Input passed to an executor's `getLLMContent()` function.
|
|
143
|
+
* Similar to SEOInput but includes `pageSlug` for page-aware content.
|
|
144
|
+
* Timeout is 500ms (longer than SEO — LLM content may fetch app config).
|
|
145
|
+
*/
|
|
146
|
+
export interface LLMContentInput {
|
|
147
|
+
collectionId: string;
|
|
148
|
+
appId: string;
|
|
149
|
+
productId?: string;
|
|
150
|
+
proofId?: string;
|
|
151
|
+
SL: any;
|
|
152
|
+
collection?: Record<string, any>;
|
|
153
|
+
product?: Record<string, any>;
|
|
154
|
+
proof?: Record<string, any>;
|
|
155
|
+
/** Which page slug is being rendered */
|
|
156
|
+
pageSlug?: string;
|
|
157
|
+
}
|
|
158
|
+
/** Return value from an executor's `getLLMContent()` function */
|
|
159
|
+
export interface LLMContentResult {
|
|
160
|
+
sections: LLMContentSection[];
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* The `executor` block in `app.manifest.json`.
|
|
164
|
+
* Declares the executor bundle and its exported capabilities.
|
|
165
|
+
*/
|
|
166
|
+
export interface AppManifestExecutor {
|
|
167
|
+
files: AppManifestFiles;
|
|
168
|
+
/** Name of the factory function that creates a configured executor instance */
|
|
169
|
+
factory?: string;
|
|
170
|
+
/** All named exports from the bundle */
|
|
171
|
+
exports?: string[];
|
|
172
|
+
/** Human-readable description for AI orchestrators and admin UIs */
|
|
173
|
+
description?: string;
|
|
174
|
+
/** LLM content contract — declares the getLLMContent function and its timeout */
|
|
175
|
+
llmContent?: {
|
|
176
|
+
function: string;
|
|
177
|
+
timeout?: number;
|
|
178
|
+
responseShape?: Record<string, any>;
|
|
179
|
+
};
|
|
180
|
+
}
|
|
58
181
|
/**
|
|
59
182
|
* Shape of `app.admin.json` -- the separate admin configuration file pointed to
|
|
60
183
|
* by `AppManifest.admin`. Fetch this file yourself when you need setup / import /
|
|
@@ -149,6 +272,21 @@ export interface AppManifest {
|
|
|
149
272
|
version: string;
|
|
150
273
|
platformRevision?: string;
|
|
151
274
|
appId: string;
|
|
275
|
+
/**
|
|
276
|
+
* SEO configuration for this app.
|
|
277
|
+
* `priority` controls which app's singular fields (title, description, ogImage) win
|
|
278
|
+
* when multiple apps appear on the same page. Default is 0; higher wins.
|
|
279
|
+
*/
|
|
280
|
+
seo?: {
|
|
281
|
+
strategy?: 'executor' | string;
|
|
282
|
+
priority?: number;
|
|
283
|
+
contract?: {
|
|
284
|
+
function: string;
|
|
285
|
+
input?: string[];
|
|
286
|
+
timeout?: number;
|
|
287
|
+
responseShape?: Record<string, string>;
|
|
288
|
+
};
|
|
289
|
+
};
|
|
152
290
|
};
|
|
153
291
|
/**
|
|
154
292
|
* Relative path to the admin configuration file (e.g. `"app.admin.json"`).
|
|
@@ -167,6 +305,20 @@ export interface AppManifest {
|
|
|
167
305
|
files: AppManifestFiles;
|
|
168
306
|
components: AppContainerComponent[];
|
|
169
307
|
};
|
|
308
|
+
/**
|
|
309
|
+
* Static deep-linkable states built into this app.
|
|
310
|
+
* These are fixed routes that exist regardless of content — declared once at build time.
|
|
311
|
+
* Dynamic content entries (e.g. CMS pages) are stored separately in `appConfig.linkable`.
|
|
312
|
+
* Consumers should merge both sources to get the full set of navigable states.
|
|
313
|
+
* @see DeepLinkEntry
|
|
314
|
+
*/
|
|
315
|
+
linkable?: DeepLinkEntry[];
|
|
316
|
+
/**
|
|
317
|
+
* Executor bundle declaration. Present when the app ships a programmatic executor
|
|
318
|
+
* for AI-driven configuration, server-side SEO, and LLM content generation.
|
|
319
|
+
* @see AppManifestExecutor
|
|
320
|
+
*/
|
|
321
|
+
executor?: AppManifestExecutor;
|
|
170
322
|
[key: string]: any;
|
|
171
323
|
}
|
|
172
324
|
/**
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @deprecated Legacy Firestore-backed attestation response.
|
|
3
|
+
* Use {@link Attestation} from `attestations.ts` for new integrations.
|
|
4
|
+
*/
|
|
1
5
|
export interface AttestationResponse {
|
|
2
6
|
/** Attestation id */
|
|
3
7
|
id: string;
|
|
@@ -12,6 +16,10 @@ export interface AttestationResponse {
|
|
|
12
16
|
/** Associated proof reference/data */
|
|
13
17
|
proof: Record<string, any>;
|
|
14
18
|
}
|
|
19
|
+
/**
|
|
20
|
+
* @deprecated Legacy Firestore attestation create request.
|
|
21
|
+
* Use {@link CreateAttestationInput} from `attestations.ts` for new integrations.
|
|
22
|
+
*/
|
|
15
23
|
export interface AttestationCreateRequest {
|
|
16
24
|
/** Public attestation payload */
|
|
17
25
|
public: Record<string, any>;
|
|
@@ -20,6 +28,10 @@ export interface AttestationCreateRequest {
|
|
|
20
28
|
/** Proof linkage or payload */
|
|
21
29
|
proof: Record<string, any>;
|
|
22
30
|
}
|
|
31
|
+
/**
|
|
32
|
+
* @deprecated The new attestation system is append-only; updates are not supported.
|
|
33
|
+
* Append a corrective record via {@link CreateAttestationInput} instead.
|
|
34
|
+
*/
|
|
23
35
|
export interface AttestationUpdateRequest {
|
|
24
36
|
/** Update operation/type */
|
|
25
37
|
type?: string;
|
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Attestations API Types — Postgres-backed (v2)
|
|
3
|
+
*
|
|
4
|
+
* These types support the new append-only, tamper-evident attestation system
|
|
5
|
+
* which is polymorphic over subject types (container, proof, product, tag, etc.),
|
|
6
|
+
* exposes three data-visibility zones, and maintains a SHA-256 hash chain for
|
|
7
|
+
* cryptographic integrity verification.
|
|
8
|
+
*
|
|
9
|
+
* @see docs/attestations.md
|
|
10
|
+
*/
|
|
11
|
+
/** Types of entities that can be the subject of an attestation. */
|
|
12
|
+
export type AttestationSubjectType = 'container' | 'proof' | 'product' | 'tag' | 'serial' | 'order_item' | string;
|
|
13
|
+
/**
|
|
14
|
+
* Per-record visibility. Set once at write time; never changed.
|
|
15
|
+
* - `'public'` — visible to any caller
|
|
16
|
+
* - `'owner'` — visible when the caller is the subject owner (Firebase ID token required)
|
|
17
|
+
* - `'admin'` — visible to admin callers only
|
|
18
|
+
*/
|
|
19
|
+
export type AttestationVisibility = 'public' | 'owner' | 'admin';
|
|
20
|
+
/**
|
|
21
|
+
* Resolved audience tier returned by public endpoints.
|
|
22
|
+
* Tells the client which data zones are populated in the response.
|
|
23
|
+
*/
|
|
24
|
+
export type AttestationAudience = 'public' | 'owner' | 'admin';
|
|
25
|
+
/** Granularity used by the time-series summary endpoints. */
|
|
26
|
+
export type AttestationGroupBy = 'hour' | 'day' | 'week' | 'month';
|
|
27
|
+
/**
|
|
28
|
+
* A single Postgres-backed attestation record.
|
|
29
|
+
*
|
|
30
|
+
* Records are **append-only** — they must never be updated or deleted.
|
|
31
|
+
* The `contentHash` / `prevHash` pair forms a tamper-evident chain keyed on
|
|
32
|
+
* `(subjectType, subjectId, attestationType)`. Use `/verify` to confirm
|
|
33
|
+
* integrity of an entire chain.
|
|
34
|
+
*/
|
|
35
|
+
export interface Attestation {
|
|
36
|
+
/** UUID primary key */
|
|
37
|
+
id: string;
|
|
38
|
+
orgId: string;
|
|
39
|
+
collectionId: string;
|
|
40
|
+
/** Kind of entity this attestation describes */
|
|
41
|
+
subjectType: AttestationSubjectType;
|
|
42
|
+
/** UUID or identifier of the subject */
|
|
43
|
+
subjectId: string;
|
|
44
|
+
/** Domain-specific label, e.g. `'temperature'`, `'abv'`, `'angel_share'` */
|
|
45
|
+
attestationType: string;
|
|
46
|
+
/** ISO 8601 — the real-world time when the recorded fact was true */
|
|
47
|
+
recordedAt: string;
|
|
48
|
+
/** Per-record visibility; governs which audience tiers can read this record */
|
|
49
|
+
visibility: AttestationVisibility;
|
|
50
|
+
/** Public data zone — visible at all audience tiers */
|
|
51
|
+
value?: Record<string, any>;
|
|
52
|
+
/** Owner-tier data zone — stripped unless `audience >= 'owner'` */
|
|
53
|
+
ownerData?: Record<string, any>;
|
|
54
|
+
/** Admin-tier data zone — stripped unless `audience === 'admin'` */
|
|
55
|
+
adminData?: Record<string, any>;
|
|
56
|
+
/** Measurement unit, e.g. `'°C'`, `'%rh'`, `'L'`, `'ABV%'` */
|
|
57
|
+
unit?: string;
|
|
58
|
+
/** Source system or sensor identifier */
|
|
59
|
+
source?: string;
|
|
60
|
+
/** User ID or service account that recorded the fact */
|
|
61
|
+
authorId?: string;
|
|
62
|
+
/** Arbitrary extra metadata */
|
|
63
|
+
metadata?: Record<string, any>;
|
|
64
|
+
/** SHA-256 digest of this record (includes `prevHash`) */
|
|
65
|
+
contentHash: string;
|
|
66
|
+
/** `contentHash` of the preceding record in this chain, if any */
|
|
67
|
+
prevHash?: string;
|
|
68
|
+
/** ISO 8601 — database insertion timestamp */
|
|
69
|
+
createdAt: string;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Returned by `/latest` — one entry per `attestationType`, containing the
|
|
73
|
+
* single most-recent record for that type.
|
|
74
|
+
*/
|
|
75
|
+
export interface LatestAttestation {
|
|
76
|
+
attestationType: string;
|
|
77
|
+
latest: Attestation;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* One time-bucket returned by `/summary`.
|
|
81
|
+
* `period` format depends on `groupBy`:
|
|
82
|
+
* - `'hour'` → `"2025-04-15T14:00:00Z"`
|
|
83
|
+
* - `'day'` → `"2025-04-15"`
|
|
84
|
+
* - `'week'` → `"2025-W16"`
|
|
85
|
+
* - `'month'` → `"2025-04"`
|
|
86
|
+
*/
|
|
87
|
+
export interface AttestationSummaryBucket {
|
|
88
|
+
period: string;
|
|
89
|
+
count: number;
|
|
90
|
+
/** Aggregated value fields for this bucket (present when `valueField` is requested) */
|
|
91
|
+
values?: Record<string, any>;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Returned by `/verify` — result of re-computing and validating the full
|
|
95
|
+
* hash chain for a `(subjectType, subjectId, attestationType)` tuple.
|
|
96
|
+
*/
|
|
97
|
+
export interface ChainVerifyResult {
|
|
98
|
+
valid: boolean;
|
|
99
|
+
checkedCount: number;
|
|
100
|
+
/** ID of the first broken link; present only when `valid` is `false` */
|
|
101
|
+
failedAt?: string;
|
|
102
|
+
message: string;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Request body for creating a single attestation (admin endpoint).
|
|
106
|
+
*
|
|
107
|
+
* Required: `subjectType`, `subjectId`, `attestationType`.
|
|
108
|
+
*/
|
|
109
|
+
export interface CreateAttestationInput {
|
|
110
|
+
/** Required — type of entity this attestation describes */
|
|
111
|
+
subjectType: AttestationSubjectType;
|
|
112
|
+
/** Required — UUID or identifier of the subject */
|
|
113
|
+
subjectId: string;
|
|
114
|
+
/** Required — domain label for this measurement/fact */
|
|
115
|
+
attestationType: string;
|
|
116
|
+
/** ISO 8601; defaults to `now()` when omitted */
|
|
117
|
+
recordedAt?: string;
|
|
118
|
+
/** Default `'public'` */
|
|
119
|
+
visibility?: AttestationVisibility;
|
|
120
|
+
/** Public data zone */
|
|
121
|
+
value?: Record<string, any>;
|
|
122
|
+
/** Owner-tier data zone */
|
|
123
|
+
ownerData?: Record<string, any>;
|
|
124
|
+
/** Admin-tier data zone */
|
|
125
|
+
adminData?: Record<string, any>;
|
|
126
|
+
unit?: string;
|
|
127
|
+
source?: string;
|
|
128
|
+
authorId?: string;
|
|
129
|
+
metadata?: Record<string, any>;
|
|
130
|
+
}
|
|
131
|
+
export interface ListAttestationsResponse {
|
|
132
|
+
attestations: Attestation[];
|
|
133
|
+
}
|
|
134
|
+
export interface PublicListAttestationsResponse {
|
|
135
|
+
attestations: Attestation[];
|
|
136
|
+
/** Resolved audience tier; governs which data zones are populated */
|
|
137
|
+
audience: AttestationAudience;
|
|
138
|
+
}
|
|
139
|
+
export interface AttestationSummaryResponse {
|
|
140
|
+
summary: AttestationSummaryBucket[];
|
|
141
|
+
}
|
|
142
|
+
export interface PublicAttestationSummaryResponse {
|
|
143
|
+
summary: AttestationSummaryBucket[];
|
|
144
|
+
audience: 'public';
|
|
145
|
+
}
|
|
146
|
+
export interface AttestationLatestResponse {
|
|
147
|
+
latest: LatestAttestation[];
|
|
148
|
+
}
|
|
149
|
+
export interface PublicAttestationLatestResponse {
|
|
150
|
+
latest: LatestAttestation[];
|
|
151
|
+
audience: AttestationAudience;
|
|
152
|
+
}
|
|
153
|
+
export interface AttestationTreeSummaryResponse {
|
|
154
|
+
summary: AttestationSummaryBucket[];
|
|
155
|
+
/** Number of distinct subjects aggregated in this response */
|
|
156
|
+
subjectCount: number;
|
|
157
|
+
}
|
|
158
|
+
export interface PublicAttestationTreeSummaryResponse {
|
|
159
|
+
summary: AttestationSummaryBucket[];
|
|
160
|
+
audience: 'public';
|
|
161
|
+
subjectCount: number;
|
|
162
|
+
}
|
|
163
|
+
export interface AttestationTreeLatestResponse {
|
|
164
|
+
latest: LatestAttestation[];
|
|
165
|
+
subjectCount: number;
|
|
166
|
+
}
|
|
167
|
+
export interface PublicAttestationTreeLatestResponse {
|
|
168
|
+
latest: LatestAttestation[];
|
|
169
|
+
audience: 'public';
|
|
170
|
+
subjectCount: number;
|
|
171
|
+
}
|
|
172
|
+
export interface ListAttestationsParams {
|
|
173
|
+
/** Required */
|
|
174
|
+
subjectType: AttestationSubjectType;
|
|
175
|
+
/** Required */
|
|
176
|
+
subjectId: string;
|
|
177
|
+
attestationType?: string;
|
|
178
|
+
/** ISO 8601 lower bound (inclusive) */
|
|
179
|
+
recordedAfter?: string;
|
|
180
|
+
/** ISO 8601 upper bound (inclusive) */
|
|
181
|
+
recordedBefore?: string;
|
|
182
|
+
/** Default 100 */
|
|
183
|
+
limit?: number;
|
|
184
|
+
/** Default 0 */
|
|
185
|
+
offset?: number;
|
|
186
|
+
}
|
|
187
|
+
export interface AttestationSummaryParams {
|
|
188
|
+
/** Required */
|
|
189
|
+
subjectType: AttestationSubjectType;
|
|
190
|
+
/** Required */
|
|
191
|
+
subjectId: string;
|
|
192
|
+
/** Required */
|
|
193
|
+
attestationType: string;
|
|
194
|
+
/** Dot-path inside `value` to aggregate, e.g. `'celsius'` */
|
|
195
|
+
valueField?: string;
|
|
196
|
+
/** Default `'day'` */
|
|
197
|
+
groupBy?: AttestationGroupBy;
|
|
198
|
+
recordedAfter?: string;
|
|
199
|
+
recordedBefore?: string;
|
|
200
|
+
/** Max number of buckets; default 200 */
|
|
201
|
+
limit?: number;
|
|
202
|
+
}
|
|
203
|
+
export interface AttestationLatestParams {
|
|
204
|
+
/** Required */
|
|
205
|
+
subjectType: AttestationSubjectType;
|
|
206
|
+
/** Required */
|
|
207
|
+
subjectId: string;
|
|
208
|
+
}
|
|
209
|
+
export interface AttestationVerifyParams {
|
|
210
|
+
/** Required */
|
|
211
|
+
subjectType: AttestationSubjectType;
|
|
212
|
+
/** Required */
|
|
213
|
+
subjectId: string;
|
|
214
|
+
/** Required */
|
|
215
|
+
attestationType: string;
|
|
216
|
+
}
|
|
217
|
+
export interface AttestationTreeSummaryParams {
|
|
218
|
+
/** Required — root container UUID */
|
|
219
|
+
subjectId: string;
|
|
220
|
+
/** Required */
|
|
221
|
+
attestationType: string;
|
|
222
|
+
valueField?: string;
|
|
223
|
+
/** Default `'day'` */
|
|
224
|
+
groupBy?: AttestationGroupBy;
|
|
225
|
+
recordedAfter?: string;
|
|
226
|
+
recordedBefore?: string;
|
|
227
|
+
/** Max number of buckets; default 200 */
|
|
228
|
+
limit?: number;
|
|
229
|
+
/** Include container items in BFS traversal; default `true` */
|
|
230
|
+
includeItems?: boolean;
|
|
231
|
+
}
|
|
232
|
+
export interface AttestationTreeLatestParams {
|
|
233
|
+
/** Required — root container UUID */
|
|
234
|
+
subjectId: string;
|
|
235
|
+
/** Include container items in BFS traversal; default `true` */
|
|
236
|
+
includeItems?: boolean;
|
|
237
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Attestations API Types — Postgres-backed (v2)
|
|
3
|
+
*
|
|
4
|
+
* These types support the new append-only, tamper-evident attestation system
|
|
5
|
+
* which is polymorphic over subject types (container, proof, product, tag, etc.),
|
|
6
|
+
* exposes three data-visibility zones, and maintains a SHA-256 hash chain for
|
|
7
|
+
* cryptographic integrity verification.
|
|
8
|
+
*
|
|
9
|
+
* @see docs/attestations.md
|
|
10
|
+
*/
|
|
11
|
+
export {};
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Container Tracking Types
|
|
3
|
+
*
|
|
4
|
+
* Physical or logical grouping entities (pallets, casks, fridges, shipping
|
|
5
|
+
* containers, warehouses, etc.) with support for hierarchical nesting and
|
|
6
|
+
* item membership tracking.
|
|
7
|
+
*
|
|
8
|
+
* @see docs/container-tracking.md
|
|
9
|
+
*/
|
|
10
|
+
/** Lifecycle status of a container. Custom strings are permitted. */
|
|
11
|
+
export type ContainerStatus = 'active' | 'archived' | string;
|
|
12
|
+
/**
|
|
13
|
+
* Types of items that can be placed inside a container.
|
|
14
|
+
* A `container` item type allows containers to nest inside other containers.
|
|
15
|
+
*/
|
|
16
|
+
export type ContainerItemType = 'tag' | 'proof' | 'serial' | 'order_item' | 'container';
|
|
17
|
+
/**
|
|
18
|
+
* A physical or logical container entity.
|
|
19
|
+
*
|
|
20
|
+
* Containers can nest arbitrarily via `parentContainerId`. The `children`
|
|
21
|
+
* field is only populated when `?tree=true` is included in the request.
|
|
22
|
+
* The `items` field is only populated when `?includeContents=true` is set.
|
|
23
|
+
*/
|
|
24
|
+
export interface Container {
|
|
25
|
+
/** UUID primary key */
|
|
26
|
+
id: string;
|
|
27
|
+
orgId: string;
|
|
28
|
+
collectionId: string;
|
|
29
|
+
/**
|
|
30
|
+
* Domain label describing what kind of container this is.
|
|
31
|
+
* Examples: `'pallet'`, `'fridge'`, `'cask'`, `'warehouse'`, `'shipping_container'`
|
|
32
|
+
*/
|
|
33
|
+
containerType: string;
|
|
34
|
+
/** Human-readable identifier, e.g. a barcode, reference number, or QR code value */
|
|
35
|
+
ref?: string;
|
|
36
|
+
name?: string;
|
|
37
|
+
description?: string;
|
|
38
|
+
/** Default `'active'` */
|
|
39
|
+
status: ContainerStatus;
|
|
40
|
+
/** Arbitrary key/value store for application-specific data */
|
|
41
|
+
metadata?: Record<string, any>;
|
|
42
|
+
/** UUID of the parent container; `undefined` / `null` for top-level containers */
|
|
43
|
+
parentContainerId?: string;
|
|
44
|
+
/** Recursively nested children — populated only when `?tree=true` */
|
|
45
|
+
children?: Container[];
|
|
46
|
+
/** Current (or historical) items — populated only when `?includeContents=true` */
|
|
47
|
+
items?: ContainerItem[];
|
|
48
|
+
/** ISO 8601 */
|
|
49
|
+
createdAt: string;
|
|
50
|
+
/** ISO 8601 */
|
|
51
|
+
updatedAt: string;
|
|
52
|
+
/** ISO 8601 soft-delete timestamp; present only for deleted containers */
|
|
53
|
+
deletedAt?: string;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* A membership record linking a single item to a container.
|
|
57
|
+
*
|
|
58
|
+
* `removedAt` being `null` / `undefined` means the item is currently inside
|
|
59
|
+
* the container. When non-null the item has been removed; the record is
|
|
60
|
+
* preserved in the history log.
|
|
61
|
+
*/
|
|
62
|
+
export interface ContainerItem {
|
|
63
|
+
id: string;
|
|
64
|
+
orgId: string;
|
|
65
|
+
containerId: string;
|
|
66
|
+
collectionId?: string;
|
|
67
|
+
itemType: ContainerItemType;
|
|
68
|
+
/** UUID or physical identifier of the item (tag ID, proof ID, serial, etc.) */
|
|
69
|
+
itemId: string;
|
|
70
|
+
/** Convenience denormalisation — product UUID if applicable */
|
|
71
|
+
productId?: string;
|
|
72
|
+
/** Convenience denormalisation — proof / serial UUID if applicable */
|
|
73
|
+
proofId?: string;
|
|
74
|
+
/** ISO 8601 — when the item was placed into the container */
|
|
75
|
+
addedAt: string;
|
|
76
|
+
/** ISO 8601 — when the item was removed; `null` / `undefined` = still inside */
|
|
77
|
+
removedAt?: string;
|
|
78
|
+
/** Arbitrary extra metadata */
|
|
79
|
+
metadata?: Record<string, any>;
|
|
80
|
+
}
|
|
81
|
+
/** Request body for `POST /containers` — creates a new container. */
|
|
82
|
+
export interface CreateContainerInput {
|
|
83
|
+
/** Required — domain label for this container */
|
|
84
|
+
containerType: string;
|
|
85
|
+
/** Human-readable reference / barcode */
|
|
86
|
+
ref?: string;
|
|
87
|
+
name?: string;
|
|
88
|
+
description?: string;
|
|
89
|
+
/** Default `'active'` */
|
|
90
|
+
status?: ContainerStatus;
|
|
91
|
+
metadata?: Record<string, any>;
|
|
92
|
+
/** UUID of the parent container; omit to create a top-level container */
|
|
93
|
+
parentContainerId?: string;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Request body for `PATCH /containers/:id`.
|
|
97
|
+
* Only provided fields are updated; all are optional.
|
|
98
|
+
*/
|
|
99
|
+
export interface UpdateContainerInput {
|
|
100
|
+
containerType?: string;
|
|
101
|
+
ref?: string;
|
|
102
|
+
name?: string;
|
|
103
|
+
description?: string;
|
|
104
|
+
status?: ContainerStatus;
|
|
105
|
+
metadata?: Record<string, any>;
|
|
106
|
+
/** Pass `null` to promote the container to top-level. */
|
|
107
|
+
parentContainerId?: string | null;
|
|
108
|
+
}
|
|
109
|
+
/** Request body for `POST /containers/:id/items` — adds items to a container. */
|
|
110
|
+
export interface AddContainerItemsInput {
|
|
111
|
+
items: Array<{
|
|
112
|
+
/** Required */
|
|
113
|
+
itemType: ContainerItemType;
|
|
114
|
+
/** Required — UUID or physical identifier of the item */
|
|
115
|
+
itemId: string;
|
|
116
|
+
productId?: string;
|
|
117
|
+
proofId?: string;
|
|
118
|
+
metadata?: Record<string, any>;
|
|
119
|
+
}>;
|
|
120
|
+
}
|
|
121
|
+
/** Request body for `DELETE /containers/:id/items` — soft-removes items. */
|
|
122
|
+
export interface RemoveContainerItemsInput {
|
|
123
|
+
/** `ContainerItem` UUIDs to mark as removed */
|
|
124
|
+
ids: string[];
|
|
125
|
+
}
|
|
126
|
+
export interface ListContainersResponse {
|
|
127
|
+
containers: Container[];
|
|
128
|
+
limit: number;
|
|
129
|
+
offset: number;
|
|
130
|
+
}
|
|
131
|
+
export interface PublicListContainersResponse {
|
|
132
|
+
containers: Container[];
|
|
133
|
+
}
|
|
134
|
+
export interface FindContainersForItemResponse {
|
|
135
|
+
containers: Container[];
|
|
136
|
+
}
|
|
137
|
+
export interface ContainerItemsResponse {
|
|
138
|
+
items: ContainerItem[];
|
|
139
|
+
limit: number;
|
|
140
|
+
offset: number;
|
|
141
|
+
}
|
|
142
|
+
export interface AddContainerItemsResponse {
|
|
143
|
+
items: ContainerItem[];
|
|
144
|
+
}
|
|
145
|
+
export interface RemoveContainerItemsResponse {
|
|
146
|
+
success: true;
|
|
147
|
+
removedCount: number;
|
|
148
|
+
}
|
|
149
|
+
export interface ListContainersParams {
|
|
150
|
+
/** Filter by container type label */
|
|
151
|
+
containerType?: string;
|
|
152
|
+
/** Filter by status */
|
|
153
|
+
status?: ContainerStatus;
|
|
154
|
+
/** Filter by human-readable reference */
|
|
155
|
+
ref?: string;
|
|
156
|
+
/** Filter by parent container UUID */
|
|
157
|
+
parentContainerId?: string;
|
|
158
|
+
/** When `true`, return only top-level containers (no `parentContainerId`) */
|
|
159
|
+
topLevel?: boolean;
|
|
160
|
+
/** Default 100 */
|
|
161
|
+
limit?: number;
|
|
162
|
+
/** Default 0 */
|
|
163
|
+
offset?: number;
|
|
164
|
+
}
|
|
165
|
+
export interface GetContainerParams {
|
|
166
|
+
/** When `true`, recursively embed child containers up to `treeDepth` levels */
|
|
167
|
+
tree?: boolean;
|
|
168
|
+
/** Max nesting depth for the tree; default unlimited */
|
|
169
|
+
treeDepth?: number;
|
|
170
|
+
/** When `true`, embed the current `items` array */
|
|
171
|
+
includeContents?: boolean;
|
|
172
|
+
}
|
|
173
|
+
export interface ListContainerItemsParams {
|
|
174
|
+
/** When `true`, include removed items (full membership log); default `false` */
|
|
175
|
+
history?: boolean;
|
|
176
|
+
/** Default 100 */
|
|
177
|
+
limit?: number;
|
|
178
|
+
/** Default 0 */
|
|
179
|
+
offset?: number;
|
|
180
|
+
}
|
|
181
|
+
export interface FindContainersForItemParams {
|
|
182
|
+
/** Required */
|
|
183
|
+
itemType: ContainerItemType;
|
|
184
|
+
/** Required */
|
|
185
|
+
itemId: string;
|
|
186
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Container Tracking Types
|
|
3
|
+
*
|
|
4
|
+
* Physical or logical grouping entities (pallets, casks, fridges, shipping
|
|
5
|
+
* containers, warehouses, etc.) with support for hierarchical nesting and
|
|
6
|
+
* item membership tracking.
|
|
7
|
+
*
|
|
8
|
+
* @see docs/container-tracking.md
|
|
9
|
+
*/
|
|
10
|
+
export {};
|