fix(api): close M5 frontend contract gaps
This commit is contained in:
@@ -1287,18 +1287,43 @@ async function createAttendanceEvent(actor, payload, eventType) {
|
||||
});
|
||||
}
|
||||
|
||||
async function loadExistingAttendanceSession() {
|
||||
const existing = await client.query(
|
||||
`
|
||||
SELECT id, status, check_in_at AS "clockInAt"
|
||||
FROM attendance_sessions
|
||||
WHERE assignment_id = $1
|
||||
ORDER BY updated_at DESC
|
||||
LIMIT 1
|
||||
`,
|
||||
[assignment.id]
|
||||
);
|
||||
return existing.rows[0] || null;
|
||||
}
|
||||
|
||||
const sessionResult = await client.query(
|
||||
`
|
||||
SELECT id, status
|
||||
SELECT id, status, check_in_at AS "clockInAt"
|
||||
FROM attendance_sessions
|
||||
WHERE assignment_id = $1
|
||||
`,
|
||||
[assignment.id]
|
||||
);
|
||||
|
||||
if (eventType === 'CLOCK_IN' && sessionResult.rowCount > 0 && sessionResult.rows[0].status === 'OPEN') {
|
||||
throw new AppError('ATTENDANCE_ALREADY_OPEN', 'Assignment already has an open attendance session', 409, {
|
||||
if (eventType === 'CLOCK_IN' && sessionResult.rowCount > 0) {
|
||||
const existingSession = sessionResult.rows[0];
|
||||
if (existingSession.status === 'OPEN') {
|
||||
throw new AppError('ALREADY_CLOCKED_IN', 'An active attendance session already exists for this assignment', 409, {
|
||||
assignmentId: assignment.id,
|
||||
sessionId: existingSession.id,
|
||||
clockInAt: existingSession.clockInAt || null,
|
||||
});
|
||||
}
|
||||
|
||||
throw new AppError('ATTENDANCE_SESSION_EXISTS', 'Attendance session already exists for this assignment', 409, {
|
||||
assignmentId: assignment.id,
|
||||
sessionId: existingSession.id,
|
||||
clockInAt: existingSession.clockInAt || null,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1414,21 +1439,43 @@ async function createAttendanceEvent(actor, payload, eventType) {
|
||||
|
||||
let sessionId;
|
||||
if (eventType === 'CLOCK_IN') {
|
||||
const insertedSession = await client.query(
|
||||
`
|
||||
INSERT INTO attendance_sessions (
|
||||
tenant_id,
|
||||
assignment_id,
|
||||
staff_id,
|
||||
clock_in_event_id,
|
||||
status,
|
||||
check_in_at
|
||||
)
|
||||
VALUES ($1, $2, $3, $4, 'OPEN', $5)
|
||||
RETURNING id
|
||||
`,
|
||||
[assignment.tenant_id, assignment.id, assignment.staff_id, eventResult.rows[0].id, capturedAt]
|
||||
);
|
||||
let insertedSession;
|
||||
try {
|
||||
insertedSession = await client.query(
|
||||
`
|
||||
INSERT INTO attendance_sessions (
|
||||
tenant_id,
|
||||
assignment_id,
|
||||
staff_id,
|
||||
clock_in_event_id,
|
||||
status,
|
||||
check_in_at
|
||||
)
|
||||
VALUES ($1, $2, $3, $4, 'OPEN', $5)
|
||||
RETURNING id
|
||||
`,
|
||||
[assignment.tenant_id, assignment.id, assignment.staff_id, eventResult.rows[0].id, capturedAt]
|
||||
);
|
||||
} catch (error) {
|
||||
if (error?.code !== '23505') {
|
||||
throw error;
|
||||
}
|
||||
|
||||
const existingSession = await loadExistingAttendanceSession();
|
||||
if (existingSession?.status === 'OPEN') {
|
||||
throw new AppError('ALREADY_CLOCKED_IN', 'An active attendance session already exists for this assignment', 409, {
|
||||
assignmentId: assignment.id,
|
||||
sessionId: existingSession.id,
|
||||
clockInAt: existingSession.clockInAt || null,
|
||||
});
|
||||
}
|
||||
|
||||
throw new AppError('ATTENDANCE_SESSION_EXISTS', 'Attendance session already exists for this assignment', 409, {
|
||||
assignmentId: assignment.id,
|
||||
sessionId: existingSession?.id || null,
|
||||
clockInAt: existingSession?.clockInAt || null,
|
||||
});
|
||||
}
|
||||
sessionId = insertedSession.rows[0].id;
|
||||
await client.query(
|
||||
`
|
||||
|
||||
Reference in New Issue
Block a user