This repository has been archived on 2026-08-11. You can view files and clone it, but cannot push or open issues or pull requests.
Gishen-Mob/docs/BACKEND_SPEC.md
kirukib 858972b5ca Add multi-provider login and guest pharmacist order codes.
Guests can generate a shareable GSH code for admin fulfillment; sign-in now supports Google, email, phone, and Telegram demos, with the backend spec updated.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-07 16:11:23 +03:00

192 lines
9.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Gishen-Mob Backend Spec
**Base URL (TBD):** `https://api.gishen.example/v1`
**Auth:** Bearer JWT after verified sign-in (phone OTP, email, Google, or Telegram)
**Headers:** `Authorization`, `Accept-Language` (`en` | `am`), `Content-Type: application/json`
Shared with Gishen-Ecom / Gishen-B2B where noted.
Patch this file whenever a feature is added or finalized.
## Auth
| Method | Path | Status | Notes |
|--------|------|--------|-------|
| POST | `/auth/otp/request` | Required | `{ phone }` — SMS OTP |
| POST | `/auth/otp/verify` | Required | `{ phone, code }` → session + user |
| POST | `/auth/email/login` | Required | `{ email, password }` → session + user |
| POST | `/auth/email/register` | Optional | `{ name, email, password, phone? }` |
| POST | `/auth/oauth/google` | Required | `{ idToken }` (or auth code) → session + user |
| POST | `/auth/oauth/telegram` | Required | Telegram Login Widget payload → session + user |
| POST | `/auth/guest` | Required | Optional device id → limited guest session (`isGuest: true`) |
| POST | `/auth/biometric/bind` | Required | Device biometric public key |
| GET | `/users/me` | Required | Profile, locale, points, tier, `authProvider` |
| PATCH | `/users/me` | Required | name, email, phone, `locale`, biometric flag |
**Providers (mobile UI):** `google` \| `email` \| `phone` \| `telegram` \| `guest`
Guest sessions may browse catalog and generate **pharmacist order codes**; loyalty, corporate, and some care features require a non-guest account.
## Locale
| Method | Path | Status | Notes |
|--------|------|--------|-------|
| PATCH | `/users/me` | Required | `{ locale: "en" \| "am" }` |
| — | Accept-Language | Required | All requests |
## Catalog
| Method | Path | Status | Notes |
|--------|------|--------|-------|
| GET | `/catalog/products` | Required | q, category, badge, max — parity with Ecom |
| GET | `/catalog/products/:idOrSlug` | Required | |
| GET | `/catalog/categories` | Required | |
## Favorites
| Method | Path | Status | Notes |
|--------|------|--------|-------|
| GET | `/favorites/me` | Required | Product ids |
| PUT | `/favorites/:productId` | Required | Add |
| DELETE | `/favorites/:productId` | Required | Remove |
## Addresses
| Method | Path | Status | Notes |
|--------|------|--------|-------|
| GET | `/users/me/addresses` | Required | Saved delivery addresses |
| POST | `/users/me/addresses` | Required | label, street, area, landmark?, isDefault? |
| PATCH | `/users/me/addresses/:id` | Required | |
| DELETE | `/users/me/addresses/:id` | Required | |
## Branches / Stock
| Method | Path | Status | Notes |
|--------|------|--------|-------|
| GET | `/branches` | Required | |
| GET | `/branches/nearby` | Required | `lat`, `lng` |
| GET | `/stock/product/:productId` | Required | Nearby availability |
## Orders
| Method | Path | Status | Notes |
|--------|------|--------|-------|
| POST | `/orders` | Required | items, fulfillment, branchId?, location, paymentMethod, prescriptionFileKeys?, notes, credit?, `anyBranch?` |
| GET | `/orders/me` | Required | Authenticated user’s orders |
| GET | `/orders/:id` | Required | |
| GET | `/orders/by-code/:code` | Required | Lookup by `GSH-XXXX` (guest + pickup). Mobile uses this for “find my code”. |
| GET | `/orders/:id/tracking` | Required | Rider trail when assigned |
| POST | `/orders/:id/cancel` | Required | |
### Guest / pharmacist order codes (parity with Gishen Ecom Web)
Guests (and optionally signed-in pickup) receive a short **pharmacist reference code** (`GSH-XXXX`).
| Method | Path | Status | Notes |
|--------|------|--------|-------|
| POST | `/orders/guest-codes` | Required | Basket snapshot + customer name/phone → `{ code, orderId, status: "requested" }`. Mobile shows copy / share / screenshot card. |
| GET | `/admin/orders/by-code/:code` | Required | **Admin** — pharmacist enters code to create / hydrate the POS order (shared with Ecom admin). |
| POST | `/admin/orders/by-code/:code/fulfill` | Required | Mark created / confirmed after admin processing |
**Mobile contract**
- Guest checkout forces pickup + `pay_at_branch` + any-branch code.
- Response includes `pickupCode`, `status: requested` until pharmacist creates the order in admin.
- Share payload should include code, customer, line items, total (plain text for WhatsApp / clipboard).
## Payments
| Method | Path | Status | Notes |
|--------|------|--------|-------|
| POST | `/payments/initiate` | Required | `chapa` \| `telebirr` \| `mpesa` only for delivery |
| POST | `/payments/webhook/*` | Required | Gateway callbacks |
| — | `pay_at_branch` | Required | Allowed **only** when `fulfillment=pickup` (required for guest pharmacist codes) |
## Prescriptions (Rx Care)
| Method | Path | Status | Notes |
|--------|------|--------|-------|
| POST | `/uploads/signed-url` | Required | Rx images |
| POST | `/prescriptions` | Required | Multi-page keys, medicines[], patient, memberId? |
| POST | `/prescriptions/check` | Required | Match catalog → ready/review/unavailable |
| GET | `/prescriptions/me` | Required | |
| GET | `/prescriptions/:id` | Required | Detail + attached reminders |
| POST | `/prescriptions/:id/reorder` | Required | |
## Reminders
| Method | Path | Status | Notes |
|--------|------|--------|-------|
| POST | `/health/reminders` | Required | Dose/refill schedules (times[], graceMinutes, escalate?) |
| POST | `/health/reminders/:id/confirm` | Required | `dose.confirmed` |
| POST | `/health/reminders/:id/snooze` | Required | |
| GET | `/health/reminders/me` | Required | |
| — | Local + remote push | Required | Daily dose window; calendar UI on `/prescriptions/:id/calendar` |
## Emergency contacts
| Method | Path | Status | Notes |
|--------|------|--------|-------|
| GET | `/users/me/emergency-contacts` | Required | |
| POST | `/users/me/emergency-contacts` | Required | name, phone, relationship |
| DELETE | `/users/me/emergency-contacts/:id` | Required | |
| — | Job `dose.missed_escalation` | Required | After grace (default 30m) SMS/push to contact if no confirm |
## Family
| Method | Path | Status | Notes |
|--------|------|--------|-------|
| GET | `/family/members` | Required | |
| POST | `/family/invites` | Required | phone or link code |
| POST | `/family/invites/accept` | Required | |
| DELETE | `/family/members/:id` | Required | |
## Subscriptions
| Method | Path | Status | Notes |
|--------|------|--------|-------|
| GET | `/subscriptions/me` | Required | |
| POST | `/subscriptions` | Required | |
| POST | `/subscriptions/:id/pause` | Required | |
| POST | `/subscriptions/:id/resume` | Required | |
| POST | `/subscriptions/:id/cancel` | Required | |
## B2B / Corporate (shared with Gishen-B2B)
| Method | Path | Status | Notes |
|--------|------|--------|-------|
| GET | `/users/me/contexts` | Required | personal + org memberships |
| POST | `/orgs/join` | Required | `{ code }` |
| GET | `/company/me` | Required | Member view: plan, allowance |
| POST | `/checkout/credit/quote` | Required | Basket split covered vs selfPay |
## Loyalty
| Method | Path | Status | Notes |
|--------|------|--------|-------|
| GET | `/loyalty/me` | Required | |
| GET | `/loyalty/me/ledger` | Required | |
| POST | `/loyalty/redeem` | Required | |
| GET | `/referrals/me` | Required | |
## Notifications (in-app inbox)
Distinct from order list. Home bell → inbox.
| Method | Path | Status | Notes |
|--------|------|--------|-------|
| GET | `/notifications/me` | Required | kinds: `order` \| `rx` \| `dose` \| `loyalty` \| `promo` \| `system` |
| POST | `/notifications/:id/read` | Required | |
| POST | `/notifications/read-all` | Required | |
| DELETE | `/notifications/:id` | Required | |
| POST | `/devices` | Required | push token registration |
## Push / Tracking
| Method | Path | Status | Notes |
|--------|------|--------|-------|
| POST | `/devices` | Required | push token |
| — | Events | Required | order.*, dispatch.*, dose.*, refill.*, escalation.*, guest_code.* |
| GET | `/orders/:id/tracking` | Required | |
## Contact / Support
| Method | Path | Status | Notes |
|--------|------|--------|-------|
| POST | `/contact` | Required | |
| — | Chatwoot | Deeplink | https://chat.yaltopia.com |
| — | WhatsApp / Call | Deeplink | Branch support numbers |
### Changelog
- 2026-08-06: Scaffold — skeleton created with all domains.
- 2026-08-06: Auth/Locale — OTP mock, biometric bind flag, language picker en/am, Accept-Language noted.
- 2026-08-06: Catalog — products/categories from Ecom data port; shop/search/favorites.
- 2026-08-06: Branches/Stock — GPS nearest sort; pickup selection (stock map stub).
- 2026-08-06: Orders/Payments/B2B — checkout with Chapa/Telebirr/M-Pesa; pay_at_branch pickup-only; WhatsApp handoff; credit quote split stub.
- 2026-08-06: Prescriptions/Reminders/Emergency — camera multi-page scan, check statuses, calendar dose push, escalation job contract.
- 2026-08-06: Family/Subscriptions — invite/manage; refill subscription CRUD.
- 2026-08-06: B2B/Account — contexts, join codes, profile switcher.
- 2026-08-06: Loyalty/Push/Tracking — wallet redeem/referral; order tracking map mock; device push channels.
- 2026-08-06: Contact/Support — contact form + Chatwoot/WhatsApp/call deeplinks.
- 2026-08-07: Auth providers — Google, Email, Phone OTP, Telegram, and Guest session contracts; `authProvider` on `/users/me`.
- 2026-08-07: Guest pharmacist codes — `POST /orders/guest-codes`, `GET /orders/by-code/:code`, admin fulfill-by-code (Ecom parity); mobile copy/share/screenshot card.
- 2026-08-07: Notifications inbox — dedicated `/notifications/me` (separate from Orders); Favorites + Addresses endpoints documented; Rx Care dose reminder confirm/snooze.