Organisation Domain Overview
High Level Domain
The Organisation Domain (Org) manages how companies (employers) interact with the Jod Platform. It answers three questions:
- Who uses Jod? →
Org::Company - Who can do what, and where? →
Org::Membership+Org::OutletAssignment - Where does the work happen? →
Org::Outlet
Fundamental Concepts
Company = Operational Entity
An Org::Company represents an organisation that actively uses the Jod Platform — it posts jobs, manages workers, and consumes credits.
It does not represent every legal entity in a commercial relationship. If Republic Iconic Hotel Pte Ltd pays invoices on behalf of Studio M Hotel Singapore, only Studio M is an Org::Company. Republic Iconic Hotel exists as a Billing::BillToProfile — a billing-domain concept.
The principle: model what you can keep true, not what would be nice to know. Jod can verify who uses the platform (they log in, they post jobs). Jod cannot verify who owns whom in the corporate world.
See Org::Company model spec for full details.
Enterprise Divisions
Large enterprise clients (e.g., NTUC Fairprice) have internal divisions that are not separate legal entities but need to operate independently on the platform. These are modeled as child Org::Company records under a root company:
NTUC Fairprice Co-Operative Limited (root — governance anchor)
├── NTUC Fairprice Supermarkets (South) ← child, operational
├── NTUC Fairprice (Finest) ← child, operational
└── ... more divisions
Each division has its own Billing::Account, users, outlets, and jobs. Simple companies (the majority) are just a root company with no children — the same model, different data.
See Org::Company — Enterprise Divisions for full details.
Membership = Access Grant
An Org::Membership links an Identities::User to an Org::Company with a specific role. It answers: "What can this user do at this company?"
One user can have memberships in multiple companies (e.g., an HR lead managing three hotels). They log in once and switch between companies from the UI.
Org::Membership replaces Org::UserProfile. On the talent side, Talent::Profile represents "who is this worker" (identity). On the employer side, Membership represents "what can this user access" (access grant). Different concerns, different models.
See Org::Membership model spec for full details.
Three Roles
| Role | Scope | Key Capabilities |
|---|---|---|
hq_manager | All outlets in the company | Full access: manage jobs, users, outlets, billing, credits |
area_manager | Assigned outlets only | Manage jobs and candidates at assigned outlets |
outlet_manager | Single assigned outlet | Manage jobs and candidates at their outlet |
Roles have fixed permissions — no per-company permission customization. The difference between area_manager and outlet_manager is scope (which outlets), not capabilities.
This was informed by analysis of the legacy system (JodGig): 277 permissions existed, but only 7 distinct permission sets across 315 companies. Per-company customization was built but barely used. See JodGig Org Statistics for the data.
Outlet = Where Work Happens
An Org::Outlet represents a physical branch, store, or site where a company operates. Each outlet belongs to one company and has its own address.
Outlets carry per-outlet settings (prefixed with is_setting_):
is_setting_job_approval_required— when enabled, gig jobs at this outlet must be approved before becoming visible to workers
See Org::Outlet model spec for full details.
Outlet Assignment = Scoping Mechanism
Org::OutletAssignment links a Membership to specific Outlets, determining which outlets a user can access:
hq_manager: no assignments needed — implicit access to all outletsarea_manager: assigned to 1 or more outletsoutlet_manager: assigned to exactly 1 outlet
This is a direct assignment, not a persistent group. There is no "area" or "zone" entity. If the company reorganizes, outlet assignments are updated directly.
See Org::OutletAssignment model spec for full details.
Invitation = Onboarding Flow
Org::Invite represents an invitation for someone to join a company. It carries the intended role and optional outlet assignments, so acceptance creates the right Membership and OutletAssignment records in one step.
See Org::Invite model spec for full details.
Domain Model Map
Models
| Model | Table | Purpose |
|---|---|---|
| Org::Company | org_companies | Organisation that uses the platform. Supports parent-child for enterprise divisions. |
| Org::Membership | org_memberships | User's access to a company: role, title, owner flag, default company. Renamed from Org::UserProfile. |
| Org::Outlet | org_outlets | Physical branch or store where work takes place. Carries per-outlet settings. |
| Org::OutletAssignment | org_outlet_assignments | Scopes a Membership to specific Outlets. Direct assignment, not persistent groups. |
| Org::Invite | org_invites | Invitation to join a company with a specified role. Renamed from Org::UserInvitation. |
How Org Connects to Other Domains
| Domain | Connection | Details |
|---|---|---|
| Billing | Org::Company → Billing::Account (1:1) | Every company has a billing account. Credits, invoices, and agreements live in the Billing domain. |
| Billing | Billing::BillToProfile on Account | The entity on invoices may differ from the Org::Company. BillToProfile handles this. |
| Careers | Org::Company → Careers::Job | Companies post full-time and part-time job listings. |
| Gig | Org::Company → Gig::TempJob | Companies post temporary gig jobs. Jobs reference an Org::Outlet for where the work happens. |
| Gig | Org::Outlet → Gig::Job | Each gig job happens at a specific outlet. Outlet determines pay rates and job approval requirements. |
| Identities | Identities::User → Org::Membership | Authentication is in the Identities domain. Org only knows users through Memberships. |
| Geo | Org::Company → Geo::Country, Geo::Area | Country of registration and office location. |
Design Decisions Log
Key architectural decisions made during the Org domain design, with references to supporting data:
| Decision | Rationale | Reference |
|---|---|---|
Org::Company = operational entity, not legal entity | Only model companies that use Jod. Billing identity handled by Billing::BillToProfile. Corporate structures are graphs; Org supports only trees. | Org::Company — Key Concepts |
Enterprise divisions are child Org::Company records | Each division needs its own billing account, users, outlets, jobs. Shares parent's registration number. | Org::Company — Enterprise Divisions |
registration_no partial unique index (root only) | Divisions share parent's UEN. 13% of companies share registration numbers. | JodGig Stats — Company Structure |
| Three fixed roles, no per-company customization | Only 7 distinct permission sets across 315 companies. Area and Location have nearly identical permissions (98 vs 96). | JodGig Stats — Permissions |
Org::Membership replaces Org::UserProfile | Employer side is about access (membership), not identity (profile). Supports multi-company access. | Org::Membership — Purpose |
| Direct outlet assignment, not persistent groups | No "area" entity. AREA managers in JodGig managed 1–10 outlets via direct assignment. No formal groups existed. | JodGig Stats — AREA Manager Scoping |
| Job approval is an outlet setting, not a role | AM_JOB_APPROVAL used by only 3 companies. The Robertson House is 96.4% of usage. It is a per-location flag in the legacy system. | JodGig Stats — Job Approval |
| Owner is a flag, not a role | No role above hq_manager needed. Owner flag protects against accidental removal. | Org::Membership — Ownership |
| Outlet-level credit allocation is a billing checkpoint | 75% of recent job volume flows through outlet-level deduction. Decision deferred to billing design phase. | Billing — Outlet-Level Entitlement Balance |