ui phase 10
This commit is contained in:
@@ -934,3 +934,47 @@ delivers fixes in its own change. **Frontend never edits backend code to "fix" a
|
||||
- **Proposed shape:** `PatientDto { …, avatarUrl: string | null }` + `POST patients/{id}/avatar` (multipart),
|
||||
same seam shape as the nurse profile's `uploadAvatar`.
|
||||
- **Status:** deferred, non-blocking — no UI currently reads a patient `avatarUrl`; initials-only ships either way.
|
||||
|
||||
## REQ-059 — Ticket inbox enrichment: last-message preview + author role + an unread-total read — filed by ui-phase-10 — 2026-07-19
|
||||
- **Need:** Extends REQ-028 (delivered: `unreadCount`/`lastMessageAt` are now real on `TicketSummaryDto`).
|
||||
Three more additions:
|
||||
1. `lastMessagePreview: string | null` on `TicketSummaryDto` — the first ~80 chars of the last
|
||||
**non-internal** message (server-truncated so an internal admin note can never leak into a preview
|
||||
snippet, same boundary REQ-028/the contract already enforces for the thread).
|
||||
2. `lastAuthorRole: 'customer' | 'nurse' | 'admin' | 'system' | null` on `TicketSummaryDto` — the last
|
||||
visible message's author role, so the inbox card can label the preview ("پرستار: …" vs "شما: …").
|
||||
3. A cheap unread-**total** read for the caller (e.g. `GET tickets/unread_count`, mirroring
|
||||
`notifications/unread_count`) — a single number summed server-side across the caller's tickets.
|
||||
- **Why:** The inbox redesign (phase §3.1) turns the ticket list into a real messaging-app inbox: a bold
|
||||
subject + one-line last-message snippet + unread pill + relative last-activity time, and a small unread
|
||||
badge on the chrome's support entry (TopBar icon on the customer shell, the sidebar item on the nurse
|
||||
shell). `unreadCount`/`lastMessageAt` already ship (REQ-028); the preview/author-role fields don't exist
|
||||
anywhere in the wire summary, and there is no chrome-badge-sized aggregate read at all today (fetching the
|
||||
whole first page of tickets just to sum `unreadCount` client-side doesn't scale and isn't the badge's job).
|
||||
The client's `TicketSummary` type carries `lastMessagePreview`/`lastAuthorRole` as optional, mock-tolerant
|
||||
fields (`services/tickets/types.ts`); the mock computes them from its own store
|
||||
(`services/tickets/apis/mockApi.ts`); the real `ticketsClientApi` maps them to `null` and the card
|
||||
degrades to subject + status chip + time — never an empty slot, never a fake "0 unread". The chrome badge
|
||||
is behind a new `TicketsApi.getUnreadTotal()` seam method — the mock sums its tickets' `unreadCount`, the
|
||||
real implementation returns `null` (no signal) until this lands, and the badge simply doesn't render.
|
||||
- **Proposed shape:** `TicketSummaryDto { …, lastMessagePreview: string | null, lastAuthorRole: string | null
|
||||
}`; `GET tickets/unread_count → { unreadCount: number }` (or fold the total into the existing list envelope
|
||||
as a `totalUnreadCount` sibling of `items`/`total`, whichever fits the pagination envelope better).
|
||||
- **Status:** open — mock-only; the real path shows subject + status + Shamsi/relative time with no preview
|
||||
line, and the support-entry chrome badge renders nothing until a signal exists.
|
||||
|
||||
## REQ-060 — Ticket message photo attachments — filed by ui-phase-10 — 2026-07-19
|
||||
- **Need:** Upload + serve a photo attachment on a ticket message, using the existing object-storage seam
|
||||
(`IObjectStorage`, already wired for verification documents — REQ-006's avatar upload is the closest
|
||||
precedent). A message-attachment linkage (one or more attachments per message), server-side size/type
|
||||
validation (images only, a sane size ceiling), and a signed-URL-style read for displaying them in a thread.
|
||||
- **Why:** Refund and coordination tickets routinely need photo evidence (a receipt, a care-situation photo)
|
||||
and today the only channel (tickets, by product design — no free chat) has no way to attach one. The
|
||||
composer's attachment button + pending-upload chip are **designed but gated** behind
|
||||
`TICKETS_ATTACHMENTS_ENABLED` (`services/tickets/constants.ts`, default `false`) — no dead button ships in
|
||||
production; flipping the flag once this lands is the only client change needed.
|
||||
- **Proposed shape:** `POST tickets/{id}/messages` gains an optional `attachmentIds: string[]` (uploaded
|
||||
beforehand via a new `POST tickets/{id}/attachments`, multipart, returning an id + a short-lived signed
|
||||
URL), and `TicketMessageDto` gains `attachments: { id: string, url: string, contentType: string }[]`.
|
||||
- **Status:** deferred — the affordance is designed and gated off; nothing renders until this lands and the
|
||||
capability flag flips.
|
||||
|
||||
Reference in New Issue
Block a user