Fixed a whole lotta broken stuff by changing state from a string to a number
This commit is contained in:
@@ -54,7 +54,7 @@ router.post('/', [requireLogin], async (req: Request, res: Response) => {
|
||||
try {
|
||||
let appID = await createApplication(memberID, appVersion, JSON.stringify(App));
|
||||
|
||||
await setUserState(memberID, MemberState.Applicant);
|
||||
await setUserState(memberID, MemberState.Applicant, "Application Submitted", memberID);
|
||||
|
||||
res.sendStatus(201);
|
||||
|
||||
@@ -230,7 +230,7 @@ router.post('/approve/:id', [requireLogin, requireRole("Recruiter")], async (req
|
||||
await approveApplication(appID, approved_by);
|
||||
|
||||
//update user profile
|
||||
await setUserState(app.member_id, MemberState.Member);
|
||||
await setUserState(app.member_id, MemberState.Member, "Application Accepted", approved_by);
|
||||
|
||||
await pool.query('CALL sp_accept_new_recruit_validation(?, ?, ?, ?)', [Number(process.env.CONFIG_ID), app.member_id, approved_by, approved_by])
|
||||
|
||||
@@ -262,7 +262,7 @@ router.post('/deny/:id', [requireLogin, requireRole("Recruiter")], async (req: R
|
||||
try {
|
||||
const app = await getApplicationByID(appID);
|
||||
await denyApplication(appID, approver);
|
||||
await setUserState(app.member_id, MemberState.Denied);
|
||||
await setUserState(app.member_id, MemberState.Denied, "Application Denied", approver);
|
||||
|
||||
logger.info('app', "Member application approved", {
|
||||
application: app.id,
|
||||
@@ -403,7 +403,7 @@ VALUES(?, ?, ?, 1);`
|
||||
router.post('/restart', async (req: Request, res: Response) => {
|
||||
const user = req.user.id;
|
||||
try {
|
||||
await setUserState(user, MemberState.Guest);
|
||||
await setUserState(user, MemberState.Guest, "Restarted Application", user);
|
||||
|
||||
logger.info('app', "Member restarted application", {
|
||||
user: user
|
||||
|
||||
@@ -240,11 +240,12 @@ router.put('/:id/displayname', async (req, res) => {
|
||||
router.post('/discharge', [requireLogin, requireMemberState(MemberState.Member), requireRole("17th Administrator")], async (req: Request, res: Response) => {
|
||||
try {
|
||||
var con = await pool.getConnection();
|
||||
let author = req.user.id;
|
||||
|
||||
con.beginTransaction();
|
||||
|
||||
var data: Discharge = req.body;
|
||||
setUserState(data.userID, MemberState.Retired, con);
|
||||
setUserState(data.userID, MemberState.Discharged, "Member Discharged", author, con);
|
||||
cancelLatestRank(data.userID, con);
|
||||
cancelLatestUnit(data.userID, con);
|
||||
con.commit();
|
||||
|
||||
@@ -6,43 +6,43 @@ import { memberCache } from "../../routes/auth";
|
||||
import * as mariadb from 'mariadb';
|
||||
|
||||
export async function getFilteredMembers(
|
||||
page: number = 1,
|
||||
pageSize: number = 15,
|
||||
search?: string,
|
||||
status?: string,
|
||||
unitId?: string
|
||||
page: number = 1,
|
||||
pageSize: number = 15,
|
||||
search?: string,
|
||||
status?: string,
|
||||
unitId?: string
|
||||
): Promise<PaginatedMembers> {
|
||||
try {
|
||||
const offset = (page - 1) * pageSize;
|
||||
const whereClauses: string[] = [];
|
||||
const params: any[] = [];
|
||||
try {
|
||||
const offset = (page - 1) * pageSize;
|
||||
const whereClauses: string[] = [];
|
||||
const params: any[] = [];
|
||||
|
||||
if (status && status !== 'all') {
|
||||
whereClauses.push(`m.state = ?`);
|
||||
params.push(status);
|
||||
}
|
||||
if (status && status !== 'all') {
|
||||
whereClauses.push(`m.state = ?`);
|
||||
params.push(status);
|
||||
}
|
||||
|
||||
if (search) {
|
||||
whereClauses.push(`v.member_name LIKE ?`);
|
||||
params.push(`%${search}%`);
|
||||
}
|
||||
if (search) {
|
||||
whereClauses.push(`v.member_name LIKE ?`);
|
||||
params.push(`%${search}%`);
|
||||
}
|
||||
|
||||
if (unitId && unitId !== 'all') {
|
||||
whereClauses.push(`v.unit = ?`);
|
||||
params.push(unitId);
|
||||
}
|
||||
if (unitId && unitId !== 'all') {
|
||||
whereClauses.push(`v.unit = ?`);
|
||||
params.push(unitId);
|
||||
}
|
||||
|
||||
const whereClause = whereClauses.length > 0
|
||||
? ` WHERE ${whereClauses.join(' AND ')}`
|
||||
: '';
|
||||
const whereClause = whereClauses.length > 0
|
||||
? ` WHERE ${whereClauses.join(' AND ')}`
|
||||
: '';
|
||||
|
||||
// COUNT QUERY
|
||||
const countQuery = `SELECT COUNT(*) as total FROM view_member_rank_unit_status_latest v INNER JOIN members m ON v.member_id = m.id ${whereClause}`;
|
||||
const [countResults]: any[] = await pool.query(countQuery, params);
|
||||
const total = Number(countResults?.total) || 0;
|
||||
// COUNT QUERY
|
||||
const countQuery = `SELECT COUNT(*) as total FROM view_member_rank_unit_status_latest v INNER JOIN members m ON v.member_id = m.id ${whereClause}`;
|
||||
const [countResults]: any[] = await pool.query(countQuery, params);
|
||||
const total = Number(countResults?.total) || 0;
|
||||
|
||||
// DATA QUERY
|
||||
const dataQuery = `
|
||||
// DATA QUERY
|
||||
const dataQuery = `
|
||||
SELECT
|
||||
v.*,
|
||||
CASE
|
||||
@@ -60,106 +60,123 @@ export async function getFilteredMembers(
|
||||
LIMIT ? OFFSET ?
|
||||
`;
|
||||
|
||||
const rows: any[] = await pool.query(dataQuery, [...params, pageSize, offset]);
|
||||
const rows: any[] = await pool.query(dataQuery, [...params, pageSize, offset]);
|
||||
|
||||
// Map rows to Member type
|
||||
const members: Member[] = rows.map(row => ({
|
||||
member_id: Number(row.member_id),
|
||||
member_name: row.member_name,
|
||||
displayName: row.displayName,
|
||||
rank: row.rank,
|
||||
rank_date: row.rank_date,
|
||||
unit: row.unit,
|
||||
unit_date: row.unit_date,
|
||||
status: row.status,
|
||||
status_date: row.status_date,
|
||||
loa_until: row.loa_until ? new Date(row.loa_until) : undefined,
|
||||
}));
|
||||
// Map rows to Member type
|
||||
const members: Member[] = rows.map(row => ({
|
||||
member_id: Number(row.member_id),
|
||||
member_name: row.member_name,
|
||||
displayName: row.displayName,
|
||||
rank: row.rank,
|
||||
rank_date: row.rank_date,
|
||||
unit: row.unit,
|
||||
unit_date: row.unit_date,
|
||||
status: row.status,
|
||||
status_date: row.status_date,
|
||||
loa_until: row.loa_until ? new Date(row.loa_until) : undefined,
|
||||
}));
|
||||
|
||||
return {
|
||||
data: members,
|
||||
pagination: {
|
||||
page,
|
||||
pageSize,
|
||||
total,
|
||||
totalPages: Math.ceil(total / pageSize),
|
||||
},
|
||||
};
|
||||
} catch (error) {
|
||||
logger.error('app', 'Error fetching filtered members', {
|
||||
error: error instanceof Error ? error.message : String(error),
|
||||
});
|
||||
throw error;
|
||||
}
|
||||
return {
|
||||
data: members,
|
||||
pagination: {
|
||||
page,
|
||||
pageSize,
|
||||
total,
|
||||
totalPages: Math.ceil(total / pageSize),
|
||||
},
|
||||
};
|
||||
} catch (error) {
|
||||
logger.error('app', 'Error fetching filtered members', {
|
||||
error: error instanceof Error ? error.message : String(error),
|
||||
});
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
export async function getUserData(userID: number): Promise<Member> {
|
||||
const sql = `SELECT * FROM view_member_rank_unit_status_latest WHERE member_id = ?`;
|
||||
const res: Member = await pool.query(sql, [userID]);
|
||||
return res[0] ?? null;
|
||||
const sql = `SELECT * FROM view_member_rank_unit_status_latest WHERE member_id = ?`;
|
||||
const res: Member = await pool.query(sql, [userID]);
|
||||
return res[0] ?? null;
|
||||
}
|
||||
|
||||
export async function setUserState(userID: number, state: MemberState, con: mariadb.Pool | mariadb.Connection = pool) {
|
||||
try {
|
||||
const sql = `UPDATE members
|
||||
SET state = ?
|
||||
WHERE id = ?;`;
|
||||
return await con.query(sql, [state, userID]);
|
||||
} catch (error) {
|
||||
logger.error('app', 'Error setting user state', error);
|
||||
} finally {
|
||||
memberCache.Invalidate(userID);
|
||||
}
|
||||
export async function setUserState(userID: number, state: MemberState, reason: string, creatorID: number, externalCon?: mariadb.Connection | mariadb.PoolConnection) {
|
||||
const isInternalConn = !externalCon;
|
||||
const con = (externalCon || await pool.getConnection()) as mariadb.PoolConnection;
|
||||
|
||||
try {
|
||||
if (isInternalConn) await con.beginTransaction();
|
||||
|
||||
await endLatestMemberState(userID, con);
|
||||
|
||||
const sql = `UPDATE members SET state = ? WHERE id = ?;`;
|
||||
await con.query(sql, [state, userID]);
|
||||
|
||||
const insertHistorySql = `INSERT INTO member_state_history
|
||||
(member_id, state_id, reason, created_by_id, start_date, end_date)
|
||||
VALUES (?, ?, ?, ?, NOW(), NULL);`;
|
||||
await con.query(insertHistorySql, [userID, state, reason, creatorID]);
|
||||
|
||||
if (isInternalConn) await con.commit();
|
||||
} catch (error) {
|
||||
if (isInternalConn) {
|
||||
await con.rollback();
|
||||
}
|
||||
logger.error('app', 'Error setting user state', error);
|
||||
throw error;
|
||||
} finally {
|
||||
memberCache.Invalidate(userID);
|
||||
if (isInternalConn && con) con.release();
|
||||
}
|
||||
}
|
||||
|
||||
export async function getUserState(user: number): Promise<MemberState> {
|
||||
let out = await pool.query(`SELECT state FROM members WHERE id = ?`, [user]);
|
||||
return (out[0].state as MemberState);
|
||||
let out = await pool.query(`SELECT state FROM members WHERE id = ?`, [user]);
|
||||
return (out[0].state as MemberState);
|
||||
}
|
||||
|
||||
export async function getMemberSettings(id: number): Promise<memberSettings> {
|
||||
const sql = `SELECT * FROM view_member_settings WHERE id = ?`;
|
||||
let out: memberSettings[] = await pool.query(sql, [id]);
|
||||
const sql = `SELECT * FROM view_member_settings WHERE id = ?`;
|
||||
let out: memberSettings[] = await pool.query(sql, [id]);
|
||||
|
||||
if (out.length != 1)
|
||||
throw new Error("Could not get user settings");
|
||||
if (out.length != 1)
|
||||
throw new Error("Could not get user settings");
|
||||
|
||||
return out[0];
|
||||
return out[0];
|
||||
}
|
||||
|
||||
export async function setUserSettings(id: number, settings: memberSettings) {
|
||||
const sql = `UPDATE view_member_settings SET
|
||||
const sql = `UPDATE view_member_settings SET
|
||||
displayName = ?
|
||||
WHERE id = ?;`;
|
||||
let result = await pool.query(sql, [settings.displayName, id])
|
||||
let result = await pool.query(sql, [settings.displayName, id])
|
||||
}
|
||||
|
||||
export async function getMembersLite(ids: number[]): Promise<MemberLight[]> {
|
||||
const sql = `SELECT m.member_id AS id,
|
||||
const sql = `SELECT m.member_id AS id,
|
||||
m.member_name AS username,
|
||||
m.displayName,
|
||||
u.color
|
||||
FROM view_member_rank_unit_status_latest m
|
||||
LEFT JOIN units u ON u.name = m.unit
|
||||
WHERE member_id IN (?);`;
|
||||
const res: MemberLight[] = await pool.query(sql, [ids]);
|
||||
return res;
|
||||
const res: MemberLight[] = await pool.query(sql, [ids]);
|
||||
return res;
|
||||
}
|
||||
|
||||
export async function getAllMembersLite(): Promise<MemberLight[]> {
|
||||
const sql = `SELECT m.member_id AS id,
|
||||
const sql = `SELECT m.member_id AS id,
|
||||
m.member_name AS username,
|
||||
m.displayName,
|
||||
u.color
|
||||
FROM view_member_rank_unit_status_latest m
|
||||
LEFT JOIN units u ON u.name = m.unit;`;
|
||||
|
||||
const res: MemberLight[] = await pool.query(sql);
|
||||
return res;
|
||||
const res: MemberLight[] = await pool.query(sql);
|
||||
return res;
|
||||
}
|
||||
|
||||
export async function getMembersFull(ids: number[]): Promise<MemberCardDetails[]> {
|
||||
const sql = `
|
||||
const sql = `
|
||||
SELECT m.*,
|
||||
COALESCE(
|
||||
JSON_ARRAYAGG(
|
||||
@@ -181,30 +198,60 @@ export async function getMembersFull(ids: number[]): Promise<MemberCardDetails[]
|
||||
GROUP BY m.member_id;
|
||||
`;
|
||||
|
||||
const rows: any[] = await pool.query(sql, [ids]);
|
||||
const rows: any[] = await pool.query(sql, [ids]);
|
||||
|
||||
return rows.map(row => {
|
||||
const member: Member = {
|
||||
member_id: row.member_id,
|
||||
member_name: row.member_name,
|
||||
displayName: row.displayName,
|
||||
rank: row.rank,
|
||||
rank_date: row.rank_date,
|
||||
unit: row.unit,
|
||||
unit_date: row.unit_date,
|
||||
status: row.status,
|
||||
status_date: row.status_date,
|
||||
loa_until: row.loa_until ? new Date(row.loa_until) : undefined,
|
||||
};
|
||||
// roles comes as array of strings; parse each one
|
||||
const roles: Role[] = row.roles;
|
||||
return rows.map(row => {
|
||||
const member: Member = {
|
||||
member_id: row.member_id,
|
||||
member_name: row.member_name,
|
||||
displayName: row.displayName,
|
||||
rank: row.rank,
|
||||
rank_date: row.rank_date,
|
||||
unit: row.unit,
|
||||
unit_date: row.unit_date,
|
||||
status: row.status,
|
||||
status_date: row.status_date,
|
||||
loa_until: row.loa_until ? new Date(row.loa_until) : undefined,
|
||||
};
|
||||
// roles comes as array of strings; parse each one
|
||||
const roles: Role[] = row.roles;
|
||||
|
||||
return { member, roles };
|
||||
});
|
||||
return { member, roles };
|
||||
});
|
||||
}
|
||||
|
||||
export async function mapDiscordtoID(id: number): Promise<number | null> {
|
||||
const sql = `SELECT id FROM members WHERE discord_id = ?;`
|
||||
let res = await pool.query(sql, [id]);
|
||||
return res.length > 0 ? res[0].id : null;
|
||||
const sql = `SELECT id FROM members WHERE discord_id = ?;`
|
||||
let res = await pool.query(sql, [id]);
|
||||
return res.length > 0 ? res[0].id : null;
|
||||
}
|
||||
|
||||
export async function endLatestMemberState(memberID: number, con: mariadb.Pool | mariadb.Connection = pool) {
|
||||
const sql = `UPDATE member_state_history
|
||||
SET end_date = NOW(),
|
||||
updated_at = NOW()
|
||||
WHERE id = (
|
||||
SELECT id
|
||||
FROM (
|
||||
SELECT id
|
||||
FROM member_state_history
|
||||
WHERE member_id = ?
|
||||
AND end_date IS NULL
|
||||
ORDER BY start_date DESC,
|
||||
created_at DESC
|
||||
LIMIT 1
|
||||
) AS x
|
||||
);`;
|
||||
|
||||
try {
|
||||
let res = await con.query(sql, [memberID]);
|
||||
console.log(res);
|
||||
} catch (error) {
|
||||
logger.error('app', 'Error ending latest member state', {
|
||||
error: error instanceof Error ? error.message : String(error),
|
||||
});
|
||||
throw error;
|
||||
}
|
||||
let res = await pool.query(sql, [memberID]);
|
||||
console.log(res);
|
||||
}
|
||||
Reference in New Issue
Block a user