const express = require('express'); const router = express.Router(); import { Request, Response } from 'express'; import pool from '../db'; import { closeLOA, createNewLOA, getAllLOA, getLOAbyID, getLoaTypes, getUserLOA, setLOAExtension } from '../services/db/loaService'; import { LOARequest } from '@app/shared/types/loa'; import { requireLogin, requireRole } from '../middleware/auth'; import { logger } from '../services/logging/logger'; router.use(requireLogin); //member posts LOA router.post("/", async (req: Request, res: Response) => { let LOARequest = req.body as LOARequest; LOARequest.member_id = req.user.id; LOARequest.created_by = req.user.id; LOARequest.filed_date = new Date(); try { await createNewLOA(LOARequest); logger.info('app', 'LOA Posted', { poster: req.user.id, user: LOARequest.member_id }) res.sendStatus(201); } catch (error) { logger.error( 'app', 'Failed to post LOA', { error: error instanceof Error ? error.message : String(error), stack: error instanceof Error ? error.stack : undefined, } ); res.status(500).send(error); } }); //admin posts LOA router.post("/admin", [requireRole(['17th Administrator', '17th HQ', '17th Command'])], async (req: Request, res: Response) => { let LOARequest = req.body as LOARequest; LOARequest.created_by = req.user.id; LOARequest.filed_date = new Date(); try { await createNewLOA(LOARequest); logger.info('app', 'LOA Posted', { poster: req.user.id, user: LOARequest.member_id }) res.sendStatus(201); } catch (error) { logger.error( 'app', 'Failed to post LOA', { error: error instanceof Error ? error.message : String(error), stack: error instanceof Error ? error.stack : undefined, } ); res.status(500).send(error); } }); //get my current LOA router.get("/me", async (req: Request, res: Response) => { const user = req.user.id; try { const result = await getUserLOA(user); res.status(200).json(result) } catch (error) { logger.error( 'app', 'Failed to get user current LOA', { error: error instanceof Error ? error.message : String(error), stack: error instanceof Error ? error.stack : undefined, } ); res.status(500).send(error); } }) //get my LOA history router.get("/history", async (req: Request, res: Response) => { try { const user = req.user.id; const page = Number(req.query.page) || undefined; const pageSize = Number(req.query.pageSize) || undefined; const result = await getUserLOA(user, page, pageSize); res.status(200).json(result) } catch (error) { logger.error( 'app', 'Failed to get user LOA history', { error: error instanceof Error ? error.message : String(error), stack: error instanceof Error ? error.stack : undefined, } ); res.status(500).send(error); } }) router.get('/all', [requireRole(['17th Administrator', '17th HQ', '17th Command'])], async (req: Request, res: Response) => { try { const page = Number(req.query.page) || undefined; const pageSize = Number(req.query.pageSize) || undefined; const result = await getAllLOA(page, pageSize); res.status(200).json(result) } catch (error) { logger.error( 'app', 'Failed to get full LOA history', { error: error instanceof Error ? error.message : String(error), stack: error instanceof Error ? error.stack : undefined, } ); res.status(500).send(error); } }) router.get('/types', async (req: Request, res: Response) => { try { let out = await getLoaTypes(); res.status(200).json(out); } catch (error) { logger.error( 'app', 'Failed to get LOA types', { error: error instanceof Error ? error.message : String(error), stack: error instanceof Error ? error.stack : undefined, } ); res.status(500).json(error); } }) router.post('/cancel/:id', async (req: Request, res: Response) => { let closer = req.user.id; let id = Number(req.params.id); try { let loa = await getLOAbyID(id); if (loa.member_id != closer) { return res.sendStatus(403); } await closeLOA(Number(req.params.id), closer); logger.info('app', 'LOA Closed', { closed_by: closer, LOA: id }) res.sendStatus(200); } catch (error) { logger.error( 'app', 'Failed to cancel LOA', { error: error instanceof Error ? error.message : String(error), stack: error instanceof Error ? error.stack : undefined, } ); res.status(500).json(error); } }) //TODO: enforce admin only router.post('/adminCancel/:id', [requireRole(['17th Administrator', '17th HQ', '17th Command'])], async (req: Request, res: Response) => { let closer = req.user.id; try { await closeLOA(Number(req.params.id), closer); logger.info('app', 'LOA Closed', { closed_by: closer, LOA: req.params.id }) res.sendStatus(200); } catch (error) { logger.error( 'app', 'Failed to cancel LOA', { error: error instanceof Error ? error.message : String(error), stack: error instanceof Error ? error.stack : undefined, } ); res.status(500).json(error); } }) // extend LOA router.post('/extend/:id', [requireRole(['17th Administrator', '17th HQ', '17th Command'])], async (req: Request, res: Response) => { const to: Date = req.body.to; if (!to) { res.status(400).send("Extension length is required"); } try { await setLOAExtension(Number(req.params.id), to); logger.info('app', 'LOA Extended', { extended_by: req.user.id, LOA: req.params.id }) res.sendStatus(200); } catch (error) { logger.error( 'app', 'Failed to extend LOA', { error: error instanceof Error ? error.message : String(error), stack: error instanceof Error ? error.stack : undefined, } ); res.status(500).json(error); } }) // GET /policy router.get('/policy', async (req: Request, res: Response) => { const t0 = performance.now(); try { const response = await fetch(`${process.env.DOC_HOST}/api/pages/42`, { headers: { Authorization: `Token ${process.env.DOC_TOKEN_ID}:${process.env.DOC_TOKEN_SECRET}`, }, }); if (!response.ok) { const text = await response.text(); logger.error('app', 'Failed to fetch policy page from Bookstack', { pageId: 42, status: response.status, statusText: response.statusText, body: text, userId: req.user?.id, }); return res.sendStatus(500); } const out = await response.json(); res.status(200).json(out.html); logger.info( 'profiling', 'GET /policy completed', { pageId: 42, total_ms: performance.now() - t0, }, 'profiling' ); } catch (error) { logger.error('app', 'Error fetching policy page from Bookstack', { pageId: 42, error: error instanceof Error ? error.message : String(error), stack: error instanceof Error ? error.stack : undefined, userId: req.user?.id, }); res.sendStatus(500); } }); export const loaRouter = router;