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/entities/organisation.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

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)