@stamprally/server 0.13.0 → 0.15.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.ts CHANGED
@@ -20,9 +20,14 @@ interface ClaimRewardTransactionParams {
20
20
  readonly idempotencyTtlMs?: number;
21
21
  /** Used when the first claim is made before a user state has been stored. */
22
22
  readonly initialUserState?: UserRallyState;
23
+ readonly stockKey?: string;
24
+ readonly secondaryStockKey?: string;
25
+ readonly initialStock?: number | null;
26
+ readonly initialSecondaryStock?: number | null;
23
27
  }
24
28
  interface ClaimRewardTransactionMutation {
25
29
  readonly nextStock: number | null;
30
+ readonly nextSecondaryStock?: number | null;
26
31
  readonly nextUserState: UserRallyState;
27
32
  readonly auditLog: AuditLog;
28
33
  /** The server response is persisted by the adapter with the idempotency key. */
@@ -30,13 +35,37 @@ interface ClaimRewardTransactionMutation {
30
35
  /** A domain rejection is committed as an audit/idempotency record without mutations. */
31
36
  readonly error?: string;
32
37
  }
38
+ interface CheckInTransactionParams {
39
+ readonly rallyId: string;
40
+ readonly userId: string;
41
+ readonly spotId: string;
42
+ readonly timestamp: number;
43
+ readonly idempotencyKey?: string;
44
+ readonly proofData?: unknown;
45
+ readonly idempotencyTtlMs?: number;
46
+ readonly initialUserState?: UserRallyState;
47
+ }
48
+ interface CheckInTransactionMutation {
49
+ readonly nextUserState: UserRallyState;
50
+ readonly auditLog: AuditLog;
51
+ readonly result?: unknown;
52
+ readonly error?: string;
53
+ }
33
54
  interface ServerPersistenceAdapter {
55
+ /** Atomically commits user state, audit log, and idempotency data. */
56
+ executeCheckInTransaction(params: CheckInTransactionParams, mutation: (current: {
57
+ readonly userState: UserRallyState;
58
+ }) => CheckInTransactionMutation): Promise<{
59
+ readonly success: boolean;
60
+ readonly error?: string;
61
+ }>;
34
62
  /**
35
63
  * Atomically commits stock, user state, claim count, audit log, and idempotency data.
36
64
  * Adapters must roll back every write when the callback or any commit operation fails.
37
65
  */
38
66
  executeClaimRewardTransaction(params: ClaimRewardTransactionParams, mutation: (current: {
39
67
  readonly stock: number | null;
68
+ readonly secondaryStock: number | null;
40
69
  readonly claimCount: number;
41
70
  readonly userState: UserRallyState;
42
71
  }) => ClaimRewardTransactionMutation): Promise<{
@@ -77,12 +106,19 @@ declare class InMemoryServerPersistenceAdapter implements ServerPersistenceAdapt
77
106
  restoreRewardStock(rallyId: string, rewardId: string, count?: number): Promise<void>;
78
107
  executeClaimRewardTransaction(params: ClaimRewardTransactionParams, mutation: (current: {
79
108
  readonly stock: number | null;
109
+ readonly secondaryStock: number | null;
80
110
  readonly claimCount: number;
81
111
  readonly userState: UserRallyState;
82
112
  }) => ClaimRewardTransactionMutation): Promise<{
83
113
  readonly success: boolean;
84
114
  readonly error?: string;
85
115
  }>;
116
+ executeCheckInTransaction(params: CheckInTransactionParams, mutation: (current: {
117
+ readonly userState: UserRallyState;
118
+ }) => CheckInTransactionMutation): Promise<{
119
+ readonly success: boolean;
120
+ readonly error?: string;
121
+ }>;
86
122
  rollbackUserState(rallyId: string, userId: string, previousState: UserRallyState | null): Promise<void>;
87
123
  getIdempotentResult<T>(rallyId: string, key: string): Promise<T | null>;
88
124
  saveIdempotentResult<T>(rallyId: string, key: string, result: T, ttlMs: number): Promise<void>;
@@ -115,10 +151,12 @@ interface SqlTransactionDatabase<Tx> {
115
151
  interface SqlClaimRewardStore<Tx> {
116
152
  readContext(transaction: Tx, params: ClaimRewardTransactionParams): Promise<{
117
153
  readonly stock: number | null;
154
+ readonly secondaryStock?: number | null;
118
155
  readonly claimCount: number;
119
156
  readonly userState: UserRallyState;
120
157
  }>;
121
158
  writeStock(transaction: Tx, params: ClaimRewardTransactionParams, nextStock: number): Promise<void>;
159
+ writeSecondaryStock?(transaction: Tx, params: ClaimRewardTransactionParams, nextStock: number): Promise<void>;
122
160
  writeUserState(transaction: Tx, params: ClaimRewardTransactionParams, state: UserRallyState): Promise<void>;
123
161
  writeClaimRecord(transaction: Tx, params: ClaimRewardTransactionParams, state: UserRallyState): Promise<void>;
124
162
  writeAudit(transaction: Tx, log: AuditLog): Promise<void>;
@@ -138,6 +176,47 @@ declare function executeClaimRewardTransaction<Tx>(database: SqlTransactionDatab
138
176
  readonly success: boolean;
139
177
  readonly error?: string;
140
178
  }>;
179
+ interface SqlCheckInStore<Tx> {
180
+ readUserState?(transaction: Tx, params: CheckInTransactionParams): Promise<UserRallyState>;
181
+ writeUserState(transaction: Tx, params: CheckInTransactionParams, state: UserRallyState): Promise<void>;
182
+ writeAudit(transaction: Tx, log: AuditLog): Promise<void>;
183
+ writeIdempotency(transaction: Tx, params: CheckInTransactionParams, result: unknown): Promise<void>;
184
+ }
185
+ /** Reference transaction block for a check-in state, audit, and idempotency write. */
186
+ declare function executeCheckInTransaction<Tx>(database: SqlTransactionDatabase<Tx>, store: SqlCheckInStore<Tx>, params: CheckInTransactionParams, mutation: (current: {
187
+ readonly userState: UserRallyState;
188
+ }) => CheckInTransactionMutation, current?: UserRallyState): Promise<{
189
+ readonly success: boolean;
190
+ readonly error?: string;
191
+ }>;
192
+ interface RedisMultiExecutor<TMulti> {
193
+ multi(): TMulti;
194
+ exec(multi: TMulti): Promise<ReadonlyArray<unknown> | null>;
195
+ }
196
+ /** Reference for Redis MULTI/EXEC adapters: all queued commands commit together. */
197
+ declare function executeRedisTransaction<TMulti>(redis: RedisMultiExecutor<TMulti>, queue: (multi: TMulti) => void): Promise<{
198
+ readonly success: boolean;
199
+ readonly error?: string;
200
+ }>;
201
+
202
+ interface RequestValidationError {
203
+ readonly path: string;
204
+ readonly message: string;
205
+ readonly code: string;
206
+ }
207
+ type RequestValidationResult<T> = {
208
+ readonly success: true;
209
+ readonly data: T;
210
+ } | {
211
+ readonly success: false;
212
+ readonly errors: ReadonlyArray<RequestValidationError>;
213
+ };
214
+ declare function validateCheckInRequest(value: unknown): RequestValidationResult<CheckInRequest>;
215
+ declare function validateClaimRewardRequest(value: unknown): RequestValidationResult<ClaimRewardRequest>;
216
+ declare function validateSyncRequest(value: unknown): RequestValidationResult<{
217
+ readonly rallyId: string;
218
+ readonly userId?: string;
219
+ }>;
141
220
 
142
221
  type ErrorResponse = {
143
222
  readonly ok: false;
@@ -148,7 +227,12 @@ type ClaimResponse = {
148
227
  readonly ok: true;
149
228
  readonly state: UserRallyState;
150
229
  readonly claimTicketNumber?: string;
230
+ readonly inventory?: InventoryStatus;
151
231
  } | ErrorResponse;
232
+ interface InventoryStatus {
233
+ readonly sharedRemaining?: number;
234
+ readonly rewardRemaining?: number;
235
+ }
152
236
  declare class StampRallyServer {
153
237
  #private;
154
238
  constructor(config: AdminRallyConfig, persistence: ServerPersistenceAdapter, options?: ServerOptions);
@@ -183,7 +267,7 @@ interface CheckInRequest {
183
267
  readonly spotId: string;
184
268
  readonly context: _stamprally_core.VerificationContext;
185
269
  readonly idempotencyKey: string;
186
- readonly now?: string;
270
+ readonly now?: string | number;
187
271
  }
188
272
  interface ClaimRewardRequest {
189
273
  readonly rallyId: string;
@@ -192,7 +276,7 @@ interface ClaimRewardRequest {
192
276
  readonly idempotencyKey: string;
193
277
  readonly staffPasscode?: string;
194
278
  readonly staffId?: string;
195
- readonly now?: string;
279
+ readonly now?: string | number;
196
280
  }
197
281
  type CheckInResponse = {
198
282
  readonly ok: true;
@@ -207,9 +291,13 @@ type CheckInResponse = {
207
291
  interface ServerOptions {
208
292
  readonly lockTtlMs?: number;
209
293
  readonly idempotencyTtlMs?: number;
210
- readonly authenticate?: (request: Request) => Promise<string | null> | string | null;
294
+ readonly authenticate?: (request: Request) => Promise<string | AuthenticationContext | null> | string | AuthenticationContext | null;
211
295
  readonly customValidators?: Readonly<Record<string, _stamprally_core.Validator>>;
212
296
  readonly now?: () => string;
297
+ readonly anonymousPolicy?: "session_scoped" | "reject";
298
+ }
299
+ interface AuthenticationContext {
300
+ readonly authenticatedUserId: string;
213
301
  }
214
302
 
215
- export { type AuditLog, type CheckInRequest, type CheckInResponse, type ClaimRewardRequest, type ClaimRewardTransactionMutation, type ClaimRewardTransactionParams, InMemoryServerPersistenceAdapter, type InMemoryServerPersistenceOptions, type ServerOptions, type ServerPersistenceAdapter, type SqlClaimRewardStore, type SqlTransactionDatabase, StampRallyServer, type SyncOperationStatus, type UserClaimRecord, executeClaimRewardTransaction };
303
+ 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, type RequestValidationResult, type ServerOptions, type ServerPersistenceAdapter, type SqlCheckInStore, type SqlClaimRewardStore, type SqlTransactionDatabase, StampRallyServer, type SyncOperationStatus, type UserClaimRecord, executeCheckInTransaction, executeClaimRewardTransaction, executeRedisTransaction, validateCheckInRequest, validateClaimRewardRequest, validateSyncRequest };