()
| 139 | * Returns separate routers for page routes (/admin/*) and API routes (/api/admin/*) |
| 140 | */ |
| 141 | export function createBillingRouter(): { pageRouter: Router; apiRouter: Router } { |
| 142 | const pageRouter = Router(); |
| 143 | const apiRouter = Router(); |
| 144 | |
| 145 | // ========================================================================= |
| 146 | // ADMIN PAGE ROUTES (mounted at /admin) |
| 147 | // ========================================================================= |
| 148 | |
| 149 | pageRouter.get("/products", requireAuth, requireAdmin, (req, res) => { |
| 150 | serveHtmlWithConfig(req, res, "admin-products.html").catch((err) => { |
| 151 | logger.error({ err }, "Error serving admin products page"); |
| 152 | res.status(500).send("Internal server error"); |
| 153 | }); |
| 154 | }); |
| 155 | |
| 156 | pageRouter.get("/billing", requireAuth, requireAdmin, (req, res) => { |
| 157 | serveHtmlWithConfig(req, res, "admin-billing.html").catch((err) => { |
| 158 | logger.error({ err }, "Error serving admin billing page"); |
| 159 | res.status(500).send("Internal server error"); |
| 160 | }); |
| 161 | }); |
| 162 | |
| 163 | // ========================================================================= |
| 164 | // BILLING PRODUCTS API (mounted at /api/admin) |
| 165 | // ========================================================================= |
| 166 | |
| 167 | // GET /api/admin/products - List all billing products |
| 168 | apiRouter.get("/products", requireAuth, requireAdmin, async (_req, res) => { |
| 169 | try { |
| 170 | const products = await getBillingProducts(); |
| 171 | res.json({ products }); |
| 172 | } catch (error) { |
| 173 | logger.error({ err: error }, "Error fetching admin products"); |
| 174 | res.status(500).json({ |
| 175 | error: "Failed to fetch products", |
| 176 | }); |
| 177 | } |
| 178 | }); |
| 179 | |
| 180 | // POST /api/admin/products - Create a new product |
| 181 | apiRouter.post("/products", requireAuth, requireAdmin, async (req, res) => { |
| 182 | try { |
| 183 | const { |
| 184 | name, |
| 185 | description, |
| 186 | lookupKey, |
| 187 | amountCents, |
| 188 | currency, |
| 189 | billingType, |
| 190 | billingInterval, |
| 191 | category, |
| 192 | displayName, |
| 193 | customerTypes, |
| 194 | revenueTiers, |
| 195 | invoiceable, |
| 196 | sortOrder, |
| 197 | } = req.body as CreateProductInput; |
| 198 |
no test coverage detected