WORKFORCEOS
FRONTEND GUIDE FOR AI CODING AGENTS - PART 1 - Project Introduction & Setup
This is the introductory document for the workforceos frontend project. It is designed for AI agents that will generate frontend code to consume the project’s backend. Read it carefully — it describes the project scope, architecture, API conventions, and initial screens you must build before proceeding to the feature-specific prompts that follow.
This prompt will help you set up the project infrastructure, create the initial layout, home page, navigation, and any dummy screens. The subsequent prompts will provide detailed API documentation for each feature area.
Project Introduction
WorkforceOS is a unified, web-based platform that enables businesses to efficiently manage employees, schedules, attendance, tasks, and workforce operations with full company-level data isolation. Designed for multi-role access, internal departments, AI-driven insights, and integrated communication via email and in-app notifications.
Project Services Overview
The project has 1 auth service, 1 notification service, 1 BFF service, and 10 business services, plus other helper services such as bucket and realtime.
Each service is a separate microservice application and listens for HTTP requests at different service URLs.
| # | Service | Description | API Prefix |
|---|---|---|---|
| 1 | auth | Authentication and user management | /auth-api |
| 2 | employeeProfile | Manages extended employee profile data, employment/tax details, and employee-rel… | /employeeProfile-api |
| 3 | scheduleManagement | Microservice managing shift scheduling, shift templates, assignment of users/dep… | /scheduleManagement-api |
| 4 | attendanceManagement | Handles employee attendance logging (check-in/out), attendance rules (lateness/a… | /attendanceManagement-api |
| 5 | taskManagement | Handles creation, assignment, update, and tracking of tasks tied to employees, s… | /taskManagement-api |
| 6 | leaveManagement | Handles employee leave/absence requests, review/approval workflows, and automati… | /leaveManagement-api |
| 7 | payrollReporting | Handles payroll report records for employees based on calculated hours, overtime… | /payrollReporting-api |
| 8 | announcementManagement | Handles company-wide and department-specific announcements, supporting scheduled… | /announcementManagement-api |
| 9 | aiWorkforceAnalytics | Microservice for computing and delivering AI-powered workforce analytics (e.g., … | /aiWorkforceAnalytics-api |
| 10 | subscriptionManagement | Manages company AI subscriptions through Stripe payments. Companies must pay via… | /subscriptionManagement-api |
| 11 | agentHub | AI Agent Hub | /agentHub-api |
Detailed API documentation for each service will be given in the following prompts. In this document, you will build the initial project structure, home pages, and navigation.
API Structure
Object Structure of a Successful Response
When the service processes requests successfully, it wraps the requested resource(s) within a JSON envelope. This envelope includes the data and essential metadata such as configuration details and pagination information, providing context to the client.
HTTP Status Codes:
- 200 OK: Returned for successful GET, LIST, UPDATE, or DELETE operations, indicating that the request was processed successfully.
- 201 Created: Returned for CREATE operations, indicating that the resource was created successfully.
Success Response Format:
For successful operations, the response includes a "status": "OK" property, signaling that the request executed successfully. The structure of a successful response is outlined below:
{
"status":"OK",
"statusCode": 200,
"elapsedMs":126,
"ssoTime":120,
"source": "db",
"cacheKey": "hexCode",
"userId": "ID",
"sessionId": "ID",
"requestId": "ID",
"dataName":"products",
"method":"GET",
"action":"list",
"appVersion":"Version",
"rowCount":3,
"products":[{},{},{}],
"paging": {
"pageNumber":1,
"pageRowCount":25,
"totalRowCount":3,
"pageCount":1
},
"filters": [],
"uiPermissions": []
}
products: In this example, this key contains the actual response content, which may be a single object or an array of objects depending on the operation.
Additional Data
Each API may include additional data besides the main data object, depending on the business logic of the API. These will be provided in each API’s response signature.
Error Response
If a request encounters an issue—whether due to a logical fault or a technical problem—the service responds with a standardized JSON error structure. The HTTP status code indicates the nature of the error, using commonly recognized codes for clarity:
- 400 Bad Request: The request was improperly formatted or contained invalid parameters.
- 401 Unauthorized: The request lacked a valid authentication token; login is required.
- 403 Forbidden: The current token does not grant access to the requested resource.
- 404 Not Found: The requested resource was not found on the server.
- 500 Internal Server Error: The server encountered an unexpected condition.
Each error response is structured to provide meaningful insight into the problem, assisting in efficient diagnosis and resolution.
{
"result": "ERR",
"status": 400,
"message": "errMsg_organizationIdisNotAValidID",
"errCode": 400,
"date": "2024-03-19T12:13:54.124Z",
"detail": "String"
}
Accessing the Backend Using Rest API
Each backend service has its own URL for each deployment environment. Users may want to test the frontend in one of the three deployments—preview, staging, or production. Please ensure that the home page includes a deployment server selection option so that, as the frontend coding agent, you can set the base URL for all services.
The base URL of the application in each environment is as follows:
- Preview:
https://workforceos.prw.mindbricks.com - Staging:
https://workforceos-stage.mindbricks.co - Production:
https://workforceos.mindbricks.co
For the auth service, the base URLs are:
- Preview:
https://workforceos.prw.mindbricks.com/auth-api - Staging:
https://workforceos-stage.mindbricks.co/auth-api - Production:
https://workforceos.mindbricks.co/auth-api
For each other service, append /{serviceName}-api to the environment base URL.
Any request that requires login must include a valid token in the Bearer authorization header.
Please note that for each service in the project (which will be introduced in following prompts) will use a different address so it is a good practice to define a separate client for each service in the frontend application lib source. Not only the different base urls, some services even may need different access rules when shaping the request.
Services may be deployed to the preview server, staging server, or production server. Therefore, each service has 3 access URLs. The frontend application must support all deployment environments during development, and the user should be able to select the target API server on the home page.
Multi-Tenancy Management
THIS APPLICATION IS MULTI-TENANT
This application is multi-tenant. Tenant data is isolated per company, and tenant-level records are attached to companyId.
For frontend, tenant context is resolved from frontend routing context (URL prefix in preview/test, subdomain in production) and then forwarded to backend through header.
Tenant Routing Contract (Required)
- SaaS pages:
/ - Tenant pages:
/{tenantCodename}/... - Example:
/babil/login - All tenant-specific pages must keep
/{tenantCodename}prefix.
In preview/test, URL prefix simulates tenant selection. In production, tenant is usually resolved from subdomain (e.g. babil.appname...).
In both modes, backend tenant targeting must always be done by header.
headers["mbx-company-codename"] = tenantCodenameFromUrl;
URL/subdomain is only a frontend tenant selection mechanism. Backend API calls must always claim tenant with header.
If no tenant codename is sent, backend assumes SaaS/root tenant (root).
Sample Company Tenant
The application backend also includes a sample tenant created with a sample tenant owner, who has the same email and password of the superadmin. This sample is created in the backend to be able to test the multi-tenant behaviour of the frontend at the beginning.
The sample company has codename babil. Use /babil/... prefixed pages and send mbx-company-codename: babil in tenant-scoped requests for testing.
Home Page
First build a home page which shows some static content about the application, and has got login and registration (if is public) buttons. The home page should be updated later according to the content that each service provides, as a frontend developer use best and common practices to reflect the service content to the home page. User may also give extra information for the home page content in addition to this prompt.
Note that this page should include a deployment (environment) selection option to set the base URL. Set the default to production.
After user logs in, page header should show the current login state as in modern web pages, logged in user fullname, avatar, email and with a logout link, make a fancy current user component. The home page may have different views before and after login.
Since this is a multi-tenant application, SaaS home and tenant home should be different.
SaaS Home (/)
Build a landing page with:
- Left area: project full name and project description
- Two primary buttons:
- Login To SaaS (root tenant login entry)
- Register New Company (show only when tenant owner registration is public)
- Bottom small link: See Companies
When user clicks See Companies, open a left sliding drawer and fetch tenant list with listBriefCompanies.
Clicking a tenant should navigate to /{tenantCodename} tenant homepage.
Tenant Home (/{tenantCodename})
Create a simple tenant homepage that shows tenant name/fullname/avatar and includes:
- Login button
- Register button only when tenant-user registration is public
Tenant homepage data should be fetched with tenant-level public API getCompanyHome while sending mbx-company-codename from URL context.
All tenant pages should keep tenant context in frontend routing. Regardless of routing method, all backend calls from tenant context must include mbx-company-codename header.
Tenant API Contract (Current)
Use the following auth APIs for tenant information access:
- Public brief list for landing/tenant selection:
listBriefCompanies - Public brief single tenant:
getBriefCompany(/briefcompanies/:codename) - Public tenant-home read in tenant scope:
getCompanyHome(/companyhome/:codename) - Logged-in tenant-level read:
getCompany(/companies, tenant id resolved from tenant context/session) - Tenant profile read for tenant managers:
getCompanyProfile(/companyprofile, id resolved from tenant header/session) - SaaS-level tenant account read/list:
getCompanyAccountandlistCompaniesAccounts
List Briefcompanies API
Get a list of companies, this route can be called by public, no login required
Rest Route
The listBriefCompanies API REST controller can be triggered via the following route:
/v1/briefcompanies
Rest Request Parameters
The listBriefCompanies api has got no request parameters.
REST Request To access the api you can use the REST controller with the path GET /v1/briefcompanies
axios({
method: 'GET',
url: '/v1/briefcompanies',
data: {
},
params: {
}
});
REST Response
This route’s response is constrained to a select list of properties, and therefore does not encompass all attributes of the resource.
{
"status": "OK",
"statusCode": "200",
"elapsedMs": 126,
"ssoTime": 120,
"source": "db",
"cacheKey": "hexCode",
"userId": "ID",
"sessionId": "ID",
"requestId": "ID",
"dataName": "companies",
"method": "GET",
"action": "list",
"appVersion": "Version",
"rowCount": "\"Number\"",
"companies": [
{
"isActive": true
},
{},
{}
],
"paging": {
"pageNumber": "Number",
"pageRowCount": "NUmber",
"totalRowCount": "Number",
"pageCount": "Number"
},
"filters": [],
"uiPermissions": []
}
Get Companyhome API
Get public tenant-home information in tenant level.
Rest Route
The getCompanyHome API REST controller can be triggered via the following route:
/v1/companyhome/:codename
Rest Request Parameters
The getCompanyHome api has got 1 regular request parameter
| Parameter | Type | Required | Population |
|---|---|---|---|
| codename | String | true | request.params?.[“codename”] |
| codename : The codename of the company to fetch |
REST Request To access the api you can use the REST controller with the path GET /v1/companyhome/:codename
axios({
method: 'GET',
url: `/v1/companyhome/${codename}`,
data: {
},
params: {
}
});
REST Response
This route’s response is constrained to a select list of properties, and therefore does not encompass all attributes of the resource.
{
"status": "OK",
"statusCode": "200",
"elapsedMs": 126,
"ssoTime": 120,
"source": "db",
"cacheKey": "hexCode",
"userId": "ID",
"sessionId": "ID",
"requestId": "ID",
"dataName": "company",
"method": "GET",
"action": "get",
"appVersion": "Version",
"rowCount": 1,
"company": {
"isActive": true
}
}
Get Company API
Get a company in current tenant scope. A protected tenant-level route for logged-in users.
Rest Route
The getCompany API REST controller can be triggered via the following route:
/v1/companies
Rest Request Parameters
The getCompany api has got no request parameters.
REST Request To access the api you can use the REST controller with the path GET /v1/companies
axios({
method: 'GET',
url: '/v1/companies',
data: {
},
params: {
}
});
REST Response
{
"status": "OK",
"statusCode": "200",
"elapsedMs": 126,
"ssoTime": 120,
"source": "db",
"cacheKey": "hexCode",
"userId": "ID",
"sessionId": "ID",
"requestId": "ID",
"dataName": "company",
"method": "GET",
"action": "get",
"appVersion": "Version",
"rowCount": 1,
"company": {
"id": "ID",
"name": "String",
"codename": "String",
"fullname": "String",
"avatar": "String",
"ownerId": "ID",
"industry": "String",
"companySize": "String",
"isActive": true,
"recordVersion": "Integer",
"createdAt": "Date",
"updatedAt": "Date",
"_owner": "ID"
}
}
Get Companyprofile API
Get tenant profile information in tenant level. A private route for tenantOwner and tenantAdmin.
Rest Route
The getCompanyProfile API REST controller can be triggered via the following route:
/v1/companyprofile
Rest Request Parameters
The getCompanyProfile api has got no request parameters.
REST Request To access the api you can use the REST controller with the path GET /v1/companyprofile
axios({
method: 'GET',
url: '/v1/companyprofile',
data: {
},
params: {
}
});
REST Response
{
"status": "OK",
"statusCode": "200",
"elapsedMs": 126,
"ssoTime": 120,
"source": "db",
"cacheKey": "hexCode",
"userId": "ID",
"sessionId": "ID",
"requestId": "ID",
"dataName": "company",
"method": "GET",
"action": "get",
"appVersion": "Version",
"rowCount": 1,
"company": {
"id": "ID",
"name": "String",
"codename": "String",
"fullname": "String",
"avatar": "String",
"ownerId": "ID",
"industry": "String",
"companySize": "String",
"isActive": true,
"recordVersion": "Integer",
"createdAt": "Date",
"updatedAt": "Date",
"_owner": "ID"
}
}
Get Companyaccount API
Get tenant account information by id. A private SaaS-level route for superAdmin, saasAdmin and saasUser.
Rest Route
The getCompanyAccount API REST controller can be triggered via the following route:
/v1/companyaccounts/:companyId
Rest Request Parameters
The getCompanyAccount api has got 1 regular request parameter
| Parameter | Type | Required | Population |
|---|---|---|---|
| companyId | ID | true | request.params?.[“companyId”] |
| companyId : The id of the company account to fetch |
REST Request To access the api you can use the REST controller with the path GET /v1/companyaccounts/:companyId
axios({
method: 'GET',
url: `/v1/companyaccounts/${companyId}`,
data: {
},
params: {
}
});
REST Response
{
"status": "OK",
"statusCode": "200",
"elapsedMs": 126,
"ssoTime": 120,
"source": "db",
"cacheKey": "hexCode",
"userId": "ID",
"sessionId": "ID",
"requestId": "ID",
"dataName": "company",
"method": "GET",
"action": "get",
"appVersion": "Version",
"rowCount": 1,
"company": {
"id": "ID",
"name": "String",
"codename": "String",
"fullname": "String",
"avatar": "String",
"ownerId": "ID",
"industry": "String",
"companySize": "String",
"isActive": true,
"recordVersion": "Integer",
"createdAt": "Date",
"updatedAt": "Date",
"_owner": "ID"
}
}
List Companiesaccounts API
List tenant accounts in SaaS level for superAdmin, saasAdmin and saasUser.
Rest Route
The listCompaniesAccounts API REST controller can be triggered via the following route:
/v1/companyaccounts
Rest Request Parameters
Filter Parameters
The listCompaniesAccounts api supports 5 optional filter parameters for filtering list results:
name (String): A string value to represent one word name of the company
- Single (partial match, case-insensitive):
?name=<value> - Multiple:
?name=<value1>&name=<value2> - Null:
?name=null
codename (String): A string value to represent a unique code name for the company which is generated automatically using name
- Single (partial match, case-insensitive):
?codename=<value> - Multiple:
?codename=<value1>&codename=<value2> - Null:
?codename=null
fullname (String): A string value to represent the fullname of the company
- Single (partial match, case-insensitive):
?fullname=<value> - Multiple:
?fullname=<value1>&fullname=<value2> - Null:
?fullname=null
avatar (String): A string value represent the url of the company avatar. Keep null for random avatar.
- Single (partial match, case-insensitive):
?avatar=<value> - Multiple:
?avatar=<value1>&avatar=<value2> - Null:
?avatar=null
ownerId (ID): An ID value to represent the user id of company owner who created the tenant
- Single:
?ownerId=<value> - Multiple:
?ownerId=<value1>&ownerId=<value2> - Null:
?ownerId=null
REST Request To access the api you can use the REST controller with the path GET /v1/companyaccounts
axios({
method: 'GET',
url: '/v1/companyaccounts',
data: {
},
params: {
// Filter parameters (see Filter Parameters section above)
// name: '<value>' // Filter by name
// codename: '<value>' // Filter by codename
// fullname: '<value>' // Filter by fullname
// avatar: '<value>' // Filter by avatar
// ownerId: '<value>' // Filter by ownerId
}
});
REST Response
{
"status": "OK",
"statusCode": "200",
"elapsedMs": 126,
"ssoTime": 120,
"source": "db",
"cacheKey": "hexCode",
"userId": "ID",
"sessionId": "ID",
"requestId": "ID",
"dataName": "companies",
"method": "GET",
"action": "list",
"appVersion": "Version",
"rowCount": "\"Number\"",
"companies": [
{
"id": "ID",
"name": "String",
"codename": "String",
"fullname": "String",
"avatar": "String",
"ownerId": "ID",
"industry": "String",
"companySize": "String",
"isActive": true,
"recordVersion": "Integer",
"createdAt": "Date",
"updatedAt": "Date",
"_owner": "ID"
},
{},
{}
],
"paging": {
"pageNumber": "Number",
"pageRowCount": "NUmber",
"totalRowCount": "Number",
"pageCount": "Number"
},
"filters": [],
"uiPermissions": []
}
Do not use deprecated tenant APIs such as getCompanyByCodename or listRegisteredCompanies.
Initial Navigation Structure
Build the initial navigation/sidebar with placeholder pages for each area of the application. These will be implemented in detail by the subsequent prompts:
SaaS Level:
- Home / Landing
- Login (SaaS)
- Dashboard (after login)
Tenant Level (/{tenantCodename}/...):
- Tenant Home
- Login
- Register
- Verification
- Profile
- User Management (admin)
- EmployeeProfile Service Pages
- ScheduleManagement Service Pages
- AttendanceManagement Service Pages
- TaskManagement Service Pages
- LeaveManagement Service Pages
- PayrollReporting Service Pages
- AnnouncementManagement Service Pages
- AiWorkforceAnalytics Service Pages
- SubscriptionManagement Service Pages
- AgentHub Service Pages
Create these as placeholder/dummy pages with a title and “Coming soon” note. They will be filled in by the following prompts.
What To Build Now
With this prompt, build:
- Project infrastructure — routing (using
react-routerv7 — import fromreact-router, notreact-router-dom), layout, environment config, API client setup (one client per service) - Home page with environment selector, login/register buttons, project description
- SaaS landing and Tenant home pages with tenant selection drawer
- Placeholder pages for all navigation items listed above
- Common components — header with user info, navigation sidebar/menu, layout wrapper
Do not implement authentication flows, registration, or any service-specific features yet — those will be covered in the next prompts.
Common Reminders
- When the application starts, please ensure that the
baseUrlis set to the production server URL, and that the environment selector dropdown has the Production option selected by default. - Note that any API call to the application backend is based on a service base URL. Auth APIs use
/auth-apiprefix, and each business service uses/{serviceName}-apiprefix after the application’s base URL. - The deployment environment selector will only be used in the home page. If any page is called directly bypassing the home page, the page will use the stored or default environment.