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>
156 lines
4.2 KiB
Markdown
156 lines
4.2 KiB
Markdown
# Entity: Organisation
|
|
|
|
Corporate account holding contract, credit limit, and monthly invoice for covered medical/pharmacy benefits.
|
|
|
|
**Workspace:** `/Users/kirukib/Desktop/Yaltopia Project/Gishen-B2B`
|
|
|
|
## Fields
|
|
|
|
| Field | Type | Required | Notes |
|
|
|-------|------|----------|-------|
|
|
| `id` | `string` | ✓ | `org_*` |
|
|
| `legal_name` | `string` | ✓ | Registered company name |
|
|
| `display_name` | `string` | | Trading name |
|
|
| `tin` | `string` | ✓ | Tax identification number |
|
|
| `status` | `OrgStatus` | ✓ | See enum below |
|
|
| `billing_contact` | `Contact` | ✓ | Name, email, phone |
|
|
| `approx_headcount` | `integer` | | Submitted at registration |
|
|
| `commercial` | `CommercialTerms` | | **Admin-written**; null until active |
|
|
| `verification` | `VerificationSettings` | | HR-configured once active |
|
|
| `dependant_limit` | `integer` | | Max dependants per primary member |
|
|
| `join_rules` | `JoinRules` | | Domain allowlist, join code |
|
|
| `locale_default` | `Locale` | | Org default; users may override |
|
|
| `created_at` | `Timestamp` | ✓ | |
|
|
| `updated_at` | `Timestamp` | ✓ | |
|
|
| `version` | `integer` | ✓ | Optimistic lock |
|
|
|
|
### OrgStatus
|
|
|
|
```
|
|
pending_activation | active | suspended | closed
|
|
```
|
|
|
|
### Contact
|
|
|
|
```typescript
|
|
{
|
|
name: string;
|
|
email: string;
|
|
phone: Phone;
|
|
}
|
|
```
|
|
|
|
### CommercialTerms (read-only in B2B; Admin writes)
|
|
|
|
| Field | Type | Notes |
|
|
|-------|------|-------|
|
|
| `credit_limit` | `Money` | Monthly or rolling — per contract |
|
|
| `credit_used` | `Money` | Current period usage |
|
|
| `payment_terms_days` | `integer` | e.g. 30 |
|
|
| `price_list_id` | `string` | Admin price list reference |
|
|
| `contract_start` | `date` | ISO date |
|
|
| `contract_end` | `date` | ISO date |
|
|
| `activated_at` | `Timestamp` | When Admin activated |
|
|
| `activated_by` | `string` | Admin user id |
|
|
|
|
### VerificationSettings
|
|
|
|
| Field | Type | Notes |
|
|
|-------|------|-------|
|
|
| `method` | `VerificationMethod` | See enum |
|
|
| `require_at_checkout` | `boolean` | Member must verify before Ecom checkout |
|
|
|
|
```
|
|
VerificationMethod = employee_id | qr_code | domain_email | manual_hr
|
|
```
|
|
|
|
### JoinRules
|
|
|
|
| Field | Type |
|
|
|-------|------|
|
|
| `join_code` | `string` \| null |
|
|
| `allowed_email_domains` | `string[]` |
|
|
| `join_code_expires_at` | `Timestamp` \| null |
|
|
|
|
## Validation rules
|
|
|
|
| Rule | Error code |
|
|
|------|------------|
|
|
| `legal_name` min 2 chars | `VALIDATION_FAILED` |
|
|
| `tin` unique platform-wide | `DUPLICATE_ORG` |
|
|
| `billing_contact.email` valid format | `INVALID_FORMAT` |
|
|
| `billing_contact.phone` E.164 | `INVALID_PHONE` |
|
|
| Commercial fields immutable from B2B | `FORBIDDEN` |
|
|
|
|
## Clinical withhold
|
|
|
|
Organisation entity has **no clinical fields**. HR and Finance may read `commercial.credit_*` and aggregates only.
|
|
|
|
## Sample payload (active org, HR view)
|
|
|
|
```json
|
|
{
|
|
"id": "org_01HQXYZ123456789",
|
|
"legal_name": "Acme Bank Ethiopia",
|
|
"display_name": "Acme Bank",
|
|
"tin": "0001234567",
|
|
"status": "active",
|
|
"billing_contact": {
|
|
"name": "Selam Bekele",
|
|
"email": "selam@acme.et",
|
|
"phone": "+251911234567"
|
|
},
|
|
"approx_headcount": 850,
|
|
"commercial": {
|
|
"credit_limit": { "amount": "5000000.00", "currency": "ETB" },
|
|
"credit_used": { "amount": "1245000.00", "currency": "ETB" },
|
|
"payment_terms_days": 30,
|
|
"price_list_id": "pl_corporate_2026",
|
|
"contract_start": "2026-01-01",
|
|
"contract_end": "2026-12-31",
|
|
"activated_at": "2025-12-15T10:00:00Z",
|
|
"activated_by": "adm_01H..."
|
|
},
|
|
"verification": {
|
|
"method": "employee_id",
|
|
"require_at_checkout": true
|
|
},
|
|
"dependant_limit": 4,
|
|
"join_rules": {
|
|
"join_code": "ACME-2026",
|
|
"allowed_email_domains": ["acme.et"],
|
|
"join_code_expires_at": null
|
|
},
|
|
"locale_default": "en",
|
|
"created_at": "2025-12-01T08:00:00Z",
|
|
"updated_at": "2026-02-01T12:00:00Z",
|
|
"version": 12
|
|
}
|
|
```
|
|
|
|
## Sample payload (pending org)
|
|
|
|
```json
|
|
{
|
|
"id": "org_01HPENDING123456",
|
|
"legal_name": "Beta NGO",
|
|
"tin": "0009876543",
|
|
"status": "pending_activation",
|
|
"billing_contact": { "name": "...", "email": "...", "phone": "+251..." },
|
|
"approx_headcount": 120,
|
|
"commercial": null,
|
|
"created_at": "2026-03-01T09:00:00Z",
|
|
"updated_at": "2026-03-01T09:00:00Z",
|
|
"version": 1
|
|
}
|
|
```
|
|
|
|
## Related endpoints
|
|
|
|
- [`../endpoints/org.md`](../endpoints/org.md)
|
|
|
|
## Events
|
|
|
|
- `org.registration_submitted`
|
|
- `org.activated` (Admin)
|