Skip to content

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

sql
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

sql
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

  1. Requested: Initial state when a permit is created
  2. Approved: Permit has been approved by Safety Officer or Admin
  3. Active: Work has started (permit is in use)
  4. Closed: Work is completed and permit is closed
  5. Rejected: Permit request was rejected
  6. 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:

typescript
const { data: permits, isLoading } = usePermits({
  status: 'requested',
  permitType: 'hot_work',
  requestedBy: userId
});

usePermit(permitId)

Fetch a single permit by ID:

typescript
const { data: permit } = usePermit(permitId);

usePermitWithDocuments(permitId)

Fetch a permit with all attached documents:

typescript
const { data: permit } = usePermitWithDocuments(permitId);
// permit.documents contains array of PermitDocument

useActivePermits()

Fetch all active permits (approved or active status, not expired):

typescript
const { data: activePermits } = useActivePermits();

useCreatePermit()

Create a new permit request:

typescript
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:

typescript
const approvePermit = useApprovePermit();

await approvePermit.mutateAsync(permitId);

useActivatePermit()

Activate an approved permit (start work):

typescript
const activatePermit = useActivatePermit();

await activatePermit.mutateAsync(permitId);

useClosePermit()

Close an active or approved permit:

typescript
const closePermit = useClosePermit();

await closePermit.mutateAsync(permitId);

useUploadPermitDocument()

Upload a document to a permit:

typescript
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:

sql
SELECT * FROM get_active_permits('tenant-uuid');

Returns permits with status 'approved' or 'active' that haven't expired (ends_at > now()).

Best Practices

  1. Request Early: Submit permit requests well in advance of work start date
  2. Complete Documentation: Attach all required documents (risk assessments, safety plans, certificates)
  3. Zone Selection: Link permits to zones when possible for better location tracking
  4. Status Management: Keep permit status updated throughout the work lifecycle
  5. 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

Released under Commercial License