Skip to content

Commit db142c0

Browse files
committed
finalize routes refactoring
1 parent be73671 commit db142c0

File tree

7 files changed

+1806
-1630
lines changed

7 files changed

+1806
-1630
lines changed

client/get-openapi.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,11 @@ const options = {
2121
"../cloudflare-worker/src/routes/index.ts",
2222
"../cloudflare-worker/src/routes/testers/index.ts",
2323
"../cloudflare-worker/src/routes/purchases/index.ts",
24+
"../cloudflare-worker/src/routes/purchases/crud.ts",
25+
"../cloudflare-worker/src/routes/purchases/list.ts",
26+
"../cloudflare-worker/src/routes/purchases/amounts.ts",
27+
"../cloudflare-worker/src/routes/purchases/status.ts",
28+
"../cloudflare-worker/src/routes/purchases/search.ts",
2429
"../cloudflare-worker/src/routes/feedback/index.ts",
2530
"../cloudflare-worker/src/routes/refunds/index.ts",
2631
"../cloudflare-worker/src/routes/stats/index.ts",
Lines changed: 211 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,211 @@
1+
/**
2+
* MIT License
3+
*
4+
* Copyright (c) 2025 Ronan LE MEILLAT
5+
*
6+
* Permission is hereby granted, free of charge, to any person obtaining a copy
7+
* of this software and associated documentation files (the "Software"), to deal
8+
* in the Software without restriction, including without limitation the rights
9+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
* copies of the Software, and to permit persons to whom the Software is
11+
* furnished to do so, subject to the following conditions:
12+
*
13+
* The above copyright notice and this permission notice shall be included in all
14+
* copies or substantial portions of the Software.
15+
*
16+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22+
* SOFTWARE.
23+
*/
24+
25+
import { getDatabase } from "../../db/db";
26+
import { Router } from "../router";
27+
28+
/**
29+
* Setup amount/total routes for purchases (refunded-amount, not-refunded-amount)
30+
*/
31+
export const setupPurchaseAmountRoutes = (router: Router, env: Env) => {
32+
/**
33+
* @openapi
34+
* /api/purchases/refunded-amount:
35+
* get:
36+
* summary: Get total amount of refunded purchases
37+
* description: Returns the total amount of refunded purchases for the authenticated user. Requires read permission.
38+
* tags:
39+
* - Purchases
40+
* responses:
41+
* 200:
42+
* description: Successfully retrieved total refunded amount
43+
* content:
44+
* application/json:
45+
* schema:
46+
* type: object
47+
* properties:
48+
* success:
49+
* type: boolean
50+
* example: true
51+
* amount:
52+
* type: number
53+
* description: Total refunded amount
54+
* example: 123.45
55+
* 403:
56+
* description: Unauthorized request
57+
*/
58+
router.get(
59+
"/api/purchases/refunded-amount",
60+
async () => {
61+
const db = getDatabase(env);
62+
63+
// Get user ID from authenticated user
64+
const userId = router.jwtPayload.sub;
65+
66+
if (!userId) {
67+
return router.handleUnauthorizedRequest();
68+
}
69+
70+
// Find tester by user ID
71+
const testerUuid = await db.idMappings.getTesterUuid(userId);
72+
73+
if (!testerUuid) {
74+
return new Response(
75+
JSON.stringify({ success: false, error: "Unauthorized" }),
76+
{
77+
status: 403,
78+
headers: {
79+
...router.corsHeaders,
80+
"Content-Type": "application/json",
81+
},
82+
},
83+
);
84+
}
85+
86+
try {
87+
// Use the optimized function for getting total refunded amount
88+
const amount = await db.purchases.refundedAmount(testerUuid);
89+
90+
return new Response(
91+
JSON.stringify({
92+
success: true,
93+
amount,
94+
}),
95+
{
96+
status: 200,
97+
headers: {
98+
...router.corsHeaders,
99+
"Content-Type": "application/json",
100+
},
101+
},
102+
);
103+
} catch (error) {
104+
return new Response(
105+
JSON.stringify({
106+
success: false,
107+
error: `Error fetching refunded amount: ${(error as Error).message}`,
108+
}),
109+
{
110+
status: 500,
111+
headers: {
112+
...router.corsHeaders,
113+
"Content-Type": "application/json",
114+
},
115+
},
116+
);
117+
}
118+
},
119+
env.READ_PERMISSION,
120+
);
121+
122+
/**
123+
* @openapi
124+
* /api/purchases/not-refunded-amount:
125+
* get:
126+
* summary: Get total amount of non-refunded purchases
127+
* description: Returns the total amount of non-refunded purchases for the authenticated user. Requires read permission.
128+
* tags:
129+
* - Purchases
130+
* responses:
131+
* 200:
132+
* description: Successfully retrieved total non-refunded amount
133+
* content:
134+
* application/json:
135+
* schema:
136+
* type: object
137+
* properties:
138+
* success:
139+
* type: boolean
140+
* example: true
141+
* amount:
142+
* type: number
143+
* description: Total non-refunded amount
144+
* example: 456.78
145+
* 403:
146+
* description: Unauthorized request
147+
*/
148+
router.get(
149+
"/api/purchases/not-refunded-amount",
150+
async () => {
151+
const db = getDatabase(env);
152+
153+
// Get user ID from authenticated user
154+
const userId = router.jwtPayload.sub;
155+
156+
if (!userId) {
157+
return router.handleUnauthorizedRequest();
158+
}
159+
160+
// Find tester by user ID
161+
const testerUuid = await db.idMappings.getTesterUuid(userId);
162+
163+
if (!testerUuid) {
164+
return new Response(
165+
JSON.stringify({ success: false, error: "Unauthorized" }),
166+
{
167+
status: 403,
168+
headers: {
169+
...router.corsHeaders,
170+
"Content-Type": "application/json",
171+
},
172+
},
173+
);
174+
}
175+
176+
try {
177+
// Use the optimized function for getting total non-refunded amount
178+
const amount = await db.purchases.notRefundedAmount(testerUuid);
179+
180+
return new Response(
181+
JSON.stringify({
182+
success: true,
183+
amount,
184+
}),
185+
{
186+
status: 200,
187+
headers: {
188+
...router.corsHeaders,
189+
"Content-Type": "application/json",
190+
},
191+
},
192+
);
193+
} catch (error) {
194+
return new Response(
195+
JSON.stringify({
196+
success: false,
197+
error: `Error fetching non-refunded amount: ${(error as Error).message}`,
198+
}),
199+
{
200+
status: 500,
201+
headers: {
202+
...router.corsHeaders,
203+
"Content-Type": "application/json",
204+
},
205+
},
206+
);
207+
}
208+
},
209+
env.READ_PERMISSION,
210+
);
211+
};

0 commit comments

Comments
 (0)