feat(api): add M5 coverage controls and frontend spec

This commit is contained in:
zouantchaw
2026-03-18 08:18:50 +01:00
parent 008dd7efb1
commit 32f6cd55c8
14 changed files with 894 additions and 8 deletions

View File

@@ -44,6 +44,30 @@ async function ensureActorUser(client, actor) {
);
}
async function ensureStaffNotBlockedByBusiness(client, { tenantId, businessId, staffId }) {
const blocked = await client.query(
`
SELECT id, reason, issue_flags
FROM staff_blocks
WHERE tenant_id = $1
AND business_id = $2
AND staff_id = $3
LIMIT 1
`,
[tenantId, businessId, staffId]
);
if (blocked.rowCount > 0) {
throw new AppError('STAFF_BLOCKED', 'Staff is blocked from future shift assignments for this business', 409, {
businessId,
staffId,
blockId: blocked.rows[0].id,
reason: blocked.rows[0].reason || null,
issueFlags: Array.isArray(blocked.rows[0].issue_flags) ? blocked.rows[0].issue_flags : [],
});
}
}
async function insertDomainEvent(client, {
tenantId,
aggregateType,
@@ -986,6 +1010,11 @@ export async function assignStaffToShift(actor, payload) {
}
const workforce = await requireWorkforce(client, payload.tenantId, payload.workforceId);
await ensureStaffNotBlockedByBusiness(client, {
tenantId: shift.tenant_id,
businessId: shift.business_id,
staffId: workforce.staff_id,
});
let application = null;
if (payload.applicationId) {
application = await requireApplication(client, payload.tenantId, payload.applicationId);