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-Admin/docs/admin-backend-spec.md
kirukib 728a31060f docs: add production Vercel URL and allow .env.example
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-06 18:06:31 +03:00

8.9 KiB

Gishen Admin — Backend Spec Sheet

Repo: Gishen-Admin
Audience: Shared backend team (consolidate with Ecom / Mobile / B2B sheets later)
Base URL (TBD): https://api.gishen.example/v1
Auth: Bearer JWT for staff roles
Mocks: Admin SPA uses in-memory mocks until VITE_USE_MOCKS=false and VITE_API_BASE_URL point here.

Changelog

Date Change
2026-08-06 Scaffold: conventions, roles, auth, empty module sections
2026-08-06 Shell + RBAC + preferredLocale
2026-08-06 Pharmacist: prescriptions, branch orders
2026-08-06 Stock + Procurement
2026-08-06 Finance, orgs create + pending self-reg approval
2026-08-06 Marketing CRM / loyalty / campaigns
2026-08-06 Dispatch board + Telegram bot events
2026-08-06 Super Admin team/inbox/audit/settings + FAQ bilingual
2026-08-06 Data migration import jobs
2026-08-06 Deployed Admin SPA: https://gishen-admin.vercel.app

Conventions

Item Convention
Content type application/json (multipart for imports / uploads)
IDs UUID v4
Money Integer ETB (major units for Admin UI demos; align platform-wide later)
Errors { "error": { "code": string, "message": string, "details"?: object } }
Pagination ?page=&limit= → { data, meta: { page, limit, total } }

Staff roles

pharmacist · stock_manager · procurement · finance · marketing_manager · operations · super_admin

Pharmacist (and optionally stock) sessions include branchId.


Auth & me

Method Path Roles Description
POST /auth/staff/login — Email/password → tokens + user
POST /auth/refresh refresh Rotate access
POST /auth/logout staff Revoke
GET /auth/me staff Current principal, roles, branchId
PATCH /users/me staff { preferredLocale?: "en"|"am", name? }

Login response sketch:

{
  "accessToken": "...",
  "refreshToken": "...",
  "user": {
    "id": "uuid",
    "name": "Hana Pharmacist",
    "email": "pharmacist@gishen.et",
    "role": "pharmacist",
    "branchId": "uuid",
    "preferredLocale": "en"
  }
}

Mock key: authStore.login → /auth/staff/login


Orders (branch inbox)

Method Path Roles Description
GET /pharmacy/orders pharmacist, operations, super_admin ?branchId= required for pharmacist
POST /orders/:id/confirm pharmacist, super_admin Confirm stock
POST /orders/:id/assign-rider pharmacist, operations, super_admin { riderId }
PATCH /orders/:id/status pharmacist, operations, super_admin Status lifecycle

Mock: mocks/data.orders


Prescriptions

Method Path Roles Description
GET /pharmacy/prescriptions pharmacist, super_admin Branch-scoped queue
POST /admin/prescriptions/:id/verify pharmacist, super_admin { status: approved|queried|rejected, qtyAdjustments?, substitute?, notes? }
POST /pharmacy/prescriptions/:id/dispense pharmacist { batch, quantity } stamped pharmacistId + time
GET /pharmacy/prescriptions/controlled-report pharmacist, super_admin Controlled-substance report
GET /pharmacy/refills pharmacist, super_admin Days-of-supply / script expiry oversight

Stock & ERP

Method Path Roles Description
GET /pharmacy/inventory stock_manager, pharmacist (read), procurement (read), super_admin Per-branch stock
GET /integrations/erp/sync-status stock_manager, super_admin Last sync
GET /admin/stock/discrepancies stock_manager, super_admin Platform vs ERP
POST /admin/stock/discrepancies/:id/resolve stock_manager, super_admin One-click resolve
GET/PUT /admin/stock/field-ownership stock_manager, super_admin ERP vs platform field owners
POST /admin/stock/entry/suggest stock_manager, super_admin Fuzzy duplicate suggestions body { query }
GET /admin/stock/merge-proposals stock_manager, super_admin Merge queue
POST /admin/stock/merge-proposals/:id/approve stock_manager, super_admin Human approve; reversible 30d
GET /admin/stock/alerts stock_manager, super_admin Low stock / expiry watchlist
POST /admin/stock/transfers stock_manager, super_admin Create/approve transfer (owner)

Procurement

Method Path Roles Description
GET /admin/procurement/reports procurement, stock_manager, super_admin Dead-stock / fast-mover
GET /admin/procurement/reorder-recommendations procurement, super_admin From velocity
POST /admin/stock/transfers/request procurement, super_admin Request only; Stock Manager approves

Finance & organisations

Method Path Roles Description
GET /admin/finance/settlements finance, super_admin Daily by channel
GET /admin/finance/reconciliations finance, super_admin Matched to orders
GET/PUT /admin/finance/gateways finance, super_admin Enable/disable Chapa, ArifPay, Telebirr, M-Pesa
POST /admin/finance/refunds finance, super_admin Refund handling
GET /admin/finance/loyalty-liability finance, super_admin Monthly Birr liability
GET /admin/organisations finance, super_admin List
POST /admin/organisations finance, super_admin Create org from Admin (active)
GET /admin/organisations/pending finance, super_admin Self-register queue
POST /admin/organisations/:id/approve finance, super_admin Activate credit
POST /admin/organisations/:id/reject finance, super_admin Reject
GET /admin/organisations/:id/statements finance, super_admin Consolidated invoices

Cross-repo: B2B portal POST /company/register creates status=pending. Admin approve activates credit.


Marketing

Method Path Roles Description
GET /admin/crm/customers marketing_manager, super_admin Read profiles
GET /admin/crm/segments marketing_manager, super_admin Self-updating segments
GET/POST /admin/campaigns marketing_manager, super_admin Compose/schedule SMS/Telegram/push
GET/PUT /admin/loyalty/config marketing_manager, super_admin Earn/tiers/referral bonus
GET /admin/kpi/summary marketing_manager, finance, super_admin Scoped KPIs

Dispatch & Telegram bot

Method Path Roles Description
GET /dispatch/board operations, super_admin Paid + Rx-approved queue
POST /dispatch/trips operations, super_admin Batch fulfilments
POST /dispatch/trips/:id/assign operations, super_admin { riderId } → emits Telegram manifest
POST /dispatch/bot/webhook service Bot status + PoD callbacks
GET /dispatch/intake operations, super_admin Partner/POS webhook monitor
POST /dispatch/riders operations, super_admin Link Telegram account

Events: trip.assigned → bot push; trip.status_updated → board + customer tracking.


FAQ (bilingual)

Method Path Roles Description
GET /admin/faq all staff Published articles
POST /admin/faq marketing_manager, super_admin Create
PUT /admin/faq/:id marketing_manager, super_admin Update / publish
DELETE /admin/faq/:id super_admin Delete

Fields: title_en, title_am, body_en, body_am, category, published.


Team, inbox, audit, settings

Method Path Roles Description
GET/POST /admin/users super_admin Staff + role + branch
GET /admin/inbox/threads super_admin Chatwoot/Telegram/WhatsApp attached to customer
GET /admin/audit super_admin Audit log
GET/PUT /admin/settings super_admin Retention, access controls

Data migration / imports

Method Path Roles Description
GET /admin/imports/templates stock_manager, finance, operations, super_admin Entity schemas
POST /admin/imports same Multipart file upload
POST /admin/imports/:id/map same Column mapping (+ save template)
POST /admin/imports/:id/validate same Dry-run row errors
POST /admin/imports/:id/commit same Upsert commit
GET /admin/imports same Job history
CRUD /admin/imports/mapping-templates same Saved presets

Entity templates: stock, catalog, hr_members, branches, riders, generic.


Open questions

  1. Money units: ETB major vs cents — keep consistent with Ecom/B2B sheets
  2. Driver channel assumption: Telegram bot (flag if SMS/WhatsApp preferred)
  3. Checkout entitlement-split: shared component across Ecom/Mobile/B2B (out of Admin UI)