3.1 KiB
profiles — customer and nurse profiles
Client seam
client/src/services/profiles/·USE_PROFILES_MOCK = false(real) · 7 server ops Last verified: 2026-07-30 against commitd3ec723and swagger.v1.json (2026-07-29).
One client domain over two server controllers, because the client's profile screens are one feature with
two actor variants. Identity and roles come from auth.md's /me, not from here.
Endpoints
| Method | Path | Verdict |
|---|---|---|
| GET | /api/v1/customer_profiles/me |
wired |
| POST | /api/v1/customer_profiles/upsert |
wired |
| POST | /api/v1/customer_profiles/avatar |
unwired — the client's avatar upload calls the nurse route only |
| GET | /api/v1/nurse_profiles/me |
wired |
| POST | /api/v1/nurse_profiles/upsert |
wired |
| POST | /api/v1/nurse_profiles/avatar |
wired |
| POST | /api/v1/nurse_profiles/set_accepting_bookings |
wired |
All [Authorize]. No phantoms.
customer_profiles/avatarexists and is unused. The nurse avatar upload is wired; the customer one is not, so a customer cannot set a photo even though the endpoint is live. A one-line client gap, not a contract gap.
Shape rules the JSON does not express
- Avatar upload is
multipart/form-data. This is the one place the client must not setContent-Type—clientFetchdetects aFormDatabody and lets the browser write the multipart boundary. A manual JSON content-type there breaks the upload. See ../api-contract.md. avatarUrlis served by the object-storage seam.Seams:ObjectStorage:Provider=local(default, writes underRootPath) ors3. In the deploymentRootPathis a named docker volume — without it, uploads vanish on the nextup --build. See ../topology.md.isAcceptingBookingsis a real toggle with real consequences. It is one of the four conditions the search index'sis_searchablerequires — flipping it off removes the nurse from discovery. See search.md.isVerifiedonNurseProfileDtois derived, never writable. It is written only by the verification finalize transaction when the aggregate reachesapproved. Never set it from a profile write. See verification.md.averageRating/totalReviews/totalCompletedBookingsare recomputed from source, not incremented. A moderation change that hides a review recomputes the aggregate. See reviews.md.specializationsJsonis a string containing JSON, like the other*Jsonfields on this wire.preferredLanguageonCustomerProfileDto(REQ-007, delivered) alongside the name update.defaultEmergencyContactName/Phoneare the customer-level fallback used when a booking supplies none.
Enums
None of its own. educationLevel and educationField are free strings. Gender lives on the user
(see auth.md), not on the profile.
Open REQs
None. REQ-006 (avatar/object-storage upload route) and REQ-007 (name + preferred language) were both delivered in refinement-phase-3.