HazCom Plan Builder — Implementation Plan
Overview
The HazCom Plan Builder enables companies to create OSHA-compliant Hazard Communication Plans (29 CFR 1910.1200) with two tiers: Basic (template-driven) and Premium (AI-powered). Implementation is complete across 5 phases.
Phase Summary
| Phase | Feature | Status |
|---|---|---|
| 1 | Basic Plan Builder (MVP) | Complete |
| 2 | Version Management & Audit Logging | Complete |
| 3 | AI Content Generation (SQS-Based) | Complete |
| 4 | PRO Auto-Setup Pipeline | Complete |
| 5 | Restructured Plan Builder | Complete |
Phase 1: Basic Plan Builder (MVP)
Database
- Tables:
plan_hazcom_plans,plan_hazcom_plan_sections,plan_hazcom_question_templates - Migrations managed via Alembic
- Question templates seeded for all 7 OSHA sections
Backend (tellus-ehs-hazcom-service)
- Models:
HazComPlan,HazComPlanSection,HazComQuestionTemplate - Repositories:
HazComPlanRepository,HazComPlanSectionRepository,HazComQuestionTemplateRepository - Service:
HazComPlanService— CRUD, questionnaire management, document preview, approval workflow - API Endpoints: Create, list, get, update, delete plans; get/update sections; preview; export
Frontend (tellus-ehs-hazcom-ui)
PlanEditorPage— Main editor with questionnaire, split, preview, and review modesQuestionnaireSection— Section questionnaire with all input typesDocumentPreview— Rendered HTML preview with table of contents- Client-side PDF generation via jsPDF
Phase 2: Version Management & Audit Logging
Database
- New table:
plan_hazcom_audit_logs(migration:2026_02_10_0001) - 16 action types across 5 categories (general, section, workflow, export, version)
Backend
- Service:
HazComAuditService— typed logging methods for each action - Repository:
HazComAuditLogRepository— paginated queries, filtering, CSV export - Permissions: Role-based approval (admin, coordinator, manager roles)
- Endpoints: Submit, approve, reject, publish, version history, audit logs, CSV export
Frontend
AuditLogViewer— Paginated log viewer with action/category filteringVersionHistory— Timeline view of plan versions per site- Status-aware UI (approve/reject buttons gated by plan status + user role)
Phase 3: AI Content Generation (SQS-Based)
Architecture
All AI operations use async SQS dispatch + frontend polling:
Frontend → API (dispatch to SQS) → Background Service (Claude AI) → DB
Frontend ← API (poll status) ←────────────────────────────────────────
Backend
POST /{plan_id}/ai/context— Gathers company, site, chemical, SDS contextPOST /{plan_id}/ai/generate/{section_code}— Generate one section (SQS)POST /{plan_id}/ai/generate-all— Generate all 7 sections (SQS)POST /{plan_id}/ai/prefill— Prefill questionnaire answers (SQS)GET /{plan_id}/ai/status— Poll task status + retrieve results
Background Service (tellus-ehs-background-service)
handle_hazcom_ai_generate()— Generates markdown content per section using Claude AI with structured OSHA promptshandle_hazcom_ai_prefill()— Generates suggested answers stored incontent_metadata['prefill_data']- Task status:
pending → processing → completed / failed
Frontend
- Async polling every 20 seconds via
getHazComAITaskStatus() - AI suggestions displayed inline with accept/dismiss per question
- AI contribution summary (assisted answers count, generated sections count)
- Confidence scoring per section
Phase 4: PRO Auto-Setup Pipeline
Flow
Premium plan creation triggers a multi-phase background pipeline:
- Phase 1: Gather company profile, site info, subscription tier
- Phase 2: Fetch chemical inventory with SDS data, hazard classifications
- Phase 3: Build enriched context (
_build_pro_enriched_context()) - Phase 4: Generate dynamic questions tailored to chemical inventory
- Phase 5: Generate AI-suggested answers for static + dynamic questions
Backend
- Plan creation detects premium tier → dispatches
hazcom_pro_plan_setupSQS message - Status:
pending → processing → questions_ready - Dynamic questions stored in
content_metadata['dynamic_questions'] - Prefill answers stored in
content_metadata['prefill_data']
Background Service
- Handler:
handle_hazcom_pro_plan_setup() - Helper functions:
_build_pro_enriched_context(),_get_pro_section_system_prompt(),_build_pro_content_prompt()
Frontend
ProPlanSetupProgress— Animated progress overlay with phase-cycling animation- Auto-transitions to questionnaire when
questions_readyreceived
Phase 5: Restructured Plan Builder
Merged Questions
get_questionnaire()returns both static template questions (ai_generated=False) and dynamic questions fromcontent_metadata['dynamic_questions'](ai_generated=True)- Completion calculation includes both static required + dynamic required questions
Generate Plan Endpoint
POST /{plan_id}/generate:
- Basic: Synchronous
generate_plan_from_templates()→ returnsDocumentPreviewResponse - Premium: Dispatches
hazcom_ai_generateto SQS with enriched PRO context → returnsAITaskDispatchResponse
Editing Permissions
Only draft status allows editing. Enforced on:
PUT /{plan_id}/sections/{section_code}(answers)PUT /{plan_id}/sections/{section_code}/content(markdown)PUT /{plan_id}(metadata)POST /{plan_id}/generate
Create New Version
POST /{plan_id}/new-version:
- Creates new draft from existing plan
- Copies sections, answers, content, metadata
- Increments version number; original unchanged
Frontend
- Generate Plan button: Visible at 100% completion, green FileText icon
- Progress overlay: Emerald-themed animation during AI generation
- Split view: Markdown
<textarea>(left) + live HTML preview (right) - Auto-save: Debounced 500ms save via
updateHazComSectionContent() - Create New Version: Button on approved/active/archived plans
Button Flow
- Fill questionnaire (100% required)
- Generate Plan → content created
- Edit in split view (optional)
- Submit for Approval (visible after content generated)
- Approve → Publish
- Create New Version for future changes
Complete API Endpoints
All under /api/v1/hazcom/plans:
| Method | Path | Phase |
|---|---|---|
| POST | `` | 1 |
| GET | `` | 1 |
| GET | /{plan_id} | 1 |
| PUT | /{plan_id} | 1 |
| DELETE | /{plan_id} | 1 |
| GET | /{plan_id}/questionnaire | 1 |
| GET | /{plan_id}/sections/{section_code} | 1 |
| PUT | /{plan_id}/sections/{section_code} | 1 |
| PUT | /{plan_id}/sections/{section_code}/content | 1 |
| GET | /{plan_id}/preview | 1 |
| POST | /{plan_id}/export | 1 |
| GET | /approvers | 2 |
| POST | /{plan_id}/submit-for-approval | 2 |
| POST | /{plan_id}/approve | 2 |
| POST | /{plan_id}/reject | 2 |
| POST | /{plan_id}/publish | 2 |
| GET | /site/{site_id}/versions | 2 |
| GET | /company/audit-logs | 2 |
| GET | /company/audit-logs/export | 2 |
| GET | /{plan_id}/audit-logs | 2 |
| POST | /{plan_id}/ai/context | 3 |
| POST | /{plan_id}/ai/generate/{section_code} | 3 |
| POST | /{plan_id}/ai/generate-all | 3 |
| POST | /{plan_id}/ai/prefill | 3 |
| GET | /{plan_id}/ai/status | 3 |
| POST | /{plan_id}/generate | 5 |
| POST | /{plan_id}/new-version | 5 |
SQS Message Handlers
| Message Type | Handler | Description |
|---|---|---|
hazcom_ai_generate | handle_hazcom_ai_generate() | Generate content for one or all sections |
hazcom_ai_prefill | handle_hazcom_ai_prefill() | Generate suggested answers for questions |
hazcom_pro_plan_setup | handle_hazcom_pro_plan_setup() | Multi-phase PRO plan background setup |
Frontend API Functions
All in tellus-ehs-hazcom-ui/src/services/api/hazcom-plan.api.ts:
| Function | Description |
|---|---|
createHazComPlan | Create a new plan |
listHazComPlans | List plans for company |
getHazComPlan | Get plan details |
updateHazComPlan | Update plan metadata |
deleteHazComPlan | Delete plan |
getHazComQuestionnaire | Get questionnaire with answers |
getHazComSection | Get section details |
updateHazComSection | Update section answers |
updateHazComSectionContent | Update section markdown content |
getHazComDocumentPreview | Get document preview |
exportHazComDocument | Export as PDF |
getHazComApprovers | List available approvers |
submitHazComPlanForApproval | Submit for approval |
approveHazComPlan | Approve plan |
rejectHazComPlan | Reject plan with reason |
publishHazComPlan | Publish plan |
getHazComAIContext | Load AI context |
generateHazComSection | Generate one section (SQS) |
generateAllHazComSections | Generate all sections (SQS) |
prefillHazComQuestionnaire | Prefill answers (SQS) |
getHazComAITaskStatus | Poll task status |
generateHazComPlan | Generate plan from answers |
createNewVersion | Create new draft version |
Key Files
Backend
app/api/v1/hazcom/plans.py— All API endpointsapp/services/hazcom/hazcom_plan_service.py— Core business logicapp/services/hazcom/hazcom_audit_service.py— Audit loggingapp/db/models/hazcom_plan.py— SQLAlchemy modelsapp/schemas/hazcom/hazcom_plan.py— Pydantic schemasapp/db/repositories/hazcom/hazcom_plan_repository.py— Data access
Background Service
app/services/sqs_consumer/handlers.py— AI generate, prefill, PRO setup handlers
Frontend
src/pages/plan/builder/hazcom/PlanEditorPage.tsx— Main plan editorsrc/pages/plan/builder/hazcom/components/QuestionnaireSection.tsx— Section questionnairesrc/pages/plan/builder/hazcom/components/DocumentPreview.tsx— Preview renderersrc/pages/plan/builder/hazcom/components/ProPlanSetupProgress.tsx— PRO setup overlaysrc/pages/plan/builder/hazcom/components/AuditLogViewer.tsx— Audit log viewersrc/pages/plan/builder/hazcom/components/VersionHistory.tsx— Version historysrc/services/api/hazcom-plan.api.ts— API functions