- Rebrand all user-facing text to AgendaMax - Fix sidebar scrolling: card container no longer overflows html (flex h-full min-h-0) - Fix calendar toolbar hover: active buttons keep readable contrast - Sticky calendar toolbar (month/week/day always visible on scroll) - Seed guarantees 2-4 appointments per day for current week (Mon-Sat)
4.9 KiB
4.9 KiB
Task 7 — backend settings + employees (campos nuevos) + script de integración
Status
COMPLETE — all verification green, no commits made.
Files changed
server/routes/settings.ts— extendedFIELDSwithauto_assign_specialist,working_hours; added both columns to GET and final-PATCH SELECTs; serializedworking_hoursto JSON when received as object; coercedauto_assign_specialistto0/1.server/routes/employees.ts—POST /andPATCH /:idnow accept and persistspecialties,working_hours,efficiency_score(JSON-serialized arrays/maps,Number(...)coercion for efficiency).server/scripts/booking-e2e.mjs— NEW. Slot-aware integration test covering auto-assign, double-booking 409, andauto_assign_specialistexposure on the public business endpoint.package.json— added"test:booking": "node server/scripts/booking-e2e.mjs".e2e-test.mjs— fixture adaptation only: addedfindSlot(slug, serviceId, maxDays=30)helper that queries/public/<slug>/slotsfor the next 30 days and returns the first available slot iso; replaced the two hard-codedstart_atISO strings (2026-09-15T11:00:00Z,2026-09-20T10:00:00Z) with slot-aware values. Added aGET /settingscall after login to obtain the businessslug. Employee-service fallback: tries service_id 5 first, falls back to 6 (both offered only by Mateo Herrera, so the self-assign assertion still holds).
Verification results
| Check | Result |
|---|---|
npm run typecheck |
0 errors |
npm run test:unit |
15/15 passed |
npm run test:e2e |
25/25 passed (was failing before the fixture fix) |
npm run test:booking |
9/9 passed |
Manual API check (temp .mjs, run + deleted)
PATCH /settings { auto_assign_specialist: 1, working_hours: {1:{start:"09:00",end:"13:00"}, ...} }→ PATCH response reflectedauto_assign_specialist = 1andworking_hoursas a JSON string.GET /settingsreturned the same.working_hoursparsed back to{1:{start:"09:00",end:"13:00"}, 3:null, ...}.PATCH /employees/:id { specialties: ["Cabello","Coloración"], efficiency_score: 87, working_hours: {...} }→ reflectedspecialties = ["Cabello","Coloración"],efficiency_score = 87withtypeof === "number", andworking_hoursJSON.GET /employees/:idconfirmed persistence. Restored afterwards.
Self-review
- settings serializes
working_hours? YES —merged.working_hours = JSON.stringify(merged.working_hours)when not already a string; stored as TEXT, returned verbatim by both SELECTs. - settings coerces
auto_assign_specialistto 0/1? YES —merged.auto_assign_specialist = merged.auto_assign_specialist ? 1 : 0. - employees coerces
efficiency_scoretoNumber? YES — both POST (typeof === "number" ? efficiency_score : 50) and PATCH (Number(efficiency_score)with fallback toexisting.efficiency_score ?? 50). Confirmed via manual check: returned value hastypeof === "number". - employees handles
specialties/working_hoursJSON? YES — POST stringifies the array/object; PATCH merges with existing and accepts string, object/array, ornull(forworking_hours). - booking-e2e covers auto-assign + 409 +
auto_assign_specialistexposure? YES — step 4 books withoutemployee_idand asserts the response containsemployee_id+ non-emptyreasons(auto-assign); step 5 re-books the same slot/employee and asserts409; step 6 togglesauto_assign_specialistto 1 via PATCH and asserts the public/public/<slug>response exposesbusiness.auto_assign_specialist === 1. - e2e-test now passes without weakening guards? YES — no guards were changed (only
settings.ts,employees.ts,e2e-test.mjs, newbooking-e2e.mjs, andpackage.jsonwere touched;booking.ts,appointments.ts,scheduling.ts,db.ts,types.tsuntouched). The fix is purely test-fixture: instead of hard-coding out-of-working-hours ISO strings (11:00Z≈ 05:00 local, and2026-09-20is Sunday — both correctly rejected by the new working-hours enforcement), the test now fetches a real available slot from the same public endpoint that respects the guards. All 25 original assertions preserved; 4 new helper assertions added (slot lookups + slug).
Deviations
- e2e-test.mjs employee-service fallback (svc 5 → svc 6). The plan does not mandate this; the additional sub-task says "If service_id 5 has no slots, pick another service the employee offers". Implemented as: try service 5 across 30 days; if null, try service 6. In practice service 5 always yields slots in the seed data, so the fallback never fires — but it makes the test robust to seed variation. The self-assign assertion still holds because both services 5 and 6 are offered exclusively by Mateo Herrera.
findSlotsearches 30 days (vs. a single weekday in the suggested approach) — gives the fixture more headroom to dodge dense seed bookings without weakening any guard.
Concerns
None.