@avenlabs/halal-trace-sdk 0.1.5 → 0.1.7

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/client.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { Anchor, AuditLog, AuditPack, AuditPackManifest, AuthResult, Batch, CertificationRecord, Device, DocumentAnchor, EventDepartment, HealthResponse, Hologram, HologramVerification, Invite, Member, Org, OrgInviteResult, OrgUserLookup, Permission, PublicAttribute, RelayerJobSummary, SignatureRecord, TraceEvent } from "./types.js";
1
+ import type { Anchor, AuditLog, AuditPack, AuditPackWithBatch, AuditPackManifest, AuthResult, Batch, BatchTrace, CertificationRecord, Device, DocumentAnchor, EventDepartment, HealthResponse, Hologram, HologramVerification, Invite, InviteAcceptance, AccessRequest, Member, Org, OrgSummary, OrgInviteResult, OrgUserLookup, Permission, PublicAttribute, RelayerJobSummary, SignatureRecord, TraceEvent } from "./types.js";
2
2
  import { ApiError, type AuthOptions, type ClientHooks, type RequestOptions, type RetryOptions } from "./http.js";
3
3
  type BaseClientOptions = {
4
4
  baseUrl: string;
@@ -74,6 +74,24 @@ export declare class ApiClient {
74
74
  }) => Promise<AuthResult>;
75
75
  };
76
76
  orgs: {
77
+ list: () => Promise<{
78
+ requestId: string;
79
+ status: import("./types.js").ApiStatus;
80
+ data?: Org[] | undefined;
81
+ relayerJob?: RelayerJobSummary | null;
82
+ }>;
83
+ get: (orgId: string) => Promise<{
84
+ requestId: string;
85
+ status: import("./types.js").ApiStatus;
86
+ data?: Org | undefined;
87
+ relayerJob?: RelayerJobSummary | null;
88
+ }>;
89
+ getSummary: (orgId: string) => Promise<{
90
+ requestId: string;
91
+ status: import("./types.js").ApiStatus;
92
+ data?: OrgSummary | undefined;
93
+ relayerJob?: RelayerJobSummary | null;
94
+ }>;
77
95
  create: (payload: {
78
96
  orgId: string;
79
97
  name?: string;
@@ -115,6 +133,42 @@ export declare class ApiClient {
115
133
  relayerJob?: RelayerJobSummary | null;
116
134
  }>;
117
135
  listMembersAll: (orgId: string) => AsyncGenerator<Member, void, unknown>;
136
+ listBatches: (orgId: string, query?: {
137
+ limit?: number;
138
+ offset?: number;
139
+ }) => Promise<{
140
+ requestId: string;
141
+ status: import("./types.js").ApiStatus;
142
+ data?: Batch[] | undefined;
143
+ relayerJob?: RelayerJobSummary | null;
144
+ }>;
145
+ listDevices: (orgId: string, query?: {
146
+ limit?: number;
147
+ offset?: number;
148
+ }) => Promise<{
149
+ requestId: string;
150
+ status: import("./types.js").ApiStatus;
151
+ data?: Device[] | undefined;
152
+ relayerJob?: RelayerJobSummary | null;
153
+ }>;
154
+ listHolograms: (orgId: string, query?: {
155
+ limit?: number;
156
+ offset?: number;
157
+ }) => Promise<{
158
+ requestId: string;
159
+ status: import("./types.js").ApiStatus;
160
+ data?: Hologram[] | undefined;
161
+ relayerJob?: RelayerJobSummary | null;
162
+ }>;
163
+ listAuditPacks: (orgId: string, query?: {
164
+ limit?: number;
165
+ offset?: number;
166
+ }) => Promise<{
167
+ requestId: string;
168
+ status: import("./types.js").ApiStatus;
169
+ data?: AuditPackWithBatch[] | undefined;
170
+ relayerJob?: RelayerJobSummary | null;
171
+ }>;
118
172
  listAuditLogs: (orgId: string, query?: {
119
173
  limit?: number;
120
174
  offset?: number;
@@ -186,13 +240,14 @@ export declare class ApiClient {
186
240
  data?: OrgInviteResult | undefined;
187
241
  relayerJob?: RelayerJobSummary | null;
188
242
  }>;
189
- acceptInvite: (orgId: string, token: string) => Promise<{
243
+ acceptInvite: (orgId: string, token: string, payload?: {
244
+ name?: string;
245
+ password?: string;
246
+ callbackURL?: string;
247
+ }) => Promise<{
190
248
  requestId: string;
191
249
  status: import("./types.js").ApiStatus;
192
- data?: {
193
- invite: Invite;
194
- member: Member;
195
- } | undefined;
250
+ data?: InviteAcceptance | undefined;
196
251
  relayerJob?: RelayerJobSummary | null;
197
252
  }>;
198
253
  lookupUserByEmail: (orgId: string, email: string) => Promise<{
@@ -325,6 +380,15 @@ export declare class ApiClient {
325
380
  data?: AuditPackManifest | undefined;
326
381
  relayerJob?: RelayerJobSummary | null;
327
382
  }>;
383
+ getTrace: (batchId: string, query?: {
384
+ include?: string;
385
+ eventType?: string;
386
+ }) => Promise<{
387
+ requestId: string;
388
+ status: import("./types.js").ApiStatus;
389
+ data?: BatchTrace | undefined;
390
+ relayerJob?: RelayerJobSummary | null;
391
+ }>;
328
392
  listRelayerJobs: (batchId: string, query?: {
329
393
  status?: string;
330
394
  jobType?: string;
@@ -411,6 +475,33 @@ export declare class ApiClient {
411
475
  downloadPdf: (pdfUri: string) => Promise<ArrayBuffer>;
412
476
  downloadJson: (jsonUri: string) => Promise<string>;
413
477
  };
478
+ accessRequests: {
479
+ create: (payload: {
480
+ companyName: string;
481
+ adminEmail: string;
482
+ companyDomain: string;
483
+ headcountEstimate?: number;
484
+ }) => Promise<{
485
+ requestId: string;
486
+ status: import("./types.js").ApiStatus;
487
+ data?: AccessRequest | undefined;
488
+ relayerJob?: RelayerJobSummary | null;
489
+ }>;
490
+ approve: (id: number, payload?: {
491
+ orgId?: string;
492
+ orgName?: string;
493
+ inviteUrl?: string;
494
+ }) => Promise<{
495
+ requestId: string;
496
+ status: import("./types.js").ApiStatus;
497
+ data?: {
498
+ lead: AccessRequest;
499
+ org: Org;
500
+ invite: Invite;
501
+ } | undefined;
502
+ relayerJob?: RelayerJobSummary | null;
503
+ }>;
504
+ };
414
505
  holograms: {
415
506
  issue: (payload: {
416
507
  batchId: string;
package/dist/client.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { ApiError, request, requestRaw, } from "./http.js";
2
- const sdkVersion = "0.1.5";
2
+ const sdkVersion = "0.1.7";
3
3
  const withDefaults = (client, options = {}) => {
4
4
  return {
5
5
  ...options,
@@ -213,6 +213,9 @@ export class ApiClient {
213
213
  },
214
214
  };
215
215
  orgs = {
216
+ list: async () => await this.request("GET", "/orgs", { canRetry: true }).then((res) => res.body),
217
+ get: async (orgId) => await this.request("GET", `/orgs/${orgId}`, { canRetry: true }).then((res) => res.body),
218
+ getSummary: async (orgId) => await this.request("GET", `/orgs/${orgId}/summary`, { canRetry: true }).then((res) => res.body),
216
219
  create: async (payload, options) => await this.request("POST", "/orgs", {
217
220
  ...options,
218
221
  body: payload,
@@ -236,6 +239,13 @@ export class ApiClient {
236
239
  canRetry: true,
237
240
  }).then((res) => res.body),
238
241
  listMembersAll: (orgId) => listSingle(this, `/orgs/${orgId}/members`),
242
+ listBatches: async (orgId, query) => await this.request("GET", `/orgs/${orgId}/batches`, { query, canRetry: true }).then((res) => res.body),
243
+ listDevices: async (orgId, query) => await this.request("GET", `/orgs/${orgId}/devices`, { query, canRetry: true }).then((res) => res.body),
244
+ listHolograms: async (orgId, query) => await this.request("GET", `/orgs/${orgId}/holograms`, { query, canRetry: true }).then((res) => res.body),
245
+ listAuditPacks: async (orgId, query) => await this.request("GET", `/orgs/${orgId}/audit-packs`, {
246
+ query,
247
+ canRetry: true,
248
+ }).then((res) => res.body),
239
249
  listAuditLogs: async (orgId, query) => await this.request("GET", `/orgs/${orgId}/audit-logs`, {
240
250
  query,
241
251
  canRetry: true,
@@ -257,7 +267,7 @@ export class ApiClient {
257
267
  canRetry: true,
258
268
  idempotencyKey: options?.idempotencyKey,
259
269
  }).then((res) => res.body),
260
- acceptInvite: async (orgId, token) => await this.request("POST", `/orgs/${orgId}/invites/${token}/accept`, { canRetry: false }).then((res) => res.body),
270
+ acceptInvite: async (orgId, token, payload) => await this.request("POST", `/orgs/${orgId}/invites/${token}/accept`, { body: payload, canRetry: false }).then((res) => res.body),
261
271
  lookupUserByEmail: async (orgId, email) => await this.request("GET", `/orgs/${orgId}/users`, {
262
272
  query: { email },
263
273
  canRetry: true,
@@ -351,6 +361,7 @@ export class ApiClient {
351
361
  idempotencyKey: options?.idempotencyKey,
352
362
  }).then((res) => res.body),
353
363
  getAuditPackManifest: async (batchId) => await this.request("GET", `/batches/${batchId}/audit-pack/manifest`, { canRetry: true }).then((res) => res.body),
364
+ getTrace: async (batchId, query) => await this.request("GET", `/batches/${batchId}/trace`, { query, canRetry: true }).then((res) => res.body),
354
365
  listRelayerJobs: async (batchId, query) => await this.request("GET", `/batches/${batchId}/relayer-jobs`, { query, canRetry: true }).then((res) => res.body),
355
366
  listRelayerJobsAll: (batchId, query) => listPaginated(this, `/batches/${batchId}/relayer-jobs`, query),
356
367
  backfillBatch: async (batchId) => await this.request("POST", `/batches/${batchId}/relayer-jobs/backfill`, { canRetry: false }).then((res) => res.body),
@@ -405,6 +416,13 @@ export class ApiClient {
405
416
  return response.text();
406
417
  },
407
418
  };
419
+ accessRequests = {
420
+ create: async (payload) => await this.request("POST", "/access-requests", {
421
+ body: payload,
422
+ canRetry: false,
423
+ }).then((res) => res.body),
424
+ approve: async (id, payload) => await this.request("POST", `/access-requests/${id}/approve`, { body: payload, canRetry: false }).then((res) => res.body),
425
+ };
408
426
  holograms = {
409
427
  issue: async (payload, options) => await this.request("POST", "/holograms", {
410
428
  ...options,
package/dist/http.js CHANGED
@@ -78,7 +78,6 @@ export const request = async (baseUrl, path, method, options) => {
78
78
  const url = `${baseUrl.replace(/\/$/, "")}${path}${buildQuery(options.query)}`;
79
79
  const requestId = options.requestId ?? generateRequestId();
80
80
  const headers = {
81
- "Content-Type": "application/json",
82
81
  "x-request-id": requestId,
83
82
  ...(options.sdkHeaders ?? {}),
84
83
  ...(options.headers ?? {}),
@@ -97,7 +96,11 @@ export const request = async (baseUrl, path, method, options) => {
97
96
  }
98
97
  }
99
98
  }
100
- const body = options.body ? JSON.stringify(options.body) : undefined;
99
+ const hasBody = options.body !== undefined;
100
+ if (hasBody) {
101
+ headers["Content-Type"] = "application/json";
102
+ }
103
+ const body = hasBody ? JSON.stringify(options.body) : undefined;
101
104
  const context = { method, url, headers, body: options.body, requestId };
102
105
  if (options.signingHook) {
103
106
  const extraHeaders = await options.signingHook(context);
package/dist/types.d.ts CHANGED
@@ -20,10 +20,33 @@ export type RelayerJobSummary = {
20
20
  export type Org = {
21
21
  orgId: string;
22
22
  name?: string | null;
23
- adminId: string;
23
+ adminId?: string | null;
24
24
  active?: boolean;
25
+ status?: string;
26
+ invitePolicy?: string;
27
+ allowlistedDomains?: string;
25
28
  createdAt?: string;
26
29
  };
30
+ export type OrgSummary = {
31
+ orgId: string;
32
+ batchesTotal: number;
33
+ batchesActive: number;
34
+ devicesTotal: number;
35
+ devicesActive: number;
36
+ membersTotal: number;
37
+ hologramsTotal: number;
38
+ auditPacksTotal: number;
39
+ relayerJobs: {
40
+ pending: number;
41
+ processing: number;
42
+ completed: number;
43
+ failed: number;
44
+ dead: number;
45
+ };
46
+ };
47
+ export type AuditPackWithBatch = AuditPack & {
48
+ batch: Batch;
49
+ };
27
50
  export type Batch = {
28
51
  batchId: string;
29
52
  orgId: string;
@@ -120,6 +143,52 @@ export type AuditPackManifest = {
120
143
  auditPack: AuditPack;
121
144
  publicAttributes: PublicAttribute[];
122
145
  };
146
+ export type TraceTimelineItem = {
147
+ kind: "event";
148
+ id: number;
149
+ recordedAt: string;
150
+ eventType: string;
151
+ metadataHash: string;
152
+ actorRole: string;
153
+ deviceId?: string | null;
154
+ } | {
155
+ kind: "document";
156
+ id: number;
157
+ recordedAt: string;
158
+ docType: string;
159
+ docHash: string;
160
+ uri: string;
161
+ } | {
162
+ kind: "signature";
163
+ id: number;
164
+ recordedAt: string;
165
+ signerRole: string;
166
+ signatureHash: string;
167
+ signerIdHash: string;
168
+ } | {
169
+ kind: "certification";
170
+ id: number;
171
+ recordedAt: string;
172
+ status: "pending" | "approved" | "rejected";
173
+ decisionHash: string;
174
+ reviewerRole: string;
175
+ reviewerIdHash: string;
176
+ } | {
177
+ kind: "public_attribute";
178
+ id: number;
179
+ recordedAt: string;
180
+ key: string;
181
+ value: string;
182
+ };
183
+ export type BatchTrace = {
184
+ batch: Batch;
185
+ timeline: TraceTimelineItem[];
186
+ events: TraceEvent[];
187
+ documents: DocumentAnchor[];
188
+ signatures: SignatureRecord[];
189
+ certifications: CertificationRecord[];
190
+ publicAttributes: PublicAttribute[];
191
+ };
123
192
  export type HologramVerification = {
124
193
  hologramId: string;
125
194
  publicCode: string;
@@ -161,10 +230,28 @@ export type Invite = {
161
230
  role: string;
162
231
  department: string;
163
232
  status: string;
164
- invitedBy: string;
233
+ invitedBy?: string | null;
165
234
  createdAt: string;
166
235
  expiresAt: string;
167
236
  acceptedAt?: string | null;
237
+ tokenHash?: string | null;
238
+ usedAt?: string | null;
239
+ };
240
+ export type InviteAcceptance = {
241
+ invite: Invite;
242
+ member: Member;
243
+ mode?: "accepted" | "signup";
244
+ };
245
+ export type AccessRequest = {
246
+ id: number;
247
+ companyName: string;
248
+ adminEmail: string;
249
+ companyDomain: string;
250
+ headcountEstimate?: number | null;
251
+ status: string;
252
+ approvedBy?: string | null;
253
+ approvedAt?: string | null;
254
+ createdAt: string;
168
255
  };
169
256
  export type Permission = {
170
257
  orgId: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@avenlabs/halal-trace-sdk",
3
- "version": "0.1.5",
3
+ "version": "0.1.7",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -18,4 +18,4 @@
18
18
  "typescript": "^5.5.4",
19
19
  "vitest": "^2.0.4"
20
20
  }
21
- }
21
+ }
package/src/client.ts CHANGED
@@ -3,9 +3,11 @@ import type {
3
3
  ApiResponse,
4
4
  AuditLog,
5
5
  AuditPack,
6
+ AuditPackWithBatch,
6
7
  AuditPackManifest,
7
8
  AuthResult,
8
9
  Batch,
10
+ BatchTrace,
9
11
  CertificationRecord,
10
12
  Device,
11
13
  DocumentAnchor,
@@ -14,8 +16,11 @@ import type {
14
16
  Hologram,
15
17
  HologramVerification,
16
18
  Invite,
19
+ InviteAcceptance,
20
+ AccessRequest,
17
21
  Member,
18
22
  Org,
23
+ OrgSummary,
19
24
  OrgInviteResult,
20
25
  OrgUserLookup,
21
26
  Permission,
@@ -59,7 +64,7 @@ type RequestConfig = Omit<
59
64
  onAuthError?: (error: ApiError) => void | Promise<void>;
60
65
  };
61
66
 
62
- const sdkVersion = "0.1.5";
67
+ const sdkVersion = "0.1.7";
63
68
 
64
69
  const withDefaults = (
65
70
  client: ApiClient,
@@ -378,6 +383,12 @@ export class ApiClient {
378
383
  };
379
384
 
380
385
  orgs = {
386
+ list: async () =>
387
+ await this.request<Org[]>("GET", "/orgs", { canRetry: true }).then((res) => res.body),
388
+ get: async (orgId: string) =>
389
+ await this.request<Org>("GET", `/orgs/${orgId}`, { canRetry: true }).then((res) => res.body),
390
+ getSummary: async (orgId: string) =>
391
+ await this.request<OrgSummary>("GET", `/orgs/${orgId}/summary`, { canRetry: true }).then((res) => res.body),
381
392
  create: async (
382
393
  payload: { orgId: string; name?: string },
383
394
  options?: RequestConfig,
@@ -418,6 +429,17 @@ export class ApiClient {
418
429
  }).then((res) => res.body),
419
430
  listMembersAll: (orgId: string) =>
420
431
  listSingle<Member>(this, `/orgs/${orgId}/members`),
432
+ listBatches: async (orgId: string, query?: { limit?: number; offset?: number }) =>
433
+ await this.request<Batch[]>("GET", `/orgs/${orgId}/batches`, { query, canRetry: true }).then((res) => res.body),
434
+ listDevices: async (orgId: string, query?: { limit?: number; offset?: number }) =>
435
+ await this.request<Device[]>("GET", `/orgs/${orgId}/devices`, { query, canRetry: true }).then((res) => res.body),
436
+ listHolograms: async (orgId: string, query?: { limit?: number; offset?: number }) =>
437
+ await this.request<Hologram[]>("GET", `/orgs/${orgId}/holograms`, { query, canRetry: true }).then((res) => res.body),
438
+ listAuditPacks: async (orgId: string, query?: { limit?: number; offset?: number }) =>
439
+ await this.request<AuditPackWithBatch[]>("GET", `/orgs/${orgId}/audit-packs`, {
440
+ query,
441
+ canRetry: true,
442
+ }).then((res) => res.body),
421
443
  listAuditLogs: async (
422
444
  orgId: string,
423
445
  query?: { limit?: number; offset?: number },
@@ -491,11 +513,15 @@ export class ApiClient {
491
513
  canRetry: true,
492
514
  idempotencyKey: options?.idempotencyKey,
493
515
  }).then((res) => res.body),
494
- acceptInvite: async (orgId: string, token: string) =>
495
- await this.request<{ invite: Invite; member: Member }>(
516
+ acceptInvite: async (
517
+ orgId: string,
518
+ token: string,
519
+ payload?: { name?: string; password?: string; callbackURL?: string },
520
+ ) =>
521
+ await this.request<InviteAcceptance>(
496
522
  "POST",
497
523
  `/orgs/${orgId}/invites/${token}/accept`,
498
- { canRetry: false },
524
+ { body: payload, canRetry: false },
499
525
  ).then((res) => res.body),
500
526
  lookupUserByEmail: async (orgId: string, email: string) =>
501
527
  await this.request<OrgUserLookup>("GET", `/orgs/${orgId}/users`, {
@@ -702,6 +728,12 @@ export class ApiClient {
702
728
  `/batches/${batchId}/audit-pack/manifest`,
703
729
  { canRetry: true },
704
730
  ).then((res) => res.body),
731
+ getTrace: async (batchId: string, query?: { include?: string; eventType?: string }) =>
732
+ await this.request<BatchTrace>(
733
+ "GET",
734
+ `/batches/${batchId}/trace`,
735
+ { query, canRetry: true },
736
+ ).then((res) => res.body),
705
737
  listRelayerJobs: async (
706
738
  batchId: string,
707
739
  query?: {
@@ -834,6 +866,28 @@ export class ApiClient {
834
866
  },
835
867
  };
836
868
 
869
+ accessRequests = {
870
+ create: async (payload: {
871
+ companyName: string;
872
+ adminEmail: string;
873
+ companyDomain: string;
874
+ headcountEstimate?: number;
875
+ }) =>
876
+ await this.request<AccessRequest>("POST", "/access-requests", {
877
+ body: payload,
878
+ canRetry: false,
879
+ }).then((res) => res.body),
880
+ approve: async (
881
+ id: number,
882
+ payload?: { orgId?: string; orgName?: string; inviteUrl?: string },
883
+ ) =>
884
+ await this.request<{ lead: AccessRequest; org: Org; invite: Invite }>(
885
+ "POST",
886
+ `/access-requests/${id}/approve`,
887
+ { body: payload, canRetry: false },
888
+ ).then((res) => res.body),
889
+ };
890
+
837
891
  holograms = {
838
892
  issue: async (
839
893
  payload: {
package/src/http.ts CHANGED
@@ -158,7 +158,6 @@ export const request = async <T>(
158
158
  const url = `${baseUrl.replace(/\/$/, "")}${path}${buildQuery(options.query)}`;
159
159
  const requestId = options.requestId ?? generateRequestId();
160
160
  const headers: Record<string, string> = {
161
- "Content-Type": "application/json",
162
161
  "x-request-id": requestId,
163
162
  ...(options.sdkHeaders ?? {}),
164
163
  ...(options.headers ?? {}),
@@ -179,7 +178,11 @@ export const request = async <T>(
179
178
  }
180
179
  }
181
180
 
182
- const body = options.body ? JSON.stringify(options.body) : undefined;
181
+ const hasBody = options.body !== undefined;
182
+ if (hasBody) {
183
+ headers["Content-Type"] = "application/json";
184
+ }
185
+ const body = hasBody ? JSON.stringify(options.body) : undefined;
183
186
  const context: RequestContext = { method, url, headers, body: options.body, requestId };
184
187
  if (options.signingHook) {
185
188
  const extraHeaders = await options.signingHook(context);
package/src/types.ts CHANGED
@@ -24,11 +24,34 @@ export type RelayerJobSummary = {
24
24
  export type Org = {
25
25
  orgId: string;
26
26
  name?: string | null;
27
- adminId: string;
27
+ adminId?: string | null;
28
28
  active?: boolean;
29
+ status?: string;
30
+ invitePolicy?: string;
31
+ allowlistedDomains?: string;
29
32
  createdAt?: string;
30
33
  };
31
34
 
35
+ export type OrgSummary = {
36
+ orgId: string;
37
+ batchesTotal: number;
38
+ batchesActive: number;
39
+ devicesTotal: number;
40
+ devicesActive: number;
41
+ membersTotal: number;
42
+ hologramsTotal: number;
43
+ auditPacksTotal: number;
44
+ relayerJobs: {
45
+ pending: number;
46
+ processing: number;
47
+ completed: number;
48
+ failed: number;
49
+ dead: number;
50
+ };
51
+ };
52
+
53
+ export type AuditPackWithBatch = AuditPack & { batch: Batch };
54
+
32
55
  export type Batch = {
33
56
  batchId: string;
34
57
  orgId: string;
@@ -136,6 +159,59 @@ export type AuditPackManifest = {
136
159
  publicAttributes: PublicAttribute[];
137
160
  };
138
161
 
162
+ export type TraceTimelineItem =
163
+ | {
164
+ kind: "event";
165
+ id: number;
166
+ recordedAt: string;
167
+ eventType: string;
168
+ metadataHash: string;
169
+ actorRole: string;
170
+ deviceId?: string | null;
171
+ }
172
+ | {
173
+ kind: "document";
174
+ id: number;
175
+ recordedAt: string;
176
+ docType: string;
177
+ docHash: string;
178
+ uri: string;
179
+ }
180
+ | {
181
+ kind: "signature";
182
+ id: number;
183
+ recordedAt: string;
184
+ signerRole: string;
185
+ signatureHash: string;
186
+ signerIdHash: string;
187
+ }
188
+ | {
189
+ kind: "certification";
190
+ id: number;
191
+ recordedAt: string;
192
+ status: "pending" | "approved" | "rejected";
193
+ decisionHash: string;
194
+ reviewerRole: string;
195
+ reviewerIdHash: string;
196
+ }
197
+ | {
198
+ kind: "public_attribute";
199
+ id: number;
200
+ recordedAt: string;
201
+ key: string;
202
+ value: string;
203
+ };
204
+
205
+ export type BatchTrace = {
206
+ batch: Batch;
207
+ timeline: TraceTimelineItem[];
208
+ events: TraceEvent[];
209
+ documents: DocumentAnchor[];
210
+ signatures: SignatureRecord[];
211
+ certifications: CertificationRecord[];
212
+ publicAttributes: PublicAttribute[];
213
+ };
214
+
139
215
  export type HologramVerification = {
140
216
  hologramId: string;
141
217
  publicCode: string;
@@ -180,10 +256,30 @@ export type Invite = {
180
256
  role: string;
181
257
  department: string;
182
258
  status: string;
183
- invitedBy: string;
259
+ invitedBy?: string | null;
184
260
  createdAt: string;
185
261
  expiresAt: string;
186
262
  acceptedAt?: string | null;
263
+ tokenHash?: string | null;
264
+ usedAt?: string | null;
265
+ };
266
+
267
+ export type InviteAcceptance = {
268
+ invite: Invite;
269
+ member: Member;
270
+ mode?: "accepted" | "signup";
271
+ };
272
+
273
+ export type AccessRequest = {
274
+ id: number;
275
+ companyName: string;
276
+ adminEmail: string;
277
+ companyDomain: string;
278
+ headcountEstimate?: number | null;
279
+ status: string;
280
+ approvedBy?: string | null;
281
+ approvedAt?: string | null;
282
+ createdAt: string;
187
283
  };
188
284
 
189
285
  export type Permission = {