# 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.