App (Patient) API Flows
JWT audience: snr_usr. User ID from JWT id claim — never sent in request body.
Browse catalog
Section titled “Browse catalog”sequenceDiagram participant App as Patient App participant Worker as second_opinion participant D1 as D1 App->>Worker: GET /app/how Worker-->>App: bilingual how-it-works copy App->>Worker: GET /app/list-reviewtypes Worker->>D1: SELECT active review_types Worker-->>App: review type picker list App->>Worker: GET /app/list-diseases Worker->>D1: SELECT active disease_categories Worker-->>App: disease category picker list
Create review case
Section titled “Create review case”sequenceDiagram
participant App as Patient App
participant Worker as second_opinion
participant D1 as D1
participant Pay as Payment Hub
App->>Worker: POST /app/save-review-case
Worker->>D1: validate rt_id, dc_id
Worker->>D1: INSERT review_cases
alt status = review (submit)
Worker->>D1: INSERT case_status_history (new_case)
Worker->>D1: UPSERT sticky_header_cards
end
Worker-->>App: { case_id }
Edit review case
Section titled “Edit review case”sequenceDiagram
participant App as Patient App
participant Worker as second_opinion
participant D1 as D1
App->>Worker: POST /app/edit-review-case
Note over Worker: Allowed only while status = draft
Worker->>D1: SELECT review_cases for user
Worker->>D1: UPDATE case fields
Worker-->>App: { status: 1000 }
List review cases
Section titled “List review cases”sequenceDiagram
participant App as Patient App
participant Worker as second_opinion
participant D1 as D1
App->>Worker: POST /app/list-review-cases { page?, page_size? }
Note over Worker: JWT id = review_cases.user_id
Worker->>D1: COUNT cases (excludes draft from total)
Worker->>D1: SELECT paginated cases for user
Worker->>D1: SELECT draft case (if any)
Worker->>D1: LOAD sop_doctors for coordinators
Worker->>D1: LOAD case_status_history for completed dates
Worker-->>App: { cases[], drafts?, summary, pagination }
Review case details
Section titled “Review case details”sequenceDiagram
participant App as Patient App
participant Worker as second_opinion
participant D1 as D1
App->>Worker: POST /app/review-case-details { case_id }
Note over Worker: JWT id must own the case
Worker->>D1: SELECT review_cases + review_type + specialty
Worker->>D1: SELECT second_opinions for case
Worker->>D1: SELECT case_status_history
Worker->>D1: LOAD sop_doctors for coordinator
Worker-->>App: case detail + timeline + coordinator + documents
Payment success webhook
Section titled “Payment success webhook”sequenceDiagram participant PG as Payment Gateway participant Worker as second_opinion participant D1 as D1 participant PX as Persistence participant Sock as Socket Hub PG->>Worker: GET /app/success-webhook?... Worker->>D1: UPDATE review_cases → payment_success Worker->>D1: INSERT case_status_history Worker->>PX: create invoice Worker->>D1: INSERT sticky_header_cards Worker->>Sock: notify coordinator Worker-->>PG: redirect / JSON
Payment failed webhook
Section titled “Payment failed webhook”sequenceDiagram participant PG as Payment Gateway participant Worker as second_opinion participant D1 as D1 PG->>Worker: GET /app/failed-webhook?... Worker->>D1: UPDATE review_cases → payment_failed Worker-->>PG: redirect / JSON
Payment confirmation
Section titled “Payment confirmation”sequenceDiagram participant App as Patient App participant Worker as second_opinion participant D1 as D1 App->>Worker: GET /app/confirm-order-deatils?case_id=... Worker->>D1: SELECT review_cases Worker-->>App: order summary for confirmation screen
Sticky header card
Section titled “Sticky header card”sequenceDiagram participant App as Patient App participant Worker as second_opinion participant D1 as D1 App->>Worker: GET /app/get-sticky-data Worker->>D1: SELECT sticky_header_cards for user Worker-->>App: active in-app status banners
Upload medical documents
Section titled “Upload medical documents”sequenceDiagram
participant App as Patient App
participant Worker as second_opinion
participant D1 as D1
App->>Worker: POST /app/update-meddocs
Note over Worker: Validates case is draft + owned by user
Worker->>D1: SELECT medical_documents
Worker->>D1: UPDATE append med_docs JSON
Worker-->>App: { status: 1000 }
View report
Section titled “View report”sequenceDiagram participant App as Patient App participant Worker as second_opinion participant D1 as D1 App->>Worker: POST /app/view-report Worker->>D1: SELECT review_cases WHERE user_id + case_id Note over Worker: status must be completed Worker-->>App: report data + PDF URL
Cancellation reasons
Section titled “Cancellation reasons”sequenceDiagram
participant App as Patient App
participant Worker as second_opinion
participant D1 as D1
App->>Worker: POST /app/cancellation-reasons { case_id }
Worker->>D1: validate case ownership
Worker-->>App: predefined + other reason options
Cancel case
Section titled “Cancel case”sequenceDiagram
participant App as Patient App
participant Worker as second_opinion
participant D1 as D1
participant PX as Persistence
App->>Worker: POST /app/cancel-review-case
Worker->>D1: validate ownership + cancellable status
Worker->>D1: UPDATE status → cancelled
Worker->>D1: INSERT case_status_history
alt payment was made
Worker->>PX: initiate refund flow
end
Worker-->>App: { status: 1000 }