2424 */
2525
2626import { mockData } from "../test/mock-data" ;
27- import {
28- Feedback ,
29- IdMapping ,
30- Publication ,
31- Purchase ,
32- PurchasesStatisticsData ,
33- Refund ,
34- Tester ,
35- } from "../types/data" ;
36-
3727import { CloudflareD1DB } from "./d1-db" ;
3828import { InMemoryDB } from "./in-memory-db" ;
29+ import { FeedbackFlowDB } from "../types/db-types" ;
3930
40- export const DEFAULT_PAGINATION = {
41- page : 1 ,
42- limit : 10 ,
43- sort : "date" ,
44- order : "desc" ,
45- } ;
46-
47- /**
48- * Interface for database structure
49- */
50- export interface DATABASESCHEMA {
51- ids : IdMapping [ ] ;
52- testers : Tester [ ] ;
53- purchases : Purchase [ ] ;
54- feedbacks : Feedback [ ] ;
55- publications : Publication [ ] ;
56- refunds : Refund [ ] ;
57- }
58-
59- export interface PurchaseStatusResponse { results : PurchaseStatus [ ] ; pageInfo : { totalCount : number ; totalPages : number ; currentPage : number ; hasNextPage : boolean ; hasPreviousPage : boolean ; nextPage : number | null ; previousPage : number | null ; } ; }
60- export interface PurchaseStatus {
61- purchase : string ;
62- testerUuid : string ;
63- date : string ;
64- order : string ;
65- description : string ;
66- amount : number ;
67- refunded : boolean ;
68- hasFeedback : boolean ;
69- hasPublication : boolean ;
70- hasRefund : boolean ;
71- purchaseScreenshot ?: string ;
72- publicationScreenshot ?: string ;
73- screenshotSummary ?: string ;
74- }
75- /**
76- * IdMappings repository interface (async version)
77- */
78- export interface IdMappingsRepository {
79- /**
80- * Check if an ID exists in the database
81- * @param id The OAuth ID to check
82- */
83- exists ( id : string ) : Promise < boolean > ;
84-
85- /**
86- * Check if multiple IDs exist in the database
87- * @param ids Array of OAuth IDs to check
88- */
89- existsMultiple ( ids : string [ ] ) : Promise < string [ ] > ;
90-
91- /**
92- * Get the tester UUID associated with an ID
93- * @param id The OAuth ID to look up
94- */
95- getTesterUuid ( id : string ) : Promise < string | undefined > ;
96-
97- /**
98- * Add a new ID to tester mapping
99- * @param id The OAuth ID
100- * @param testerUuid The associated tester UUID
101- */
102- put ( id : string , testerUuid : string ) : Promise < boolean > ;
103-
104- /**
105- * Add multiple ID to tester mappings
106- * @param ids Array of OAuth IDs
107- * @param testerUuid The associated tester UUID
108- */
109- putMultiple ( ids : string [ ] , testerUuid : string ) : Promise < string [ ] > ;
110-
111- /**
112- * Delete an ID mapping
113- * @param id The OAuth ID to delete
114- */
115- delete ( id : string ) : Promise < boolean > ;
116-
117- /**
118- * Get all ID mappings
119- */
120- getAll ( ) : Promise < IdMapping [ ] > ;
121- }
122-
123- /**
124- * Testers repository interface (async version)
125- */
126- export interface TestersRepository {
127- /**
128- * Find a tester that matches the provided condition
129- * @param fn Predicate function to filter testers
130- */
131- find ( fn : ( tester : Tester ) => boolean ) : Promise < Tester | undefined > ;
132-
133- /**
134- * Filter testers based on the provided condition
135- * @param fn Predicate function to filter testers
136- */
137- filter ( fn : ( tester : Tester ) => boolean ) : Promise < Tester [ ] > ;
138-
139- /**
140- * Add or update a tester in the database
141- * @param newTester The tester object to add or update
142- */
143- put ( newTester : Tester ) : Promise < string [ ] > ;
144-
145- /**
146- * Get all testers from the database
147- */
148- getAll ( ) : Promise < Tester [ ] > ;
149-
150- /**
151- * Find a tester by their authentication ID
152- * @param id Authentication ID to search for
153- */
154- getTesterWithId ( id : string ) : Promise < Tester | undefined > ;
155-
156- /**
157- * Find a tester by their UUID
158- * @param uuid UUID to search for
159- */
160- getTesterWithUuid ( uuid : string ) : Promise < Tester | undefined > ;
161-
162- /**
163- * Add IDs to an existing tester
164- * @param uuid UUID of the tester to update
165- * @param ids IDs to add to the tester
166- */
167- addIds ( uuid : string , ids : string [ ] ) : Promise < string [ ] | undefined > ;
168- }
169-
170- export interface PaginatedResult < T > {
171- results : T [ ] ;
172- totalCount : number ;
173- }
174-
175- // Define PurchaseWithFeedback type that extends Purchase with feedback and publication data
176- export interface PurchaseWithFeedback extends Purchase {
177- /**
178- * The feedback content associated with this purchase
179- */
180- feedback : string ;
181-
182- /**
183- * The date when the feedback was submitted
184- */
185- feedbackDate : string ;
186-
187- /**
188- * The publication screenshot, if available
189- */
190- publicationScreenshot ?: string ;
191-
192- /**
193- * The date when the feedback was published, if available
194- */
195- publicationDate ?: string ;
196- }
197-
198- // Convertir également PurchasesRepository, FeedbacksRepository, PublicationsRepository, RefundsRepository
199- // de manière similaire (toutes les méthodes retournent des Promises)
200- export interface PurchasesRepository {
201- /**
202- * Find a purchase that matches the provided condition
203- * @param fn Predicate function to filter purchases
204- */
205- find ( fn : ( purchase : Purchase ) => boolean ) : Promise < Purchase | undefined > ;
206- /**
207- * Filter purchases based on the provided condition
208- * @param fn Predicate function to filter purchases
209- */
210- filter ( fn : ( purchase : Purchase ) => boolean ) : Promise < Purchase [ ] > ;
211- /**
212- * Add or update a purchase in the database
213- * @param newPurchase The purchase object to add or update
214- */
215- refunded ( testerUuid : string , pagination ?: typeof DEFAULT_PAGINATION ) : Promise < PaginatedResult < Purchase > > ;
216- /**
217- * Get the total number of refunded purchases for a tester
218- * @param testerUuid UUID of the tester
219- */
220- refundedAmount ( testerUuid : string ) : Promise < number > ;
221- /**
222- * Get all purchases for a tester that are not refunded
223- * @param testerUuid UUID of the tester
224- * @param pagination Optional pagination parameters
225- */
226- notRefunded ( testerUuid : string , pagination ?: typeof DEFAULT_PAGINATION ) : Promise < PaginatedResult < Purchase > > ;
227- /**
228- * Get all purchases for a tester ready for refund (not refunded and with feedback)
229- * @param testerUuid UUID of the tester
230- * @param pagination Optional pagination parameters
231- */
232- readyForRefund (
233- testerUuid : string ,
234- pagination ?: typeof DEFAULT_PAGINATION ,
235- ) : Promise < PaginatedResult < PurchaseWithFeedback > > ;
236- /**
237- * Get the total number of purchases for a tester that are not refunded
238- * @param testerUuid UUID of the tester
239- */
240- notRefundedAmount ( testerUuid : string ) : Promise < number > ;
241- /**
242- * Get all purchases for a tester
243- * @param testerUuid UUID of the tester
244- * @param pagination Optional pagination parameters
245- */
246- delete ( id : string ) : Promise < boolean > ;
247- /**
248- * Add a new purchase for a tester
249- * @param testerUuid UUID of the tester
250- * @param newPurchase The purchase object to add
251- */
252- put ( testerUuid : string , newPurchase : Purchase ) : Promise < string > ;
253- /**
254- * Update an existing purchase
255- * @param id The ID of the purchase to update
256- * @param updates The updates to apply to the purchase
257- */
258- update ( id : string , updates : Partial < Purchase > ) : Promise < boolean > ;
259- /**
260- * Get all purchases for a tester
261- * @param testerUuid UUID of the tester
262- * @param pagination Optional pagination parameters
263- */
264- getAll ( ) : Promise < Purchase [ ] > ;
265-
266- /**
267- * Get all purchases for a tester with full status
268- * @param testerUuid UUID of the tester
269- * @param limitToNotRefunded Optional flag to limit to not refunded purchases
270- * @param page Optional page number for pagination
271- * @param limit Optional limit for number of results per page
272- * @param sort Optional sorting field
273- * @param order Optional sorting order (asc/desc)
274- */
275- getPurchaseStatus (
276- testerUuid : string ,
277- limitToNotRefunded ?: boolean ,
278- page ?: number ,
279- limit ?: number ,
280- sort ?: string ,
281- order ?: string ,
282- ) : Promise < PurchaseStatusResponse > ;
283-
284- /**
285- * Get some statistics of purchases for a tester
286- * @param testerUuid UUID of the tester
287- * @returns Promise<PurchasesStatisticsData> Statistics data for the tester's purchases
288- */
289- getPurchaseStatistics (
290- testerUuid : string ) : Promise < PurchasesStatisticsData > ;
291- }
292-
293- export interface FeedbacksRepository {
294- find ( fn : ( feedback : Feedback ) => boolean ) : Promise < Feedback | undefined > ;
295- filter ( fn : ( feedback : Feedback ) => boolean ) : Promise < Feedback [ ] > ;
296- put ( testerId : string , newFeedback : Feedback ) : Promise < string > ;
297- getAll ( ) : Promise < Feedback [ ] > ;
298- }
299-
300- export interface PublicationsRepository {
301- find (
302- fn : ( publication : Publication ) => boolean ,
303- ) : Promise < Publication | undefined > ;
304- filter ( fn : ( publication : Publication ) => boolean ) : Promise < Publication [ ] > ;
305- put ( testerId : string , newPublication : Publication ) : Promise < string > ;
306- getAll ( ) : Promise < Publication [ ] > ;
307- }
308-
309- export interface RefundsRepository {
310- find ( fn : ( refund : Refund ) => boolean ) : Promise < Refund | undefined > ;
311- filter ( fn : ( refund : Refund ) => boolean ) : Promise < Refund [ ] > ;
312- put ( testerId : string , newRefund : Refund ) : Promise < string > ;
313- getAll ( ) : Promise < Refund [ ] > ;
314- }
315-
316- /**
317- * Abstract database class that defines the interface for all database implementations
318- */
319- export abstract class FeedbackFlowDB {
320- /**
321- * ID mappings operations
322- */
323- abstract idMappings : IdMappingsRepository ;
324-
325- /**
326- * Tester-related database operations
327- */
328- abstract testers : TestersRepository ;
329-
330- /**
331- * Purchase-related database operations
332- */
333- abstract purchases : PurchasesRepository ;
334-
335- /**
336- * Feedback-related database operations
337- */
338- abstract feedbacks : FeedbacksRepository ;
339-
340- /**
341- * Publication-related database operations
342- */
343- abstract publications : PublicationsRepository ;
344-
345- /**
346- * Refund-related database operations
347- */
348- abstract refunds : RefundsRepository ;
349-
350- /**
351- * Reset the database with new data (optional)
352- */
353- abstract reset ?( newData : DATABASESCHEMA ) : Promise < void > ;
354-
355- /**
356- * Get a copy of the raw database data (optional)
357- */
358- abstract getRawData ?( ) : Promise < DATABASESCHEMA > ;
359-
360- /**
361- * Backup the database to JSON string (optional)
362- */
363- abstract backupToJson ?( ) : Promise < string > ;
364-
365- /**
366- * Restore the database from JSON string (optional)
367- */
368- abstract restoreFromJsonString ?(
369- backup : string ,
370- ) : Promise < { success : boolean ; message ?: string } > ;
371- }
31+ // Export all types from the shared db-types file
32+ export * from "../types/db-types" ;
37233
37334/**
37435 * Singleton instance of the database
@@ -381,7 +42,7 @@ let dbInstance: FeedbackFlowDB | null = null;
38142 */
38243export function getDatabase ( env : Env ) : FeedbackFlowDB {
38344 if ( dbInstance === null ) {
384- // Initialize the database based on env.DB_BACKEND
45+ // Initialize the database based on env.DB_BACKEND
38546 dbInstance =
38647 env . DB_BACKEND !== "memory"
38748 ? ( new CloudflareD1DB ( env . FeedbackFlowDB ) as FeedbackFlowDB )
0 commit comments