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/members.md
kirukib 3778801ef5 Ship Gishen B2B institutional portal with polished layout and mock-backed flows.
Deliver role-aware shell (sidebar, breadcrumbs, quick search, tables, detail/create layouts), locale-ready pages, shared backend/feature docs, and Vercel project config so HR, finance, and members can demo against typed mocks.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-06 21:18:23 +03:00

310 lines
4.9 KiB
Markdown

# Endpoints: Members
Member CRUD, quick import, invites, join flow, and dependants.
**Workspace:** `/Users/kirukib/Desktop/Yaltopia Project/Gishen-B2B`
**Entity:** [`../entities/member.md`](../entities/member.md)
---
## GET /v1/members
List members.
| | |
|---|---|
| **Auth** | Required |
| **Roles** | SUPER_USER, HR_ADMIN, FINANCE (read metadata) |
### Query
`?page=1&status=active&department_id=dept_01H&q=abel&member_type=primary`
### Response 200
Paginated members. HR/Finance receive withhold-safe fields (no Rx detail).
### Clinical withhold
Response omits prescription arrays; includes `prescription_count` only.
---
## POST /v1/members
Create member.
| | |
|---|---|
| **Auth** | Required |
| **Roles** | SUPER_USER, HR_ADMIN |
### Request
```json
{
"full_name": "Sara Hailu",
"phone": "+251933445566",
"email": "sara.h@acme.et",
"employee_id": "EMP-2001",
"department_id": "dept_01HABC",
"package_id": "pkg_01HGOLD",
"member_type": "primary",
"start_date": "2026-04-01",
"send_invite": true
}
```
### Response 201
Created [`Member`](../entities/member.md).
### Errors
| Code | HTTP | When |
|------|------|------|
| `ORG_PENDING` | 422 | Org not active |
| `DUPLICATE_MEMBER` | 409 | Phone/employee_id conflict |
| `NOT_FOUND` | 404 | Invalid department/package |
| `DEPENDANT_LIMIT_EXCEEDED` | 422 | For dependant create |
---
## GET /v1/members/:id
Member detail.
| | |
|---|---|
| **Auth** | Required |
| **Roles** | SUPER_USER, HR_ADMIN, FINANCE (metadata); MEMBER (own only) |
### Errors
| Code | HTTP |
|------|------|
| `FORBIDDEN` | 403 — MEMBER accessing other member |
| `NOT_FOUND` | 404 |
### Clinical withhold
HR/Finance: no linked prescriptions. SUPER_USER: may include `prescriptions_summary`. MEMBER own: full allowance, order pointers.
---
## PATCH /v1/members/:id
Update member.
| | |
|---|---|
| **Auth** | Required |
| **Roles** | SUPER_USER, HR_ADMIN |
### Request (partial)
```json
{
"department_id": "dept_01HNEW",
"package_id": "pkg_01HSILVER",
"overrides": { "copay_percent": 5 }
}
```
---
## POST /v1/members/:id/offboard
Offboard member.
| | |
|---|---|
| **Auth** | Required |
| **Roles** | SUPER_USER, HR_ADMIN |
### Request
```json
{
"end_date": "2026-03-31",
"reason": "resignation"
}
```
### Response 200
`status: "offboarded"`. Prescriptions remain on `customer_id`.
---
## POST /v1/members/import
Quick Excel/CSV import (simplified migration).
| | |
|---|---|
| **Auth** | Required |
| **Roles** | SUPER_USER, HR_ADMIN |
### Request
`multipart/form-data`: `file`, optional `send_invites=true`
### Response 202
```json
{
"data": {
"job_id": "mig_01HQUICK",
"status": "validating"
}
}
```
Delegates to migration engine — see [`migration.md`](migration.md).
---
## POST /v1/members/:id/invite
Resend or create invite.
| | |
|---|---|
| **Auth** | Required |
| **Roles** | SUPER_USER, HR_ADMIN |
### Response 200
```json
{
"data": {
"invite_url": "https://b2b.gishen.../invite/tok_abc123",
"expires_at": "2026-03-20T00:00:00Z"
}
}
```
---
## GET /v1/invite/:token
Public invite preview.
| | |
|---|---|
| **Auth** | Public |
### Response 200
```json
{
"data": {
"org_name": "Acme Bank",
"member_name": "Sara Hailu",
"expires_at": "2026-03-20T00:00:00Z",
"valid": true
}
}
```
### Errors
| Code | HTTP |
|------|------|
| `INVITE_EXPIRED` | 422 |
| `NOT_FOUND` | 404 |
---
## POST /v1/invite/:token/accept
Accept invite and activate member account.
| | |
|---|---|
| **Auth** | Public (creates session) |
### Request
```json
{
"password": "SecurePass1",
"locale": "en"
}
```
---
## POST /v1/join
Self-join via join code or email domain.
| | |
|---|---|
| **Auth** | Public |
### Request
```json
{
"join_code": "ACME-2026",
"full_name": "New Employee",
"email": "new@acme.et",
"phone": "+251944556677"
}
```
Or domain-verified email flow.
### Response 201
Pending or active member + session depending on org verification settings.
### Errors
| Code | HTTP |
|------|------|
| `VALIDATION_FAILED` | 400 — bad code/domain |
| `ORG_PENDING` | 422 |
---
## POST /v1/members/:id/dependants
Add dependant.
| | |
|---|---|
| **Auth** | Required |
| **Roles** | SUPER_USER, HR_ADMIN |
### Request
```json
{
"full_name": "Kidus Hailu",
"phone": "+251955667788",
"relationship": "child",
"start_date": "2026-04-01"
}
```
---
## UI routes
| Route | Endpoint(s) |
|-------|-------------|
| `/members` | GET `/v1/members` |
| `/members/new` | POST `/v1/members` |
| `/members/import` | POST `/v1/members/import` |
| `/members/[id]` | GET/PATCH + invite/offboard/status mock actions |
| `/invite/[token]` | GET/POST invite |
| `/join` | POST `/v1/join` |
## Clinical withhold
Member endpoints never return prescription images or medicine lines to HR_ADMIN/FINANCE. Use prescription endpoints with role checks for SUPER_USER/MEMBER clinical access.