Full permit lifecycle management with inspection scheduling, license tracking, compliance scoring, and expiration alert automation.
PermitCard, StatsCard components
useQuery(api.permits.queries.list) + useQuery(api.permits.queries.getStats)
Empty component with IconCircle style D (hero)
Shown when permits.length === 0
CreatePermitScreen with type selector chips
useMutation(api.permits.mutations.createPermit)
PermitDetailScreen with tabbed layout
useQuery(api.permits.queries.get) + useMutation(api.permits.mutations.deletePermit)
InspectionCard with timeline layout
useQuery(api.permits.queries.get) → inspections array
LicenseCard with Checkr verification badge
useQuery(api.licenses.queries.list) + Checkr integration status
ReminderCard with urgency-sorted list
useQuery(api.permits.queries.listReminders) sorted by daysUntilExpiration
ComplianceOverview with score ring
useQuery(api.compliance.queries.getScore) aggregates licenses, insurance, permits, background
permitType: string (building, electrical, plumbing...)
permitNumber: string (OH-BLD-44120-0847)
jurisdiction: string (Summit County)
jurisdictionUrl: string?
jurisdictionPhone: string?
status: string (draft|applied|active|expired...)
applicationDate: number (timestamp)
approvalDate: number?
expirationDate: number?
propertyAddress: string?
description: string?
contractorId: Id<contractorUsers>
jobId: Id<jobs>?
licenseType: string (contractor, electrician, plumber)
licenseNumber: string (OH-GC-2024-14892)
state: string (OH)
expirationDate: number
verificationStatus: string (verified|pending|expired)
verificationProvider: string (checkr)
verifiedAt: number?
contractorId: Id<contractorUsers>
permitId: Id<permits>
inspectionType: string (foundation, framing, rough-in, final)
scheduledDate: number?
status: string (passed|failed|scheduled|not_scheduled)
inspectorName: string?
notes: string?
completedAt: number?
usePermits() → permits[], stats, filters
useLicenses() → licenses[], verification
useCompliance() → score, breakdown, needs
useInspections() → inspections[] by permit
createPermit(permitType, jurisdiction, ...)
updatePermit(permitId, fields...)
deletePermit(permitId)
scheduleInspection(permitId, type, date)
addLicense(type, number, state, exp)
completeReminder(reminderId)
dismissReminder(reminderId)
verifyLicense(licenseNumber, state)
backgroundCheck(contractorId)
webhook: checkr.completed → update status
webhook: checkr.flagged → admin alert
autoRefresh: every 90 days re-verify