Permit-to-Work Workflow Engine (Phase 5)
Overview
The Permit-to-Work Workflow Engine provides a comprehensive system for managing work permits with request, approval, document management, and closure workflows. This system is designed for Safety Officers and Admins to ensure proper authorization and documentation for hazardous work activities.
Features
- Permit Request: Workers can request permits for various types of work
- Approval Workflow: Safety Officers and Admins can approve permit requests
- Document Management: Attach safety plans, risk assessments, certificates, and other documents
- Status Tracking: Track permit status from requested → approved → active → closed
- Zone Integration: Link permits to warehouse zones for location tracking
- Multi-Type Support: Support for hot work, electrical work, confined spaces, chemical work, excavation, height work, lockout/tagout, and other permit types
Database Schema
permits Table
CREATE TABLE public.permits (
id uuid PRIMARY KEY,
tenant_id uuid NOT NULL,
permit_type text NOT NULL CHECK (permit_type IN (
'hot_work', 'electrical_work', 'confined_space', 'chemical_work',
'excavation', 'height_work', 'lockout_tagout', 'other'
)),
requested_by uuid NOT NULL,
approved_by uuid,
status text NOT NULL DEFAULT 'requested' CHECK (status IN (
'requested', 'approved', 'active', 'closed', 'rejected', 'cancelled'
)),
zone_id uuid,
location text,
title text NOT NULL,
description text,
starts_at timestamp with time zone NOT NULL,
ends_at timestamp with time zone NOT NULL,
closed_at timestamp with time zone,
closed_by uuid,
rejection_reason text,
created_at timestamp with time zone DEFAULT now(),
updated_at timestamp with time zone DEFAULT now()
);permit_documents Table
CREATE TABLE public.permit_documents (
id uuid PRIMARY KEY,
permit_id uuid NOT NULL REFERENCES public.permits(id) ON DELETE CASCADE,
file_url text NOT NULL,
file_name text,
file_type text,
file_size integer,
uploaded_by uuid NOT NULL,
created_at timestamp with time zone DEFAULT now()
);Workflow States
- Requested: Initial state when a permit is created
- Approved: Permit has been approved by Safety Officer or Admin
- Active: Work has started (permit is in use)
- Closed: Work is completed and permit is closed
- Rejected: Permit request was rejected
- Cancelled: Permit was cancelled before completion
User Roles & Permissions
Workers
- Can request permits
- Can view their own permits
- Can upload documents to their permits
Safety Officers
- Full access to all permits within their tenant
- Can approve/reject permit requests
- Can activate permits
- Can close permits
- Can upload documents to any permit
Admins
- Full access to all permits
- Same permissions as Safety Officers
React Query Hooks
usePermits(filters?)
Fetch all permits with optional filters:
const { data: permits, isLoading } = usePermits({
status: 'requested',
permitType: 'hot_work',
requestedBy: userId
});usePermit(permitId)
Fetch a single permit by ID:
const { data: permit } = usePermit(permitId);usePermitWithDocuments(permitId)
Fetch a permit with all attached documents:
const { data: permit } = usePermitWithDocuments(permitId);
// permit.documents contains array of PermitDocumentuseActivePermits()
Fetch all active permits (approved or active status, not expired):
const { data: activePermits } = useActivePermits();useCreatePermit()
Create a new permit request:
const createPermit = useCreatePermit();
await createPermit.mutateAsync({
permit_type: 'hot_work',
title: 'Welding work in Hall 3',
description: 'Welding of support beams',
zone_id: zoneId,
location: null,
starts_at: '2025-02-10T08:00:00Z',
ends_at: '2025-02-10T17:00:00Z',
requested_by: userId,
status: 'requested'
});useApprovePermit()
Approve a permit request:
const approvePermit = useApprovePermit();
await approvePermit.mutateAsync(permitId);useActivatePermit()
Activate an approved permit (start work):
const activatePermit = useActivatePermit();
await activatePermit.mutateAsync(permitId);useClosePermit()
Close an active or approved permit:
const closePermit = useClosePermit();
await closePermit.mutateAsync(permitId);useUploadPermitDocument()
Upload a document to a permit:
const uploadDocument = useUploadPermitDocument();
await uploadDocument.mutateAsync({
permit_id: permitId,
file_url: fileUrl,
file_name: 'safety-plan.pdf',
file_type: 'application/pdf',
file_size: 1024000
});UI Components
Permit Workflow Page
Location: /admin → Safety → Permit Workflow
Features:
- List of all permits with filters (status, type)
- Request new permit dialog
- View permit details with documents
- Approve/Activate/Close actions
- Upload documents dialog
Permit Types
- Hot Work: Welding, cutting, grinding
- Electrical Work: Electrical installations and repairs
- Confined Space: Work in confined spaces
- Chemical Work: Handling hazardous chemicals
- Excavation: Digging and excavation work
- Height Work: Work at height
- Lockout/Tagout: Equipment isolation procedures
- Other: Other types of hazardous work
RLS Policies
Permits
- Admins: Full access to all permits
- Safety Officers: Full access within their tenant
- Workers: Can create and view their own permits
Permit Documents
- Admins: Full access to all documents
- Safety Officers: Full access within their tenant
- Workers: Can upload and view documents for their permits
Helper Functions
get_active_permits(tenant_id)
SQL function that returns all active permits for a tenant:
SELECT * FROM get_active_permits('tenant-uuid');Returns permits with status 'approved' or 'active' that haven't expired (ends_at > now()).
Best Practices
- Request Early: Submit permit requests well in advance of work start date
- Complete Documentation: Attach all required documents (risk assessments, safety plans, certificates)
- Zone Selection: Link permits to zones when possible for better location tracking
- Status Management: Keep permit status updated throughout the work lifecycle
- Document Retention: Keep all permit documents for compliance and audit purposes
Integration
The Permit Workflow system integrates with:
- Zones: Permits can be linked to warehouse zones
- Safety Module: Permits are part of the Safety Pro system
- User Management: Uses existing user roles and permissions
- Multi-Tenancy: Fully tenant-aware with RLS
Future Enhancements
- QR code generation for active permits
- Mobile permit scanning
- Permit expiration notifications
- Integration with predictive safety scores
- Automated permit renewal workflows
- Permit templates for common work types