@stamprally/server 0.14.0 → 0.16.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/index.d.cts CHANGED
@@ -18,11 +18,20 @@ interface ClaimRewardTransactionParams {
18
18
  readonly idempotencyKey?: string;
19
19
  readonly proofData?: unknown;
20
20
  readonly idempotencyTtlMs?: number;
21
+ /** The configured per-reward stock limit, or null for unlimited stock. */
22
+ readonly rewardStockLimit: number | null;
23
+ /** The configured shared stock limit, or null when shared inventory is disabled. */
24
+ readonly sharedStockLimit: number | null;
21
25
  /** Used when the first claim is made before a user state has been stored. */
22
26
  readonly initialUserState?: UserRallyState;
27
+ readonly stockKey?: string;
28
+ readonly secondaryStockKey?: string;
29
+ readonly initialStock?: number | null;
30
+ readonly initialSecondaryStock?: number | null;
23
31
  }
24
32
  interface ClaimRewardTransactionMutation {
25
33
  readonly nextStock: number | null;
34
+ readonly nextSecondaryStock?: number | null;
26
35
  readonly nextUserState: UserRallyState;
27
36
  readonly auditLog: AuditLog;
28
37
  /** The server response is persisted by the adapter with the idempotency key. */
@@ -60,12 +69,15 @@ interface ServerPersistenceAdapter {
60
69
  */
61
70
  executeClaimRewardTransaction(params: ClaimRewardTransactionParams, mutation: (current: {
62
71
  readonly stock: number | null;
72
+ readonly secondaryStock: number | null;
63
73
  readonly claimCount: number;
64
74
  readonly userState: UserRallyState;
65
75
  }) => ClaimRewardTransactionMutation): Promise<{
66
76
  readonly success: boolean;
67
77
  readonly error?: string;
68
78
  }>;
79
+ /** Set false when the adapter cannot persist per-reward inventory atomically. */
80
+ readonly supportsRewardStock?: boolean;
69
81
  acquireLock(rallyId: string, lockKey: string, ttlMs: number): Promise<boolean>;
70
82
  releaseLock(rallyId: string, lockKey: string): Promise<void>;
71
83
  getRewardStock(rallyId: string, rewardId: string): Promise<number | null>;
@@ -89,6 +101,7 @@ interface InMemoryServerPersistenceOptions {
89
101
  }
90
102
  declare class InMemoryServerPersistenceAdapter implements ServerPersistenceAdapter {
91
103
  #private;
104
+ readonly supportsRewardStock = true;
92
105
  constructor(options?: InMemoryServerPersistenceOptions);
93
106
  acquireLock(rallyId: string, key: string, ttlMs: number): Promise<boolean>;
94
107
  releaseLock(rallyId: string, key: string): Promise<void>;
@@ -100,6 +113,7 @@ declare class InMemoryServerPersistenceAdapter implements ServerPersistenceAdapt
100
113
  restoreRewardStock(rallyId: string, rewardId: string, count?: number): Promise<void>;
101
114
  executeClaimRewardTransaction(params: ClaimRewardTransactionParams, mutation: (current: {
102
115
  readonly stock: number | null;
116
+ readonly secondaryStock: number | null;
103
117
  readonly claimCount: number;
104
118
  readonly userState: UserRallyState;
105
119
  }) => ClaimRewardTransactionMutation): Promise<{
@@ -128,7 +142,7 @@ declare class InMemoryServerPersistenceAdapter implements ServerPersistenceAdapt
128
142
  /** @deprecated Use recordUserClaim with a ticket number and timestamp. */
129
143
  recordClaim(params: UserClaimRecord): Promise<void>;
130
144
  recordClaim(rallyId: string, userId: string, rewardId: string): Promise<void>;
131
- runTransaction<T>(_rallyId: string, operation: (transaction: ServerPersistenceAdapter) => Promise<T>): Promise<T>;
145
+ runTransaction<T>(rallyId: string, operation: (transaction: ServerPersistenceAdapter) => Promise<T>): Promise<T>;
132
146
  }
133
147
 
134
148
  /**
@@ -144,10 +158,12 @@ interface SqlTransactionDatabase<Tx> {
144
158
  interface SqlClaimRewardStore<Tx> {
145
159
  readContext(transaction: Tx, params: ClaimRewardTransactionParams): Promise<{
146
160
  readonly stock: number | null;
161
+ readonly secondaryStock?: number | null;
147
162
  readonly claimCount: number;
148
163
  readonly userState: UserRallyState;
149
164
  }>;
150
165
  writeStock(transaction: Tx, params: ClaimRewardTransactionParams, nextStock: number): Promise<void>;
166
+ writeSecondaryStock?(transaction: Tx, params: ClaimRewardTransactionParams, nextStock: number): Promise<void>;
151
167
  writeUserState(transaction: Tx, params: ClaimRewardTransactionParams, state: UserRallyState): Promise<void>;
152
168
  writeClaimRecord(transaction: Tx, params: ClaimRewardTransactionParams, state: UserRallyState): Promise<void>;
153
169
  writeAudit(transaction: Tx, log: AuditLog): Promise<void>;
@@ -167,11 +183,33 @@ declare function executeClaimRewardTransaction<Tx>(database: SqlTransactionDatab
167
183
  readonly success: boolean;
168
184
  readonly error?: string;
169
185
  }>;
186
+ interface SqlCheckInStore<Tx> {
187
+ readUserState?(transaction: Tx, params: CheckInTransactionParams): Promise<UserRallyState>;
188
+ writeUserState(transaction: Tx, params: CheckInTransactionParams, state: UserRallyState): Promise<void>;
189
+ writeAudit(transaction: Tx, log: AuditLog): Promise<void>;
190
+ writeIdempotency(transaction: Tx, params: CheckInTransactionParams, result: unknown): Promise<void>;
191
+ }
192
+ /** Reference transaction block for a check-in state, audit, and idempotency write. */
193
+ declare function executeCheckInTransaction<Tx>(database: SqlTransactionDatabase<Tx>, store: SqlCheckInStore<Tx>, params: CheckInTransactionParams, mutation: (current: {
194
+ readonly userState: UserRallyState;
195
+ }) => CheckInTransactionMutation, current?: UserRallyState): Promise<{
196
+ readonly success: boolean;
197
+ readonly error?: string;
198
+ }>;
199
+ interface RedisMultiExecutor<TMulti> {
200
+ multi(): TMulti;
201
+ exec(multi: TMulti): Promise<ReadonlyArray<unknown> | null>;
202
+ }
203
+ /** Reference for Redis MULTI/EXEC adapters: all queued commands commit together. */
204
+ declare function executeRedisTransaction<TMulti>(redis: RedisMultiExecutor<TMulti>, queue: (multi: TMulti) => void): Promise<{
205
+ readonly success: boolean;
206
+ readonly error?: string;
207
+ }>;
170
208
 
171
209
  interface RequestValidationError {
172
210
  readonly path: string;
173
211
  readonly message: string;
174
- readonly code: "invalid_request";
212
+ readonly code: string;
175
213
  }
176
214
  type RequestValidationResult<T> = {
177
215
  readonly success: true;
@@ -180,11 +218,27 @@ type RequestValidationResult<T> = {
180
218
  readonly success: false;
181
219
  readonly errors: ReadonlyArray<RequestValidationError>;
182
220
  };
221
+ declare class RequestValidationException extends Error {
222
+ readonly code = "VALIDATION_FAILED";
223
+ readonly errors: ReadonlyArray<RequestValidationError>;
224
+ constructor(errors: ReadonlyArray<RequestValidationError>);
225
+ }
183
226
  declare function validateCheckInRequest(value: unknown): RequestValidationResult<CheckInRequest>;
184
227
  declare function validateClaimRewardRequest(value: unknown): RequestValidationResult<ClaimRewardRequest>;
228
+ declare function assertValidCheckInParams(value: unknown, config: AdminRallyConfig): asserts value is CheckInRequest & {
229
+ readonly userId: string;
230
+ };
231
+ declare function assertValidClaimParams(value: unknown, config: AdminRallyConfig): asserts value is ClaimRewardRequest & {
232
+ readonly userId: string;
233
+ };
234
+ declare function assertValidSyncParams(value: unknown, config: AdminRallyConfig): asserts value is {
235
+ readonly rallyId: string;
236
+ readonly userId: string;
237
+ };
185
238
  declare function validateSyncRequest(value: unknown): RequestValidationResult<{
186
239
  readonly rallyId: string;
187
240
  readonly userId?: string;
241
+ readonly anonymousSessionId?: string;
188
242
  }>;
189
243
 
190
244
  type ErrorResponse = {
@@ -196,7 +250,12 @@ type ClaimResponse = {
196
250
  readonly ok: true;
197
251
  readonly state: UserRallyState;
198
252
  readonly claimTicketNumber?: string;
253
+ readonly inventory?: InventoryStatus;
199
254
  } | ErrorResponse;
255
+ interface InventoryStatus {
256
+ readonly sharedRemaining?: number;
257
+ readonly rewardRemaining?: number;
258
+ }
200
259
  declare class StampRallyServer {
201
260
  #private;
202
261
  constructor(config: AdminRallyConfig, persistence: ServerPersistenceAdapter, options?: ServerOptions);
@@ -204,15 +263,22 @@ declare class StampRallyServer {
204
263
  handleCheckIn(request: Request): Promise<Response>;
205
264
  handleClaimReward(request: Request): Promise<Response>;
206
265
  handleSync(request: Request): Promise<Response>;
207
- checkIn(request: CheckInRequest & {
208
- readonly userId: string;
209
- }): Promise<CheckInResponse>;
210
- claimReward(request: ClaimRewardRequest & {
211
- readonly userId: string;
212
- }): Promise<ClaimResponse>;
266
+ checkIn(request: CheckInRequest): Promise<CheckInResponse>;
267
+ claimReward(request: ClaimRewardRequest): Promise<ClaimResponse>;
213
268
  sync(rallyId: string, userId: string): Promise<UserRallyState>;
269
+ syncProgress(request: {
270
+ readonly rallyId: string;
271
+ readonly userId?: string;
272
+ readonly anonymousSessionId?: string;
273
+ }): Promise<UserRallyState>;
214
274
  }
215
275
 
276
+ /**
277
+ * Runs the minimum atomicity and idempotency contract against a persistence adapter.
278
+ * The function throws a descriptive error when the adapter violates the contract.
279
+ */
280
+ declare function runPersistenceAdapterComplianceTests(createAdapter: () => Promise<ServerPersistenceAdapter>): Promise<void>;
281
+
216
282
  interface AuditLog {
217
283
  readonly id: string;
218
284
  readonly timestamp: string;
@@ -228,19 +294,21 @@ type SyncOperationStatus = "ACCEPTED" | "REJECTED_PERMANENT" | "RETRYABLE_ERROR"
228
294
  interface CheckInRequest {
229
295
  readonly rallyId: string;
230
296
  readonly userId?: string;
297
+ readonly anonymousSessionId?: string;
231
298
  readonly spotId: string;
232
299
  readonly context: _stamprally_core.VerificationContext;
233
300
  readonly idempotencyKey: string;
234
- readonly now?: string;
301
+ readonly now?: string | number;
235
302
  }
236
303
  interface ClaimRewardRequest {
237
304
  readonly rallyId: string;
238
305
  readonly userId?: string;
306
+ readonly anonymousSessionId?: string;
239
307
  readonly rewardId: string;
240
308
  readonly idempotencyKey: string;
241
309
  readonly staffPasscode?: string;
242
310
  readonly staffId?: string;
243
- readonly now?: string;
311
+ readonly now?: string | number;
244
312
  }
245
313
  type CheckInResponse = {
246
314
  readonly ok: true;
@@ -258,9 +326,10 @@ interface ServerOptions {
258
326
  readonly authenticate?: (request: Request) => Promise<string | AuthenticationContext | null> | string | AuthenticationContext | null;
259
327
  readonly customValidators?: Readonly<Record<string, _stamprally_core.Validator>>;
260
328
  readonly now?: () => string;
329
+ readonly anonymousPolicy?: "session_scoped" | "reject" | "shared_global_opt_in_insecure";
261
330
  }
262
331
  interface AuthenticationContext {
263
332
  readonly authenticatedUserId: string;
264
333
  }
265
334
 
266
- export { type AuditLog, type AuthenticationContext, type CheckInRequest, type CheckInResponse, type CheckInTransactionMutation, type CheckInTransactionParams, type ClaimRewardRequest, type ClaimRewardTransactionMutation, type ClaimRewardTransactionParams, InMemoryServerPersistenceAdapter, type InMemoryServerPersistenceOptions, type RequestValidationError, type RequestValidationResult, type ServerOptions, type ServerPersistenceAdapter, type SqlClaimRewardStore, type SqlTransactionDatabase, StampRallyServer, type SyncOperationStatus, type UserClaimRecord, executeClaimRewardTransaction, validateCheckInRequest, validateClaimRewardRequest, validateSyncRequest };
335
+ export { type AuditLog, type AuthenticationContext, type CheckInRequest, type CheckInResponse, type CheckInTransactionMutation, type CheckInTransactionParams, type ClaimRewardRequest, type ClaimRewardTransactionMutation, type ClaimRewardTransactionParams, InMemoryServerPersistenceAdapter, type InMemoryServerPersistenceOptions, type RedisMultiExecutor, type RequestValidationError, RequestValidationException, type RequestValidationResult, type ServerOptions, type ServerPersistenceAdapter, type SqlCheckInStore, type SqlClaimRewardStore, type SqlTransactionDatabase, StampRallyServer, type SyncOperationStatus, type UserClaimRecord, assertValidCheckInParams, assertValidClaimParams, assertValidSyncParams, executeCheckInTransaction, executeClaimRewardTransaction, executeRedisTransaction, runPersistenceAdapterComplianceTests, validateCheckInRequest, validateClaimRewardRequest, validateSyncRequest };
package/dist/index.d.ts CHANGED
@@ -18,11 +18,20 @@ interface ClaimRewardTransactionParams {
18
18
  readonly idempotencyKey?: string;
19
19
  readonly proofData?: unknown;
20
20
  readonly idempotencyTtlMs?: number;
21
+ /** The configured per-reward stock limit, or null for unlimited stock. */
22
+ readonly rewardStockLimit: number | null;
23
+ /** The configured shared stock limit, or null when shared inventory is disabled. */
24
+ readonly sharedStockLimit: number | null;
21
25
  /** Used when the first claim is made before a user state has been stored. */
22
26
  readonly initialUserState?: UserRallyState;
27
+ readonly stockKey?: string;
28
+ readonly secondaryStockKey?: string;
29
+ readonly initialStock?: number | null;
30
+ readonly initialSecondaryStock?: number | null;
23
31
  }
24
32
  interface ClaimRewardTransactionMutation {
25
33
  readonly nextStock: number | null;
34
+ readonly nextSecondaryStock?: number | null;
26
35
  readonly nextUserState: UserRallyState;
27
36
  readonly auditLog: AuditLog;
28
37
  /** The server response is persisted by the adapter with the idempotency key. */
@@ -60,12 +69,15 @@ interface ServerPersistenceAdapter {
60
69
  */
61
70
  executeClaimRewardTransaction(params: ClaimRewardTransactionParams, mutation: (current: {
62
71
  readonly stock: number | null;
72
+ readonly secondaryStock: number | null;
63
73
  readonly claimCount: number;
64
74
  readonly userState: UserRallyState;
65
75
  }) => ClaimRewardTransactionMutation): Promise<{
66
76
  readonly success: boolean;
67
77
  readonly error?: string;
68
78
  }>;
79
+ /** Set false when the adapter cannot persist per-reward inventory atomically. */
80
+ readonly supportsRewardStock?: boolean;
69
81
  acquireLock(rallyId: string, lockKey: string, ttlMs: number): Promise<boolean>;
70
82
  releaseLock(rallyId: string, lockKey: string): Promise<void>;
71
83
  getRewardStock(rallyId: string, rewardId: string): Promise<number | null>;
@@ -89,6 +101,7 @@ interface InMemoryServerPersistenceOptions {
89
101
  }
90
102
  declare class InMemoryServerPersistenceAdapter implements ServerPersistenceAdapter {
91
103
  #private;
104
+ readonly supportsRewardStock = true;
92
105
  constructor(options?: InMemoryServerPersistenceOptions);
93
106
  acquireLock(rallyId: string, key: string, ttlMs: number): Promise<boolean>;
94
107
  releaseLock(rallyId: string, key: string): Promise<void>;
@@ -100,6 +113,7 @@ declare class InMemoryServerPersistenceAdapter implements ServerPersistenceAdapt
100
113
  restoreRewardStock(rallyId: string, rewardId: string, count?: number): Promise<void>;
101
114
  executeClaimRewardTransaction(params: ClaimRewardTransactionParams, mutation: (current: {
102
115
  readonly stock: number | null;
116
+ readonly secondaryStock: number | null;
103
117
  readonly claimCount: number;
104
118
  readonly userState: UserRallyState;
105
119
  }) => ClaimRewardTransactionMutation): Promise<{
@@ -128,7 +142,7 @@ declare class InMemoryServerPersistenceAdapter implements ServerPersistenceAdapt
128
142
  /** @deprecated Use recordUserClaim with a ticket number and timestamp. */
129
143
  recordClaim(params: UserClaimRecord): Promise<void>;
130
144
  recordClaim(rallyId: string, userId: string, rewardId: string): Promise<void>;
131
- runTransaction<T>(_rallyId: string, operation: (transaction: ServerPersistenceAdapter) => Promise<T>): Promise<T>;
145
+ runTransaction<T>(rallyId: string, operation: (transaction: ServerPersistenceAdapter) => Promise<T>): Promise<T>;
132
146
  }
133
147
 
134
148
  /**
@@ -144,10 +158,12 @@ interface SqlTransactionDatabase<Tx> {
144
158
  interface SqlClaimRewardStore<Tx> {
145
159
  readContext(transaction: Tx, params: ClaimRewardTransactionParams): Promise<{
146
160
  readonly stock: number | null;
161
+ readonly secondaryStock?: number | null;
147
162
  readonly claimCount: number;
148
163
  readonly userState: UserRallyState;
149
164
  }>;
150
165
  writeStock(transaction: Tx, params: ClaimRewardTransactionParams, nextStock: number): Promise<void>;
166
+ writeSecondaryStock?(transaction: Tx, params: ClaimRewardTransactionParams, nextStock: number): Promise<void>;
151
167
  writeUserState(transaction: Tx, params: ClaimRewardTransactionParams, state: UserRallyState): Promise<void>;
152
168
  writeClaimRecord(transaction: Tx, params: ClaimRewardTransactionParams, state: UserRallyState): Promise<void>;
153
169
  writeAudit(transaction: Tx, log: AuditLog): Promise<void>;
@@ -167,11 +183,33 @@ declare function executeClaimRewardTransaction<Tx>(database: SqlTransactionDatab
167
183
  readonly success: boolean;
168
184
  readonly error?: string;
169
185
  }>;
186
+ interface SqlCheckInStore<Tx> {
187
+ readUserState?(transaction: Tx, params: CheckInTransactionParams): Promise<UserRallyState>;
188
+ writeUserState(transaction: Tx, params: CheckInTransactionParams, state: UserRallyState): Promise<void>;
189
+ writeAudit(transaction: Tx, log: AuditLog): Promise<void>;
190
+ writeIdempotency(transaction: Tx, params: CheckInTransactionParams, result: unknown): Promise<void>;
191
+ }
192
+ /** Reference transaction block for a check-in state, audit, and idempotency write. */
193
+ declare function executeCheckInTransaction<Tx>(database: SqlTransactionDatabase<Tx>, store: SqlCheckInStore<Tx>, params: CheckInTransactionParams, mutation: (current: {
194
+ readonly userState: UserRallyState;
195
+ }) => CheckInTransactionMutation, current?: UserRallyState): Promise<{
196
+ readonly success: boolean;
197
+ readonly error?: string;
198
+ }>;
199
+ interface RedisMultiExecutor<TMulti> {
200
+ multi(): TMulti;
201
+ exec(multi: TMulti): Promise<ReadonlyArray<unknown> | null>;
202
+ }
203
+ /** Reference for Redis MULTI/EXEC adapters: all queued commands commit together. */
204
+ declare function executeRedisTransaction<TMulti>(redis: RedisMultiExecutor<TMulti>, queue: (multi: TMulti) => void): Promise<{
205
+ readonly success: boolean;
206
+ readonly error?: string;
207
+ }>;
170
208
 
171
209
  interface RequestValidationError {
172
210
  readonly path: string;
173
211
  readonly message: string;
174
- readonly code: "invalid_request";
212
+ readonly code: string;
175
213
  }
176
214
  type RequestValidationResult<T> = {
177
215
  readonly success: true;
@@ -180,11 +218,27 @@ type RequestValidationResult<T> = {
180
218
  readonly success: false;
181
219
  readonly errors: ReadonlyArray<RequestValidationError>;
182
220
  };
221
+ declare class RequestValidationException extends Error {
222
+ readonly code = "VALIDATION_FAILED";
223
+ readonly errors: ReadonlyArray<RequestValidationError>;
224
+ constructor(errors: ReadonlyArray<RequestValidationError>);
225
+ }
183
226
  declare function validateCheckInRequest(value: unknown): RequestValidationResult<CheckInRequest>;
184
227
  declare function validateClaimRewardRequest(value: unknown): RequestValidationResult<ClaimRewardRequest>;
228
+ declare function assertValidCheckInParams(value: unknown, config: AdminRallyConfig): asserts value is CheckInRequest & {
229
+ readonly userId: string;
230
+ };
231
+ declare function assertValidClaimParams(value: unknown, config: AdminRallyConfig): asserts value is ClaimRewardRequest & {
232
+ readonly userId: string;
233
+ };
234
+ declare function assertValidSyncParams(value: unknown, config: AdminRallyConfig): asserts value is {
235
+ readonly rallyId: string;
236
+ readonly userId: string;
237
+ };
185
238
  declare function validateSyncRequest(value: unknown): RequestValidationResult<{
186
239
  readonly rallyId: string;
187
240
  readonly userId?: string;
241
+ readonly anonymousSessionId?: string;
188
242
  }>;
189
243
 
190
244
  type ErrorResponse = {
@@ -196,7 +250,12 @@ type ClaimResponse = {
196
250
  readonly ok: true;
197
251
  readonly state: UserRallyState;
198
252
  readonly claimTicketNumber?: string;
253
+ readonly inventory?: InventoryStatus;
199
254
  } | ErrorResponse;
255
+ interface InventoryStatus {
256
+ readonly sharedRemaining?: number;
257
+ readonly rewardRemaining?: number;
258
+ }
200
259
  declare class StampRallyServer {
201
260
  #private;
202
261
  constructor(config: AdminRallyConfig, persistence: ServerPersistenceAdapter, options?: ServerOptions);
@@ -204,15 +263,22 @@ declare class StampRallyServer {
204
263
  handleCheckIn(request: Request): Promise<Response>;
205
264
  handleClaimReward(request: Request): Promise<Response>;
206
265
  handleSync(request: Request): Promise<Response>;
207
- checkIn(request: CheckInRequest & {
208
- readonly userId: string;
209
- }): Promise<CheckInResponse>;
210
- claimReward(request: ClaimRewardRequest & {
211
- readonly userId: string;
212
- }): Promise<ClaimResponse>;
266
+ checkIn(request: CheckInRequest): Promise<CheckInResponse>;
267
+ claimReward(request: ClaimRewardRequest): Promise<ClaimResponse>;
213
268
  sync(rallyId: string, userId: string): Promise<UserRallyState>;
269
+ syncProgress(request: {
270
+ readonly rallyId: string;
271
+ readonly userId?: string;
272
+ readonly anonymousSessionId?: string;
273
+ }): Promise<UserRallyState>;
214
274
  }
215
275
 
276
+ /**
277
+ * Runs the minimum atomicity and idempotency contract against a persistence adapter.
278
+ * The function throws a descriptive error when the adapter violates the contract.
279
+ */
280
+ declare function runPersistenceAdapterComplianceTests(createAdapter: () => Promise<ServerPersistenceAdapter>): Promise<void>;
281
+
216
282
  interface AuditLog {
217
283
  readonly id: string;
218
284
  readonly timestamp: string;
@@ -228,19 +294,21 @@ type SyncOperationStatus = "ACCEPTED" | "REJECTED_PERMANENT" | "RETRYABLE_ERROR"
228
294
  interface CheckInRequest {
229
295
  readonly rallyId: string;
230
296
  readonly userId?: string;
297
+ readonly anonymousSessionId?: string;
231
298
  readonly spotId: string;
232
299
  readonly context: _stamprally_core.VerificationContext;
233
300
  readonly idempotencyKey: string;
234
- readonly now?: string;
301
+ readonly now?: string | number;
235
302
  }
236
303
  interface ClaimRewardRequest {
237
304
  readonly rallyId: string;
238
305
  readonly userId?: string;
306
+ readonly anonymousSessionId?: string;
239
307
  readonly rewardId: string;
240
308
  readonly idempotencyKey: string;
241
309
  readonly staffPasscode?: string;
242
310
  readonly staffId?: string;
243
- readonly now?: string;
311
+ readonly now?: string | number;
244
312
  }
245
313
  type CheckInResponse = {
246
314
  readonly ok: true;
@@ -258,9 +326,10 @@ interface ServerOptions {
258
326
  readonly authenticate?: (request: Request) => Promise<string | AuthenticationContext | null> | string | AuthenticationContext | null;
259
327
  readonly customValidators?: Readonly<Record<string, _stamprally_core.Validator>>;
260
328
  readonly now?: () => string;
329
+ readonly anonymousPolicy?: "session_scoped" | "reject" | "shared_global_opt_in_insecure";
261
330
  }
262
331
  interface AuthenticationContext {
263
332
  readonly authenticatedUserId: string;
264
333
  }
265
334
 
266
- export { type AuditLog, type AuthenticationContext, type CheckInRequest, type CheckInResponse, type CheckInTransactionMutation, type CheckInTransactionParams, type ClaimRewardRequest, type ClaimRewardTransactionMutation, type ClaimRewardTransactionParams, InMemoryServerPersistenceAdapter, type InMemoryServerPersistenceOptions, type RequestValidationError, type RequestValidationResult, type ServerOptions, type ServerPersistenceAdapter, type SqlClaimRewardStore, type SqlTransactionDatabase, StampRallyServer, type SyncOperationStatus, type UserClaimRecord, executeClaimRewardTransaction, validateCheckInRequest, validateClaimRewardRequest, validateSyncRequest };
335
+ export { type AuditLog, type AuthenticationContext, type CheckInRequest, type CheckInResponse, type CheckInTransactionMutation, type CheckInTransactionParams, type ClaimRewardRequest, type ClaimRewardTransactionMutation, type ClaimRewardTransactionParams, InMemoryServerPersistenceAdapter, type InMemoryServerPersistenceOptions, type RedisMultiExecutor, type RequestValidationError, RequestValidationException, type RequestValidationResult, type ServerOptions, type ServerPersistenceAdapter, type SqlCheckInStore, type SqlClaimRewardStore, type SqlTransactionDatabase, StampRallyServer, type SyncOperationStatus, type UserClaimRecord, assertValidCheckInParams, assertValidClaimParams, assertValidSyncParams, executeCheckInTransaction, executeClaimRewardTransaction, executeRedisTransaction, runPersistenceAdapterComplianceTests, validateCheckInRequest, validateClaimRewardRequest, validateSyncRequest };