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-B2B/docs/backend/endpoints/auth.md
kirukib 8fe6d58a09 Document portal auth, profile, and pharmacy ID contracts in backend specs.
Keep the living API sheet aligned with demo personas, avatars, ID-card QR scan, list filters, and Admin/Ecom coordination.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-06 22:10:07 +03:00

288 lines
5.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.

# Endpoints: Auth
Session and user preference endpoints for Gishen-B2B demo login and future production auth.
**Workspace:** `/Users/kirukib/Desktop/Yaltopia Project/Gishen-B2B`
**Entity:** [`../entities/session-user.md`](../entities/session-user.md)
---
## POST /v1/auth/login
Demo persona login (mock phase). Prefer `demo_user_id`; `demo_role` remains for compatibility.
| | |
|---|---|
| **Auth** | Public |
| **Roles** | — |
### Request
```json
{
"demo_user_id": "user_hr",
"locale": "en"
}
```
Legacy: `{ "demo_role": "HR_ADMIN", "locale": "en" }`
`demo_role`: `SUPER_USER` \| `HR_ADMIN` \| `FINANCE` \| `MEMBER`
Production (future): `{ "email", "password" }` or OAuth code exchange.
### Response 200
```json
{
"data": {
"token": "mock_jwt_...",
"user": {
"id": "user_hr",
"email": "hr@yaltopia.com",
"full_name": "Hanna HR",
"org_id": "org_yaltopia",
"roles": ["HR_ADMIN"],
"active_role": "HR_ADMIN",
"locale": "en",
"avatar_url": "https://api.dicebear.com/9.x/lorelei/svg?seed=user_hr",
"org_status": "active",
"permissions": ["org:read", "org:write_hr", "members:write", "packages:write", "migration:write", "finance:read"]
}
}
}
```
### Errors
| Code | HTTP | When |
|------|------|------|
| `VALIDATION_FAILED` | 400 | Invalid `demo_user_id` / `demo_role` |
| `NOT_FOUND` | 404 | Unknown demo persona |
| `UNAUTHENTICATED` | 401 | Production bad credentials |
### Clinical withhold
N/A — session only.
---
## POST /v1/auth/logout
| | |
|---|---|
| **Auth** | Required |
| **Roles** | Any |
### Response 204
No body.
---
## GET /v1/auth/me
Current session user.
| | |
|---|---|
| **Auth** | Required |
| **Roles** | Any |
### Response 200
```json
{
"data": {
"id": "usr_01HMEM",
"email": "member.demo@acme.et",
"full_name": "Demo Member",
"org_id": "org_01DEMO",
"member_id": "mbr_01DEMO",
"customer_id": "cus_01DEMO",
"roles": ["MEMBER"],
"locale": "am",
"org_status": "active",
"allowance_summary": {
"allowance_remaining": { "amount": "10800.00", "currency": "ETB" }
}
}
}
```
### Errors
| Code | HTTP |
|------|------|
| `UNAUTHENTICATED` | 401 |
---
## PATCH /v1/auth/me/locale
Update user locale preference.
| | |
|---|---|
| **Auth** | Required |
| **Roles** | Any |
### Request
```json
{ "locale": "am" }
```
### Response 200
Returns updated session user with `locale: "am"`.
### Validation
| Rule | Code |
|------|------|
| `locale` in `en`, `am` | `VALIDATION_FAILED` |
### Clinical withhold
N/A.
---
## GET /v1/auth/demo-profiles
List pre-seeded demo personas for `/login` test-user dropdown.
| | |
|---|---|
| **Auth** | Public |
| **Roles** | — |
### Response 200
```json
{
"data": [
{
"id": "user_super",
"email": "super@yaltopia.com",
"full_name": "Selam Super",
"demo_role": "SUPER_USER",
"roles": ["SUPER_USER", "HR_ADMIN", "FINANCE", "MEMBER"],
"avatar_url": "https://api.dicebear.com/9.x/lorelei/svg?seed=user_super",
"label": "Super User",
"description": "Full portal access including clinical detail"
},
{
"id": "user_hr",
"email": "hr@yaltopia.com",
"full_name": "Hanna HR",
"demo_role": "HR_ADMIN",
"roles": ["HR_ADMIN"],
"avatar_url": "https://api.dicebear.com/9.x/lorelei/svg?seed=user_hr",
"label": "HR Administrator",
"description": "Members, departments, packages — no clinical detail"
},
{
"id": "user_fin",
"email": "finance@yaltopia.com",
"full_name": "Fikru Finance",
"demo_role": "FINANCE",
"roles": ["FINANCE"],
"avatar_url": "https://api.dicebear.com/9.x/lorelei/svg?seed=user_fin",
"label": "Finance Approver",
"description": "Spend, statements, approvals — no clinical detail"
},
{
"id": "user_mem",
"email": "member@yaltopia.com",
"full_name": "Abebe Member",
"demo_role": "MEMBER",
"roles": ["MEMBER"],
"member_id": "mbr_01HMEM001",
"avatar_url": "https://api.dicebear.com/9.x/lorelei/svg?seed=user_mem",
"label": "Member",
"description": "Own allowance, orders, prescriptions"
}
]
}
```
Login request may use `{ "demo_user_id": "user_hr" }` (preferred) or legacy `{ "demo_role": "HR_ADMIN" }`.
---
## GET /v1/me/profile
Current user’s profile (account page).
| | |
|---|---|
| **Auth** | Required |
| **Roles** | Any |
### Response 200
```json
{
"data": {
"id": "user_hr",
"email": "hr@yaltopia.com",
"full_name": "Hanna HR",
"org_id": "org_yaltopia",
"org_name": "Yaltopia",
"roles": ["HR_ADMIN"],
"active_role": "HR_ADMIN",
"locale": "en",
"avatar_url": "https://api.dicebear.com/9.x/lorelei/svg?seed=user_hr",
"avatar_initials": "HH",
"member_id": null
}
}
```
---
## PATCH /v1/me/profile
Update display preferences (locale / name stub / active role for multi-role users).
| | |
|---|---|
| **Auth** | Required |
| **Roles** | Any |
### Request
```json
{
"locale": "am",
"active_role": "SUPER_USER"
}
```
`active_role` must be one of the user’s `roles[]` (demo: `user_super` holds all four).
### Response 200
Updated profile object.
### Errors
| Code | HTTP | When |
|------|------|------|
| `VALIDATION_FAILED` | 400 | Invalid locale or role not in `roles[]` |
---
## UI routes
| Route | Purpose |
|-------|---------|
| `/login` | Yimaru-style login — test-user dropdown + locale switcher |
| `/profile` | Own profile — avatar, org, role switch, sign out |
## Clinical withhold notes
Auth endpoints do not expose clinical data. Role list / `active_role` on session determines withhold behavior on downstream endpoints.