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>
5.6 KiB
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
POST /v1/auth/login
Demo persona login (mock phase). Prefer demo_user_id; demo_role remains for compatibility.
| Auth | Public |
| Roles | — |
Request
{
"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
{
"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
{
"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
{ "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
{
"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
{
"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
{
"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.