org-prompt
I would like to explore, discuss and architect in detail my Org domain. Act as a Staff Software Architect that understands my design conventions, which is a flavour of DDD and bounded contexts (rails). You will advice me based on best software engineering practices
Interview me to extract domain concepts for Org, especially key nuances.
- don't make assumptions
- ask if something is not clear
You can also use mysql -uroot with the database jodgig_2026_clean to access the companies table which has the current companies listed.
- this will provide you an idea of the current live use-cases
- for example, there's many companies with "NTUC" in
jodgig-2026_clean.companies.name, however, they might ha
Keep your context clean. Always spin up a separate agent when:
- fetching data from mysql (e.g. Senior Data Engineer)
- editing doc files (e.g. Senior Technical Writer)
- searching existing codebases to understand current context (e.g. Senior Software Engineer)
The idea is to ensure you only know what you need to know without spending context on administrative matters.
- be explicit when you spin up a separate agent in your response so I know you are following instructions.
Overview
We are migrating the legacy php into a new rails api-only (backend) project called JodApp
- Frontend: React Router Framework Mode (project is @../jodapp-web)
- Database: Postgreql
Legacy Project Name: JodGig New Project: JodApp
JodApp Org domain was trivially designed, specifically for the careers domain (@../jodapp-api/app/domains/careers)
- started as a simple job posting website
- users can sign up, create an Org::Company and Org::UserProfile so they can log in.
- they can post jobs, receive applications and move the job applications through a pipeline (e.g. applied, shortlisted, accepted, cancelled)
The vision is to have an all-inclusive HR platform for the blue collar industry.
- employers can post full-time jobs
- employers can look for adhoc manpower based on their daily needs to supplement their full-time manpower
- employers can pay to post Ads on our website to promote their company landing page (@../jodapp-web/app/routes/companies/company-landing-page.jsx) or their job detail page (@../jodapp-web/app/routes/jobs/job-detail-page.jsx)
This way we can attract new clients easier since we provide all the solutions.
A future feature would be Workforce Management:
- manage shifts of full-time/part-time staff
- easily request for adhoc manpower from the shifts saved on the platform
- easily calculate and disburse payroll on hourly waged workers
Gig Domain
However now, we are brining in the Gig domain ( @docs/30-49-domains/35-gig/).
- legacy php project handles the adhoc manpower fulfilment platform, JodGig.
- Jodgig also has
companiestable
I'm worried that it would cause Org::Company get overloaded meaning, especially since we have established that we should not try to model the company hierarchy/structure in the real world.
In JodGig:
companiesrefer to the actual company using the JodGig platform
in JodApp:
Org::Companyalso refers to the actual company using the JodApp platform
Structuring Org::Companies
We have large enterprise companies like NTUC, which have different "business units", but they are not registered in ARCA (singpaore business registry).
- for example
NTUC Fairprice Co-operative Ltd Supermarkets (Central East)is not a registered company, butNTUC Fairprice Co-Operative Limitedis registered. - within Central East, they have many Org::Outlets (
jodgig_2026_clean.locations). - they would have a hq manager for each of the "business unit" (based on the area in singapore, Central East, East, North, etc.)
It was due to this specific client, we decided to introduce org_companies.parent_id, since we require the business registration number for each company.
Are there any software engineering patterns to handle this, while considering that we also need to ensure roles and permissions continue to work in a similar fashion? For example:
- location manager can only access a single outlet
- area manager can access multiple outlets
- hq manager can manage the entire company
Employer Roles & Permissions
You can read @docs/30-49-domains/33-org/notes/initial-user-permission-design.md which has our initial design and context of JodGig
In JodGig, we have various roles and permissions which I would like to try to avoid building in the users table
- spin up a separate agent to fetch the unique values of
jodgig_2026_clean.users.user_type - cross reference @../jodgig/ to see the limitations of these users
- This is really JUST for you to be able to understand currently the different roles.
- We are NOT going to just mimic the current design.
What I have in mind for a start is to allow all Org::UserProfile to be able to access everything about the company.
- however, when we actually make the switch from jodgig to jodapp, employers might not like it.
- to find the middle ground, i was thinking that we could consolidate the current
jodgig_2026_clean.users.user_typeinto simpler roles:- location_manager can only see within a single Org::Outlet
- area_manager can only see a subset of Org::Outlets
- hq_manager
You should also cross reference @../jodapp-api/app/domains/org/ code to determine the current use-cases that already have been implemented so you have a better idea.
::Org domain was created to group anything related to managing a company on the Jod platform.
- group related models like company, outlets and employer-type users via Org::UserProfile
Key Points
- We need to decide how to structure and design Org::Company, especially to handle company business units, PLUS how each Org::UserProfile would be linked to a specific company or business unit or parent_id
- We need to decide how to structure and design Org::UserProfile so that they can only access what they are allowed to within the company.
Interview Questions — Round 1
I have three clusters of questions. Let's start with the most fundamental one.
1. What is a "Business Unit" to Jod?
In JodGig, the NTUC problem was solved by creating separate company records for each regional division. This worked but created the "21 companies with the same UEN" situation.
In JodApp, you introduced parent_company_id to relate them. But I need to understand the real-world relationship:
Q1a: When NTUC Fairprice splits into "Supermarkets (Central)", "Supermarkets (East)", "Finest" — is this NTUC's own internal
structure that they asked you to mirror? Or was this a Jod ops decision to organize outlets into manageable groups?
Q1b: Do business units like "NTUC Fairprice Supermarkets (Central)" have their own budget/credits for hiring gig workers? Or
does the entire NTUC Fairprice share one credit pool and one billing relationship?
- yes, they manage their own budget/credits
- every company in JodGig has it's own credits.
- credits used by an outlet can be assigned to from the company credits.
- or the outlet can use the credits directly from the company credits.
Q1c: Looking at the data, some NTUC records are marked with (Old) or have status = 0 (inactive). It seems like business units
get restructured over time (Central splits into Central + Central East, regions merge). How often does this happen, and who initiates it — NTUC or Jod ops?
Yes, NTUC restructured, so we restructured how we represent them most likely due to the credit structure.
- every branch will request for invoice from JOD
- we will send them the invoice and they will forward it to their finance for approval and payment.
1. Outlet vs Business Unit — The Access Control Question
This is the question I need answered before I can recommend a model.
In JodGig, the hierarchy is effectively: Company (business unit) → Location → [AREA user manages N locations, LOCATION user manages 1]
Q2a: In your proposed role simplification (hq_manager, area_manager, location_manager), what does "area" mean? Is it:
- A geographic region (Central, East, North — like the NTUC business units)?
- A subset of outlets that an admin arbitrarily groups?
- Something else?
Q2b: Can an area_manager manage outlets that span across business units? For example, could one person manage outlets from both
"NTUC Supermarkets (Central)" and "NTUC Supermarkets (East)"?
Q2c: Is the hq_manager scoped to a single business unit (e.g., manages only "Supermarkets Central"), or does hq_manager manage
the entire legal entity (all NTUC Fairprice divisions)?
3. The Gig Integration Question
Q3a: When we migrate JodGig's 21 NTUC "companies" into JodApp, which entity should own the gig jobs and credit balances? The
legal entity (NTUC Fairprice Co-operative Limited)? Each business unit? Or each outlet?
This question directly impacts whether we need a BusinessUnit concept in the Org domain or whether Org::Company + Org::Outlet (with better role-based scoping) is sufficient.
Q4a: For the enterprise companies — who is the Jod customer? Is NTUC Fairprice Co-Operative Limited (the legal entity) the customer? Or is each division (Supermarkets Central, Finest, etc.) an independent customer that happens to share a UEN?
NTUC Fairprice Co-Operative Limited (legal entity) is the customer service agreement. However, they have various divisions which are based on areas in Singapore (e.g. Central East, North, South) or non-area based divisions like Hyper and Finest. In Xero, Finance would bill to "NTUC Fairprice Co-Operative Limited (Hyper)". This is to indicate that this division is paying for the invoice.
Q4b: You mentioned "every branch will request for invoice from JOD." Can you clarify — does "branch" here mean:
- The business unit (e.g., "Supermarkets Central" requests an invoice for all its outlets' gig usage)?
- Or individual outlets (e.g., "FairPrice Waterway Point" requests its own invoice)?'
"branch" refers to Org::Outlet. A physical location where the company conducts business. For example, NTUC Fairprice Co-Operative Limited (South) would have different outlets in the south of singapore. You can ask the Senior Data Engineer to show you the different jodgig_2026_clean.locations for the non-disabled NTUC Fairprice (South) company
Q5a: When NTUC restructures (e.g., "Supermarkets NE, NW, E, Central" splits into "Central", "East", "North", etc.), what happens
to:
-
Credits/balance — do they get transferred to the new BU? Split proportionally? Zeroed out?
-
Active jobs — do they stay under the old BU until completed, or get reassigned?
-
Users (managers) — do they move to the new BU?
-
Credits/balance: The restructuring already happened. It's really just a rename of the existing
companiesin the table, but Sales created newcompanies. They manually adjusted credits for the previous NTUC Fairprice companies, and assigned credits to the new ones that were created. -
Active jobs: Yes they stay in the old BU until completed
-
Users (managers) move to the new BU.
Q5b: Who initiates the restructuring — does NTUC tell Jod ops "we've reorganized, please update our structure"? Or does Jod ops decide?
- ntuc tells Jod
Interview Questions — Round 3 (Converging)
- The Division Identity
Your Q4a answer revealed something critical: in Xero, Finance bills to "NTUC Fairprice Co-Operative Limited (Hyper)". This means each division has a distinct billing label but shares the legal entity's UEN.
Q7a: Does each NTUC division have its own Billing::Account (own credit balance, own invoices, own entitlement history)? Or does the entire legal entity share one pool that gets allocated to divisions?
- yes, each NTUC division has their own Billing::Account.
- However, jod staff can move credits from one division to another depending on what was requested from NTUC Fairprice.
I'm asking because the current billing design has Billing::Account 1:1 with Org::Company. If each division needs its own credit balance, that constrains whether divisions can be Org::Company records or need to be something else.
Q7b: When a new simple company signs up (e.g., a cafe with 3 outlets), should they ever need to create "divisions"? Or is the division concept only relevant for enterprise clients that Jod ops onboards manually?
- no they don't have to.
- we should keep it simple cause these people are not really tech savvy.
- The Outlet Assignment Model
This is the last piece I need before I can recommend an architecture for roles.
In JodGig, AREA managers are assigned to specific locations via location.area_user_id. There's no formal "area group" — it's just "this user manages these locations."
Q8a: In the new system, when an AREA manager is assigned outlets, who does the assignment? The HQ manager? Jod ops/admin? Or does the AREA manager self-select?
- In the new system, for existing companies, we would need to assign the various area and locations appropriately when we migrate.
- For new companies that use the new system, ideally it would be a self-serve kinda thing, where the UI guides the users through what needs to be done. However, in the real life, im very sure that these companies would ask sales to assist them to set it up for them. It's kinda a Singaporean company expectation.
Q8b: When you said "a subset of outlets that an admin arbitrarily groups" — did you mean a persistent group (e.g., "South Zone" with 15 outlets assigned to it), or just a direct user-to-outlet assignment (e.g., "User X manages outlets A, B, C")?
- It's a direct user-to-outlet assignment.
- Let's assume it's a persistent group. If it was, then that would mean we would be trying to model the way the company organises their outlet in the real world, which might be over engineering at this point in time.
This distinction matters: a persistent group is a first-class entity. A direct assignment is a join table.
Q5: On the Membership rename — does Org::Membership feel right as a name? Or do you prefer keeping Org::UserProfile with the expanded semantics? The frontend currently shows "team members" — Membership aligns with "this user is a member of this company with this role."
- Yes the name Org::Membership feels right.
- One of the requirements would be to easily invite a user to a company provided an email address. When a company is created by the employer user, they would be the first Org::UserProfile set to that Org::Company. They would need allowances to invite users to join the Org::Company, and later assign them to outlets if required.
- Another requirement is that during the onboarding process, admins would also need to invite users to the Org::Company that the Admin created for the company.
- I'm not sure if we should have Org::Membership and Org::UserProfile split, or have it all in a single model. From my experience, having more tables might increase the design complexity, but it gives us more flexibility when new requirements come in the future. We also keep to the Single Responsibility principle.
- Then again, past 2 years we have not received feedback or complaints from employers regarding the whole membership thing.
- what's the industries best practice and if it's an overkill, how can we reduce complexity without having to
Q6: For the dropdown company switcher you described (user switches between companies in the UI) — should there be a concept of a default/primary membership? So when the user logs in, they land on their primary company's dashboard?
- yes we can add this.
Q7: Should we capture the job approval feature in the Org::Company model spec or the Org::Outlet model spec? It's fundamentally an outlet-level setting, but it affects the Gig job workflow.
we should set it on the outlet level. we cannot assume all outlets within a company has the same job approval process, just like how we cannot assume organisation structure when we were designing Org::Company (tree vs graph with the parent_id)