# API Documentation The Romanoff Fire Alarm Management System provides a RESTful API for programmatic access to all data. All API endpoints are prefixed with `/api`. ## Base URL ``` http://localhost:5000/api ``` ## Response Format All API responses are JSON. Successful responses return the requested data directly. Error responses include appropriate HTTP status codes. ## Endpoints ### Dashboard Statistics #### Get Dashboard Stats ``` GET /api/stats ``` Returns aggregated statistics for the dashboard. **Response** ```json { "total_jobs": 25, "total_budget": 1500000.00, "total_labor": 450000.00, "total_material": 350000.00, "avg_completion": 65.5, "completed_jobs": 8, "in_progress_jobs": 15, "not_started_jobs": 2, "vendor_budgets": { "Vendor A": 750000.00, "Vendor B": 500000.00, "Unknown": 250000.00 }, "pm_jobs": { "John Smith": { "count": 10, "budget": 600000.00 }, "Jane Doe": { "count": 8, "budget": 500000.00 } }, "jobs_completion": [ { "id": 1, "job_number": "JOB-001", "name": "Project Alpha", "completion": 75.0, "budget": 50000.00, "pm_assigned": "John Smith" } ] } ``` --- ### Jobs #### List All Jobs ``` GET /api/jobs ``` Returns a list of all jobs. **Response** ```json [ { "id": 1, "job_number": "JOB-001", "job_name": "Project Alpha", "location": "123 Main St, Raleigh, NC", "percent_complete": 0.75, "est_starting_qtr": "Q1 2025", "fire_alarm_budget": 50000.00, "labor_estimate": 20000.00, "material_estimate": 15000.00, "amount_left_on_contract": 15000.00, "pm_assigned": "John Smith", "aor": "Region A", "fire_vendor": "Vendor A", "install_partner": "Partner Inc", "ps_or_install": "Install", "subcontractor": "Sub Co", "pci": "Yes", "voip_or_phone": "VoIP", "plans": "Approved", "notes": "Project notes here", "issues": "No major issues", "milestone_1": "Permits obtained", "milestone_2": "Rough-in complete", "milestone_3": null, "milestone_4": null, "milestone_5": null, "milestone_6": null, "milestone_7": null, "elevator_final": "2025-03-15", "pretest": "2025-04-01", "final_date": "2025-04-15", "co_drop_dead_date": "2025-04-30", "number_of_units": 150, "sep_club_house": "Yes", "created_at": "2025-01-01T00:00:00", "updated_at": "2025-01-15T12:30:00" } ] ``` #### Get Single Job ``` GET /api/jobs/ ``` Returns a single job by ID. **Parameters** | Name | Type | Description | |------|------|-------------| | id | integer | Job ID (path parameter) | **Response** Returns a job object (same structure as list item above). **Errors** | Status | Description | |--------|-------------| | 404 | Job not found | #### Create Job ``` POST /api/jobs ``` Creates a new job. **Request Body** ```json { "job_number": "JOB-002", "job_name": "Project Beta", "location": "456 Oak Ave, Raleigh, NC", "percent_complete": 0, "est_starting_qtr": "Q2 2025", "fire_alarm_budget": 75000.00, "labor_estimate": 30000.00, "material_estimate": 25000.00, "amount_left_on_contract": 75000.00, "pm_assigned": "Jane Doe", "aor": "Region B", "fire_vendor": "Vendor B", "install_partner": "Partner Corp", "ps_or_install": "PS", "subcontractor": "Sub LLC", "pci": "No", "voip_or_phone": "Phone", "plans": "Pending", "notes": "New project", "issues": "", "milestone_1": "Site survey", "number_of_units": 200, "sep_club_house": "No", "elevator_final": "2025-06-15", "pretest": "2025-07-01", "final_date": "2025-07-15", "co_drop_dead_date": "2025-07-31" } ``` **Required Fields** | Field | Type | Description | |-------|------|-------------| | job_number | string | Unique job identifier | | job_name | string | Job name/title | **Optional Fields** | Field | Type | Description | |-------|------|-------------| | location | string | Job location address | | percent_complete | float | Completion percentage (0.0 - 1.0) | | est_starting_qtr | string | Estimated starting quarter | | fire_alarm_budget | float | Total fire alarm budget | | labor_estimate | float | Labor cost estimate | | material_estimate | float | Material cost estimate | | amount_left_on_contract | float | Remaining contract amount | | pm_assigned | string | Project manager name | | aor | string | Area of responsibility | | fire_vendor | string | Fire alarm vendor | | install_partner | string | Installation partner | | ps_or_install | string | PS or Install designation | | subcontractor | string | Subcontractor name | | pci | string | PCI status | | voip_or_phone | string | Communication type | | plans | string | Plans status | | notes | string | General notes | | issues | string | Known issues | | milestone_1 - milestone_7 | string | Project milestones | | elevator_final | date | Elevator final date (YYYY-MM-DD) | | pretest | date | Pretest date (YYYY-MM-DD) | | final_date | date | Final date (YYYY-MM-DD) | | co_drop_dead_date | date | CO drop dead date (YYYY-MM-DD) | | number_of_units | integer | Number of units | | sep_club_house | string | Separate club house indicator | **Response** Returns the created job object with status `201 Created`. #### Update Job ``` PUT /api/jobs/ ``` Updates an existing job. **Parameters** | Name | Type | Description | |------|------|-------------| | id | integer | Job ID (path parameter) | **Request Body** Include only the fields you want to update. Same fields as create. ```json { "percent_complete": 0.85, "notes": "Updated project notes" } ``` **Response** Returns the updated job object. **Errors** | Status | Description | |--------|-------------| | 404 | Job not found | #### Delete Job ``` DELETE /api/jobs/ ``` Deletes a job and all associated phases and materials. **Parameters** | Name | Type | Description | |------|------|-------------| | id | integer | Job ID (path parameter) | **Response** Returns `204 No Content` on success. **Errors** | Status | Description | |--------|-------------| | 404 | Job not found | --- ### Phases #### List Phases for Job ``` GET /api/jobs//phases ``` Returns all phases for a specific job. **Parameters** | Name | Type | Description | |------|------|-------------| | job_id | integer | Job ID (path parameter) | **Response** ```json [ { "id": 1, "job_id": 1, "phase_type": "rough_in", "phase_number": 1, "points": 500, "mobilization_date": "2025-02-01", "start_date": "2025-02-05", "due_date": "2025-02-28", "completion_date": "2025-02-25", "men_on_site": 5, "completed": true, "due_date_met": true, "pci_man_hours": 120.5, "rer_fire_mgmt_hours": 40.0, "rer_fire_mgmt_hours_avl": 50.0 } ] ``` #### Create Phase ``` POST /api/jobs//phases ``` Creates a new phase for a job. **Parameters** | Name | Type | Description | |------|------|-------------| | job_id | integer | Job ID (path parameter) | **Request Body** ```json { "phase_type": "trim", "phase_number": 2, "points": 300, "mobilization_date": "2025-03-01", "start_date": "2025-03-05", "due_date": "2025-03-31", "men_on_site": 4, "completed": false, "pci_man_hours": 0, "rer_fire_mgmt_hours": 0, "rer_fire_mgmt_hours_avl": 30.0 } ``` **Fields** | Field | Type | Description | |-------|------|-------------| | phase_type | string | Phase type: `rough_in`, `trim`, `commissioning`, `final`, `turnover` | | phase_number | integer | Phase sequence number | | points | integer | Points assigned to phase | | mobilization_date | date | Mobilization date (YYYY-MM-DD) | | start_date | date | Start date (YYYY-MM-DD) | | due_date | date | Due date (YYYY-MM-DD) | | completion_date | date | Completion date (YYYY-MM-DD) | | men_on_site | integer | Number of workers on site | | completed | boolean | Whether phase is complete | | due_date_met | boolean | Whether due date was met | | pci_man_hours | float | PCI man hours | | rer_fire_mgmt_hours | float | RER fire management hours | | rer_fire_mgmt_hours_avl | float | RER fire management hours available | **Response** Returns the created phase object with status `201 Created`. **Errors** | Status | Description | |--------|-------------| | 404 | Job not found | #### Update Phase ``` PUT /api/phases/ ``` Updates an existing phase. **Parameters** | Name | Type | Description | |------|------|-------------| | phase_id | integer | Phase ID (path parameter) | **Request Body** Include only the fields you want to update. ```json { "completed": true, "completion_date": "2025-03-28", "due_date_met": true } ``` **Response** Returns the updated phase object. **Errors** | Status | Description | |--------|-------------| | 404 | Phase not found | #### Delete Phase ``` DELETE /api/phases/ ``` Deletes a phase. **Parameters** | Name | Type | Description | |------|------|-------------| | phase_id | integer | Phase ID (path parameter) | **Response** Returns `204 No Content` on success. **Errors** | Status | Description | |--------|-------------| | 404 | Phase not found | --- ### Materials #### List All Materials ``` GET /api/materials ``` Returns all materials across all jobs. **Response** ```json [ { "id": 1, "job_id": 1, "part_number": "FA-SENSOR-001", "quantity": 50, "ordered": true, "received": true, "received_qty": 50, "received_by": "John Doe", "delivered_qty": 45, "delivered_to": "Site A - Building 1" } ] ``` #### List Materials for Job ``` GET /api/jobs//materials ``` Returns all materials for a specific job. **Parameters** | Name | Type | Description | |------|------|-------------| | job_id | integer | Job ID (path parameter) | **Response** Returns an array of material objects (same structure as above). #### Create Material ``` POST /api/jobs//materials ``` Creates a new material record for a job. **Parameters** | Name | Type | Description | |------|------|-------------| | job_id | integer | Job ID (path parameter) | **Request Body** ```json { "part_number": "FA-PANEL-002", "quantity": 10, "ordered": false, "received": false, "received_qty": 0, "received_by": "", "delivered_qty": 0, "delivered_to": "" } ``` **Fields** | Field | Type | Description | |-------|------|-------------| | part_number | string | Part/item number | | quantity | integer | Quantity needed | | ordered | boolean | Whether order has been placed | | received | boolean | Whether items have been received | | received_qty | integer | Quantity received | | received_by | string | Person who received items | | delivered_qty | integer | Quantity delivered to site | | delivered_to | string | Delivery location | **Response** Returns the created material object with status `201 Created`. **Errors** | Status | Description | |--------|-------------| | 404 | Job not found | #### Update Material ``` PUT /api/materials/ ``` Updates an existing material record. **Parameters** | Name | Type | Description | |------|------|-------------| | material_id | integer | Material ID (path parameter) | **Request Body** Include only the fields you want to update. ```json { "ordered": true, "received": true, "received_qty": 10, "received_by": "Jane Smith" } ``` **Response** Returns the updated material object. **Errors** | Status | Description | |--------|-------------| | 404 | Material not found | #### Delete Material ``` DELETE /api/materials/ ``` Deletes a material record. **Parameters** | Name | Type | Description | |------|------|-------------| | material_id | integer | Material ID (path parameter) | **Response** Returns `204 No Content` on success. **Errors** | Status | Description | |--------|-------------| | 404 | Material not found | --- ## Data Types ### Date Format All dates use ISO 8601 format: `YYYY-MM-DD` Examples: - `2025-01-15` - `2025-12-31` ### DateTime Format All timestamps use ISO 8601 format: `YYYY-MM-DDTHH:MM:SS` Examples: - `2025-01-15T14:30:00` - `2025-12-31T23:59:59` ### Phase Types Valid values for `phase_type`: - `rough_in` - Initial rough-in phase - `trim` - Trim phase - `commissioning` - System commissioning - `final` - Final inspection - `turnover` - Project turnover --- ## Error Handling The API uses standard HTTP status codes: | Status | Description | |--------|-------------| | 200 | Success | | 201 | Created | | 204 | No Content (successful deletion) | | 400 | Bad Request (invalid input) | | 404 | Not Found | | 500 | Internal Server Error | --- ## Examples ### cURL Examples **Get all jobs:** ```bash curl http://localhost:5000/api/jobs ``` **Create a job:** ```bash curl -X POST http://localhost:5000/api/jobs \ -H "Content-Type: application/json" \ -d '{"job_number": "JOB-003", "job_name": "New Project"}' ``` **Update a job:** ```bash curl -X PUT http://localhost:5000/api/jobs/1 \ -H "Content-Type: application/json" \ -d '{"percent_complete": 0.5}' ``` **Delete a job:** ```bash curl -X DELETE http://localhost:5000/api/jobs/1 ``` ### JavaScript Fetch Examples **Get all jobs:** ```javascript const response = await fetch('/api/jobs'); const jobs = await response.json(); ``` **Create a job:** ```javascript const response = await fetch('/api/jobs', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ job_number: 'JOB-003', job_name: 'New Project' }) }); const newJob = await response.json(); ``` **Update a job:** ```javascript const response = await fetch('/api/jobs/1', { method: 'PUT', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ percent_complete: 0.5 }) }); const updatedJob = await response.json(); ``` **Delete a job:** ```javascript await fetch('/api/jobs/1', { method: 'DELETE' }); ```