Skip to main content

WP-12 API spec

Fields and read projections the Stitch screens show. Decision: ADR 0012. Contract types: contracts.md. Wire: exchange/api-enrichment.md.

Usage​

Each field lands in its owner package. New projections are read-only. A patient reads /patient/home and /notifications. A clinician reads /clinician/dashboard. An admin reads /admin/dashboard. Imaging and lab read /worklists/summary?kind=.

Domain​

  • Appointment in patient.appointment gains reason, mode (VIDEO, CABINET), priority (ROUTINE, URGENT), clinicName, specialty, and rating?.
  • ClinicianProfile in clinician.profile gains displayName, clinicName, and bio. The search card adds fee and nextSlot.
  • PatientProfile in patient.profile gains firstName, lastName, birthDate, email, address, city, bloodGroup, allergies, and history.
  • Vitals in patient.monitoring gain unit, measuredAt, and status (NORMAL, HIGH, LOW).
  • Invoices in patient.billing gain createdAt, currency (MRU), reference, and clinicianName.
  • DiagnosticOrder in diagnostics gains examName, requestedAt, orderedBy, structureName, and scheduledAt?.
  • Admin users in admin gain displayName, status (ACTIVE, SUSPENDED), and createdAt. status lives on the Account row. Admin does not add a user table.
  • Account in identity gains lastSeenAt?.
  • Notification in notifications is a record: id, kind (VISIT, RESULT, INVOICE, ALERT), title, at, refId, unread. It is built per request.

Persistence​

All new columns are in db/changelog/modules/stitch-parity.yaml. One changeset per owner table. appointment_rating is one new table keyed by appointment_id. Notifications have no table. They are read from the owner tables at request time.

HTTP DTOs​

  • RatingRequestDto inbound. stars 1 to 5.
  • AgendaQueryDto gains from and to.
  • ScheduleRequestDto inbound. scheduledAt.
  • UserStatusRequestDto inbound. status.
  • PatientHomeResponseDto outbound. nextVisit?, latestResults, unpaidInvoices, openAlerts, unreadCount.
  • ClinicianDashboardResponseDto outbound. todayCount, waitingCount, urgentCount, nextVisits, openAlerts.
  • AdminDashboardResponseDto outbound. userCount, activeCount, structureCount, transactionTotal, recentUsers.
  • WorklistSummaryResponseDto outbound. kind, pending, urgent, scheduledToday, toValidate, sent.
  • NotificationResponseDto outbound. Notification fields.

Mappers​

NotificationMapper.fromAppointment(Appointment, lastSeenAt) -> Notification
NotificationMapper.fromResult(DiagnosticResult, lastSeenAt) -> Notification
NotificationMapper.fromInvoice(Invoice, lastSeenAt) -> Notification
NotificationMapper.fromAlert(Alert, lastSeenAt) -> Notification

Owner mappers add the new fields to their existing response DTOs.

Services​

NotificationService
list(session) -> Notification[]
markSeen(session) -> lastSeenAt

HomeProjectionService
patientHome(session) -> PatientHomeResponseDto
clinicianDashboard(session) -> ClinicianDashboardResponseDto

BookingService.rate(session, appointmentId, stars)
AgendaService.clinicianAgenda(session, from, to)
AdminService.dashboard(session)
AdminService.setUserStatus(session, accountId, status)
DiagnosticsService.summary(session, kind)
DiagnosticsService.schedule(session, orderId, scheduledAt)

Projection services call owner services. They do not call another package's controller or repository.

Controllers​

  • NotificationController on /api/v1/afia/notifications and /notifications/seen.
  • HomeProjectionController on /api/v1/afia/patient/home and /api/v1/afia/clinician/dashboard.
  • AppointmentController adds POST /{id}/rating.
  • AgendaController adds from and to.
  • AdminController adds GET /dashboard and PATCH /users/{id}/status. The existing POST /users/{id}/activation calls the same service until WP-15 moves to status.
  • DiagnosticsController adds GET /worklists/summary and PATCH /orders/{id}/schedule.

Does not do​

Screens. A copy of health rows in notifications. Push delivery. Charts. AI fields. Video session state. NNI is ADR 0013 / AFIA-38 on the patient profile, not this enrichment cut.