feat(api): complete M5 swap and dispatch backend slice
This commit is contained in:
@@ -5,8 +5,10 @@ import { V2DemoFixture as fixture } from '../../command-api/scripts/v2-demo-fixt
|
||||
const unifiedBaseUrl = process.env.UNIFIED_API_BASE_URL || 'https://krow-api-v2-e3g6witsvq-uc.a.run.app';
|
||||
const ownerEmail = process.env.V2_DEMO_OWNER_EMAIL || 'legendary.owner+v2@krowd.com';
|
||||
const staffEmail = process.env.V2_DEMO_STAFF_EMAIL || 'ana.barista+v2@krowd.com';
|
||||
const staffBenEmail = process.env.V2_DEMO_STAFF_BEN_EMAIL || 'ben.barista+v2@krowd.com';
|
||||
const ownerPassword = process.env.V2_DEMO_OWNER_PASSWORD || 'Demo2026!';
|
||||
const staffPassword = process.env.V2_DEMO_STAFF_PASSWORD || 'Demo2026!';
|
||||
const staffBenPassword = process.env.V2_DEMO_STAFF_BEN_PASSWORD || 'Demo2026!';
|
||||
|
||||
function uniqueKey(prefix) {
|
||||
return `${prefix}-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
|
||||
@@ -175,13 +177,22 @@ async function signInStaff() {
|
||||
});
|
||||
}
|
||||
|
||||
async function signInStaffBen() {
|
||||
return signInWithPassword({
|
||||
email: staffBenEmail,
|
||||
password: staffBenPassword,
|
||||
});
|
||||
}
|
||||
|
||||
async function main() {
|
||||
const reportWindow = `startDate=${encodeURIComponent(isoTimestamp(-24 * 14))}&endDate=${encodeURIComponent(isoTimestamp(24 * 14))}`;
|
||||
const ownerSession = await signInClient();
|
||||
const staffAuth = await signInStaff();
|
||||
const staffBenAuth = await signInStaffBen();
|
||||
|
||||
assert.ok(ownerSession.sessionToken);
|
||||
assert.ok(staffAuth.idToken);
|
||||
assert.ok(staffBenAuth.idToken);
|
||||
assert.equal(ownerSession.business.businessId, fixture.business.id);
|
||||
logStep('auth.client.sign-in.ok', {
|
||||
tenantId: ownerSession.tenant.tenantId,
|
||||
@@ -191,6 +202,10 @@ async function main() {
|
||||
uid: staffAuth.localId,
|
||||
email: staffEmail,
|
||||
});
|
||||
logStep('auth.staff-b.password-sign-in.ok', {
|
||||
uid: staffBenAuth.localId,
|
||||
email: staffBenEmail,
|
||||
});
|
||||
|
||||
const authSession = await apiCall('/auth/session', {
|
||||
token: ownerSession.sessionToken,
|
||||
@@ -342,6 +357,13 @@ async function main() {
|
||||
assert.ok(Array.isArray(coreTeam.items));
|
||||
logStep('client.coverage.core-team.ok', { count: coreTeam.items.length });
|
||||
|
||||
const dispatchTeams = await apiCall('/client/coverage/dispatch-teams', {
|
||||
token: ownerSession.sessionToken,
|
||||
});
|
||||
assert.ok(Array.isArray(dispatchTeams.items));
|
||||
assert.ok(dispatchTeams.items.length >= 2);
|
||||
logStep('client.coverage.dispatch-teams.ok', { count: dispatchTeams.items.length });
|
||||
|
||||
const coverageIncidentsBefore = await apiCall(`/client/coverage/incidents?${reportWindow}`, {
|
||||
token: ownerSession.sessionToken,
|
||||
});
|
||||
@@ -1197,7 +1219,7 @@ async function main() {
|
||||
assert.equal(submittedCompletedShift.submitted, true);
|
||||
logStep('staff.shifts.submit-for-approval.ok', submittedCompletedShift);
|
||||
|
||||
const requestedSwap = await apiCall(`/staff/shifts/${fixture.shifts.assigned.id}/request-swap`, {
|
||||
const requestedSwap = await apiCall(`/staff/shifts/${fixture.shifts.swapEligible.id}/request-swap`, {
|
||||
method: 'POST',
|
||||
token: staffAuth.idToken,
|
||||
idempotencyKey: uniqueKey('staff-shift-swap'),
|
||||
@@ -1207,6 +1229,54 @@ async function main() {
|
||||
});
|
||||
logStep('staff.shifts.request-swap.ok', requestedSwap);
|
||||
|
||||
const benOpenShifts = await apiCall('/staff/shifts/open?limit=10', {
|
||||
token: staffBenAuth.idToken,
|
||||
});
|
||||
const benSwapShift = benOpenShifts.items.find((item) => item.shiftId === fixture.shifts.swapEligible.id);
|
||||
assert.ok(benSwapShift);
|
||||
assert.equal(benSwapShift.swapRequestId, requestedSwap.swapRequestId);
|
||||
assert.equal(benSwapShift.dispatchTeam, 'CERTIFIED_LOCATION');
|
||||
logStep('staff-b.shifts.open-swap.ok', benSwapShift);
|
||||
|
||||
const dispatchCandidates = await apiCall(`/client/coverage/dispatch-candidates?shiftId=${fixture.shifts.swapEligible.id}&roleId=${fixture.shiftRoles.swapEligibleBarista.id}`, {
|
||||
token: ownerSession.sessionToken,
|
||||
});
|
||||
assert.ok(Array.isArray(dispatchCandidates.items));
|
||||
assert.ok(dispatchCandidates.items.length >= 1);
|
||||
assert.equal(dispatchCandidates.items[0].staffId, fixture.staff.ben.id);
|
||||
logStep('client.coverage.dispatch-candidates.ok', { count: dispatchCandidates.items.length });
|
||||
|
||||
const benSwapApplication = await apiCall(`/staff/shifts/${fixture.shifts.swapEligible.id}/apply`, {
|
||||
method: 'POST',
|
||||
token: staffBenAuth.idToken,
|
||||
idempotencyKey: uniqueKey('staff-b-shift-swap-apply'),
|
||||
body: {
|
||||
roleId: fixture.shiftRoles.swapEligibleBarista.id,
|
||||
},
|
||||
});
|
||||
assert.ok(benSwapApplication.applicationId);
|
||||
logStep('staff-b.shifts.apply-swap.ok', benSwapApplication);
|
||||
|
||||
const swapRequests = await apiCall('/client/coverage/swap-requests?status=OPEN', {
|
||||
token: ownerSession.sessionToken,
|
||||
});
|
||||
const openSwapRequest = swapRequests.items.find((item) => item.swapRequestId === requestedSwap.swapRequestId);
|
||||
assert.ok(openSwapRequest);
|
||||
assert.ok(openSwapRequest.candidates.some((candidate) => candidate.staffId === fixture.staff.ben.id));
|
||||
logStep('client.coverage.swap-requests.ok', { count: swapRequests.items.length });
|
||||
|
||||
const resolvedSwap = await apiCall(`/client/coverage/swap-requests/${requestedSwap.swapRequestId}/resolve`, {
|
||||
method: 'POST',
|
||||
token: ownerSession.sessionToken,
|
||||
idempotencyKey: uniqueKey('client-swap-resolve'),
|
||||
body: {
|
||||
applicationId: benSwapApplication.applicationId,
|
||||
note: 'Smoke resolved swap request',
|
||||
},
|
||||
});
|
||||
assert.equal(resolvedSwap.status, 'RESOLVED');
|
||||
logStep('client.coverage.swap-resolve.ok', resolvedSwap);
|
||||
|
||||
const blockedReview = await apiCall('/client/coverage/reviews', {
|
||||
method: 'POST',
|
||||
token: ownerSession.sessionToken,
|
||||
|
||||
Reference in New Issue
Block a user