Implemented admin assign unit UI
All checks were successful
Pull Request CI / Merge Check (pull_request) Successful in 3m55s
All checks were successful
Pull Request CI / Merge Check (pull_request) Successful in 3m55s
This commit is contained in:
@@ -103,7 +103,7 @@ import { roles, memberRoles } from './routes/roles';
|
||||
import { courseRouter, eventRouter } from './routes/course';
|
||||
import { calendarRouter } from './routes/calendar';
|
||||
import { docsRouter } from './routes/docs';
|
||||
import { units } from './routes/units';
|
||||
import { memberUnits, units } from './routes/units';
|
||||
|
||||
app.use('/application', applicationRouter);
|
||||
app.use('/ranks', ranks);
|
||||
@@ -118,6 +118,7 @@ app.use('/course', courseRouter)
|
||||
app.use('/courseEvent', eventRouter)
|
||||
app.use('/calendar', calendarRouter)
|
||||
app.use('/units', units)
|
||||
app.use('/memberUnits', memberUnits);
|
||||
app.use('/docs', docsRouter)
|
||||
app.use('/', authRouter)
|
||||
|
||||
|
||||
@@ -1,10 +1,16 @@
|
||||
import express = require('express');
|
||||
const unitsRouter = express.Router();
|
||||
const memberUnitsRouter = express.Router();
|
||||
|
||||
import { Request, Response } from 'express';
|
||||
|
||||
import pool from '../db';
|
||||
import { requireLogin } from '../middleware/auth';
|
||||
import { requireLogin, requireMemberState, requireRole } from '../middleware/auth';
|
||||
import { logger } from '../services/logging/logger';
|
||||
import { Unit } from '@app/shared/types/units';
|
||||
import { MemberState } from '@app/shared/types/member';
|
||||
import { assignNewUnit } from '../services/db/unitService';
|
||||
import { audit } from '../services/logging/auditLog';
|
||||
|
||||
unitsRouter.use(requireLogin);
|
||||
|
||||
@@ -26,4 +32,38 @@ unitsRouter.get('/', async (req, res) => {
|
||||
}
|
||||
});
|
||||
|
||||
memberUnitsRouter.post('/admin', [requireMemberState(MemberState.Member), requireRole("17th Administrator")], async (req: Request, res: Response) => {
|
||||
const memberId = Number(req.query.memberId);
|
||||
const unitId = Number(req.query.unitId);
|
||||
const reason = req.query.reason as string;
|
||||
|
||||
try {
|
||||
|
||||
if (!memberId || !unitId) {
|
||||
return res.status(400).json({ error: 'memberId and unitId query parameters are required' });
|
||||
}
|
||||
|
||||
await assignNewUnit(memberId, unitId, req.user.id, req.user.id, reason);
|
||||
logger.info('app', 'Member force assigned unit', {
|
||||
member: memberId,
|
||||
unit: unitId,
|
||||
caller: req.user.id,
|
||||
});
|
||||
audit.member('update_unit', { actorId: req.user.id, targetId: memberId }, { unit: unitId, reason: reason });
|
||||
|
||||
res.sendStatus(200);
|
||||
} catch (error) {
|
||||
logger.error('app', 'Failed to force assign unit', {
|
||||
member: memberId,
|
||||
unit: unitId,
|
||||
caller: req.user.id,
|
||||
error: error instanceof Error ? error.message : String(error),
|
||||
stack: error instanceof Error ? error.stack : undefined,
|
||||
})
|
||||
|
||||
res.sendStatus(500);
|
||||
}
|
||||
});
|
||||
|
||||
export const units = unitsRouter;
|
||||
export const memberUnits = memberUnitsRouter;
|
||||
@@ -10,4 +10,13 @@ export async function cancelLatestUnit(userID: number, con: mariadb.Pool | maria
|
||||
} catch (error) {
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
export async function assignNewUnit(memberID: number, unitID: number, authorizedID: number, creatorID: number, reason: string) {
|
||||
let sql = `CALL sp_update_member_unit(?, ?, ?, ?, ?, NOW())`;
|
||||
|
||||
const result = await pool.query(sql, [memberID, unitID, authorizedID, creatorID, reason]);
|
||||
if (!result || result.affectedRows === 0) {
|
||||
throw new Error('Record was not updated');
|
||||
}
|
||||
}
|
||||
@@ -32,8 +32,8 @@ class AuditLogger {
|
||||
logger.error('audit', `AUDIT_FAILURE: Failed to log ${actionType}`, { error: err });
|
||||
}
|
||||
}
|
||||
|
||||
member(action: 'update_rank' | 'suspension_added' | 'suspension_removed' | 'discharged', context: AuditContext, data: any = {}) {
|
||||
|
||||
member(action: 'update_rank'| 'update_unit' | 'suspension_added' | 'suspension_removed' | 'discharged', context: AuditContext, data: any = {}) {
|
||||
return this.record('member', action, context, data);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user