mem-dashboard / docs/api_endpoints.md
API Endpoints Documentation
MEM dashboard
API Endpoints Documentation
This document provides comprehensive documentation for the NocoDB API endpoints used by the MEM Dashboard frontend application.
Overview
The MEM Dashboard frontend connects to a NocoDB instance that exposes PostgreSQL database tables via REST API. NocoDB automatically creates API endpoints for each table in the database, eliminating the need for a custom backend API.
Base Configuration
Environment Variables
The following environment variables must be configured for API access:
VITE_API_BASE_URL='https://nocodb.mem.gov.om/api/v2/tables'
VITE_API_TOKEN='GW_ZXfUgOhV4LhcMdzwaPE_qt48MDpXKzcnCk4ab'
VITE_API_ENDPOINT_UNITS='/mwmtkgvc4uo7b4e/records'
VITE_API_ENDPOINT_UNITS_WORKFORCE='/mqgoz7qkhobtod3/records'
Authentication
All API requests require authentication via the xc-token header:
headers: {
"xc-token": "GW_ZXfUgOhV4LhcMdzwaPE_qt48MDpXKzcnCk4ab"
}
Base URL Structure
https://nocodb.mem.gov.om/api/v2/tables/{table_id}/records
Where {table_id} is the unique identifier assigned by NocoDB for each table.
API Endpoints
1. Units Endpoint
Retrieves drilling units data including rigs and hoists.
Endpoint: /mwmtkgvc4uo7b4e/records
Full URL: https://nocodb.mem.gov.om/api/v2/tables/mwmtkgvc4uo7b4e/records
Method: GET
Query Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
offset | number | 0 | Number of records to skip for pagination |
limit | number | 1000 | Maximum number of records to return |
where | string | - | Filter conditions (see Filtering section) |
Response Format
{
"list": [
{
"id": "string",
"operator_name": "string",
"contract_type": "string",
"unit_number": "string",
"block_number": "string",
"field_name": "string",
"contractor_name": "string",
"contractor_name_short": "string",
"contract_number": "string",
"total_workforce": "string",
"total_workforce_omani": "string",
"purpose": "Production" | "Exploration",
"contract_amount": number,
"planned_date": "YYYY-MM-DD",
"awarded_date": "YYYY-MM-DD",
"commencement_date": "YYYY-MM-DD",
"expiry_date": "YYYY-MM-DD",
"stacked_start_date": "YYYY-MM-DD",
"stacked_end_date": "YYYY-MM-DD",
"terminated_date": "YYYY-MM-DD",
"extension_duration_in_months": number
}
],
"pageInfo": {
"totalRows": number,
"page": number,
"pageSize": number,
"isFirstPage": boolean,
"isLastPage": boolean
}
}
Example Request
const response = await fetch('https://nocodb.mem.gov.om/api/v2/tables/mwmtkgvc4uo7b4e/records?offset=0&limit=1000', {
headers: {
"xc-token": "GW_ZXfUgOhV4LhcMdzwaPE_qt48MDpXKzcnCk4ab"
}
});
const data = await response.json();
Frontend Usage
The frontend uses this endpoint through the useFetchUnitsQuery hook:
// web/src/hooks/units/useFetchUnitsQuery.ts
const fetchUnits = async (): Promise<Unit[]> => {
const res = await callApi<{ list: Unit[] }>(
import.meta.env.VITE_API_ENDPOINT_UNITS,
{ offset: 0, limit: 1000 }
);
return res.list;
};
2. Units Workforce Endpoint
Retrieves workforce data associated with drilling units.
Endpoint: /mqgoz7qkhobtod3/records
Full URL: https://nocodb.mem.gov.om/api/v2/tables/mqgoz7qkhobtod3/records
Method: GET
Query Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
offset | number | 0 | Number of records to skip for pagination |
limit | number | 1000 | Maximum number of records to return |
where | string | - | Complex filter conditions for workforce data |
Response Format
{
"list": [
{
"operator_name": "string",
"contract_number": "string",
"company_name": "string",
"year_period": "string",
"skill_category_name": "string",
"skill_sub_category_name": "string",
"head_count": number,
"icv_sub_element": "Omani" | "Expat"
}
],
"pageInfo": {
"totalRows": number,
"page": number,
"pageSize": number,
"isFirstPage": boolean,
"isLastPage": boolean
}
}
Example Request with Filtering
const contractClause = "(contract_number,in,PDO-12345,OQ-67890)";
const contractorClause = "(company_name,in,Schlumberger,Halliburton)";
const whereClause = `${contractClause}~and${contractorClause}`;
const response = await fetch(`https://nocodb.mem.gov.om/api/v2/tables/mqgoz7qkhobtod3/records?offset=0&limit=1000&where=${whereClause}`, {
headers: {
"xc-token": "GW_ZXfUgOhV4LhcMdzwaPE_qt48MDpXKzcnCk4ab"
}
});
Frontend Usage
The frontend implements complex filtering and pagination for this endpoint:
// web/src/hooks/units/useFetchUnitsWorkforceQuery.ts
const fetchUnitsWorkforce = async (units: Unit[]): Promise<UnitWorkforce[]> => {
// Build complex where clause
const contractClause = `(contract_number,in,${units
.map((unit) => `${unit.operator_name}-${unit.contract_number}`)
.join(",")})`;
const contractorClause = `(company_name,in,${units
.map((unit) => unit.contractor_name)
.join(",")})`;
const whereClause = `${contractClause}~and${contractorClause}`;
// Handle pagination for large datasets
let offset = 0;
let allResults: UnitWorkforce[] = [];
while (true) {
const res = await callApi<{
list: UnitWorkforce[];
pageInfo: { isLastPage: boolean; };
}>(import.meta.env.VITE_API_ENDPOINT_UNITS_WORKFORCE, {
offset,
limit: 1000,
where: whereClause,
});
allResults = allResults.concat(res.list);
if (res.pageInfo.isLastPage) break;
offset += 1000;
}
return allResults;
};
Filtering and Query Syntax
NocoDB uses a specific syntax for filtering records in the where parameter.
Basic Operators
| Operator | Syntax | Example |
|---|---|---|
| Equal | (field,eq,value) | (operator_name,eq,PDO) |
| Not Equal | (field,neq,value) | (status,neq,terminated) |
| In | (field,in,value1,value2) | (contract_type,in,rig,hoist) |
| Like | (field,like,%value%) | (field_name,like,%north%) |
| Greater Than | (field,gt,value) | (contract_amount,gt,1000000) |
| Less Than | (field,lt,value) | (total_workforce,lt,100) |
Logical Operators
| Operator | Syntax | Example |
|---|---|---|
| AND | condition1~and~condition2 | (operator_name,eq,PDO)~and~(status,eq,active) |
| OR | condition1~or~condition2 | (contract_type,eq,rig)~or~(contract_type,eq,hoist) |
Complex Filter Example
// Filter for active PDO rigs with workforce > 50
const whereClause = "(operator_name,eq,PDO)~and~(contract_type,eq,rig)~and~(total_workforce,gt,50)";
Pagination
Implementation Pattern
Both endpoints support pagination through offset and limit parameters. The frontend implements automatic pagination handling:
let offset = 0;
const limit = 1000;
let allResults = [];
while (true) {
const response = await callApi(endpoint, { offset, limit, where });
allResults = allResults.concat(response.list);
if (response.pageInfo.isLastPage) break;
offset += limit;
}
Page Info Object
interface PageInfo {
totalRows: number; // Total number of records
page: number; // Current page number
pageSize: number; // Number of records per page
isFirstPage: boolean; // Whether this is the first page
isLastPage: boolean; // Whether this is the last page
}
Error Handling
Common HTTP Status Codes
| Status | Meaning | Action |
|---|---|---|
| 200 | Success | Process response data |
| 401 | Unauthorized | Check API token |
| 403 | Forbidden | Verify permissions |
| 404 | Not Found | Check endpoint URL |
| 500 | Server Error | Retry or contact admin |
Frontend Error Handling
export async function callApi<T>(
url: string,
params?: Record<string, string | number | boolean>,
): Promise<T> {
try {
const response = await instance.get(url, { params });
return response.data as T;
} catch (error) {
console.error("API call failed:", error);
throw error;
}
}
Data Types and Interfaces
Unit Interface
interface Unit {
id: string;
operator_name: string;
contract_type: string; // "rig" or "hoist"
unit_number: string;
block_number: string;
field_name: string;
contractor_name: string;
contractor_name_short: string;
contract_number: string;
total_workforce: string; // numeric string
total_workforce_omani: string; // numeric string
purpose: "Production" | "Exploration";
contract_amount?: number;
planned_date?: string; // YYYY-MM-DD
awarded_date?: string; // YYYY-MM-DD
commencement_date?: string; // YYYY-MM-DD
expiry_date?: string; // YYYY-MM-DD
stacked_start_date?: string; // YYYY-MM-DD
stacked_end_date?: string; // YYYY-MM-DD
terminated_date?: string; // YYYY-MM-DD
extension_duration_in_months?: number;
}
UnitWorkforce Interface
interface UnitWorkforce {
operator_name: string;
contract_number: string;
company_name: string;
year_period: string; // "YYYY-QX" format (e.g., "2024-Q4")
skill_category_name: string; // e.g., "Professional"
skill_sub_category_name: string; // e.g., "Driver - LV"
head_count: number;
icv_sub_element: "Omani" | "Expat";
}
Frontend Integration Examples
React Query Integration
The frontend uses React Query for data fetching and caching:
// Basic query hook
export const useFetchUnitsQuery = () => {
return useQuery({
queryKey: ["units"],
queryFn: fetchUnits,
});
};
// Usage in components
const { data: units, isLoading, error } = useFetchUnitsQuery();
Processing and Filtering
The frontend processes raw API data for display:
// Processing units with status calculation
const processedUnits = units?.map(unit => ({
...unit,
contractStatus: calculateStatus(unit),
coords: generateCoordinates(unit, blocks),
completionPercentage: calculateCompletion(unit)
}));
Development Notes
Environment Setup
- Ensure all
VITE_API_*environment variables are properly configured - NocoDB table IDs may change if database is recreated
- API token should be kept secure and not committed to version control
Performance Considerations
- Use pagination for large datasets (limit: 1000 recommended)
- Implement proper error handling and retry logic
- Cache responses using React Query for better performance
- Batch related API calls when possible
Security
- Never expose API tokens in client-side code in production
- Consider implementing API token rotation
- Use HTTPS for all API communications
- Validate and sanitize all user inputs before sending to API
Troubleshooting
Common Issues
- 401 Unauthorized: Check if
xc-tokenis correctly set - Empty Results: Verify table IDs in environment variables
- Timeout Errors: Reduce limit parameter or implement better pagination
- CORS Errors: Ensure NocoDB is configured to allow frontend domain
Debugging Tips
- Use browser network tab to inspect actual API requests
- Check console for detailed error messages
- Verify environment variables are loaded correctly
- Test API endpoints directly using tools like Postman or curl
Related Documentation
- System Design - Overall system architecture
- Unit States - Contract status definitions
- Frontend Structure - Code organization