This page documents the frontend state management architecture and the data persistence layer of the Certimate web application. The system follows a repository pattern to abstract the PocketBase backend, uses Zustand for client-side state orchestration, and provides specialized hooks for form handling and performance optimization.
The frontend follows a unidirectional data flow where UI components interact with Zustand Stores for complex state or directly with Repositories for simple CRUD operations. Repositories act as a wrapper around the PocketBase SDK, providing type safety and consistent error handling.
| Functional Concept | Code Entity | File Path |
|---|---|---|
| Workflow State | useWorkflowStore | ui/src/stores/workflow/index.ts1 |
| Access Credentials | useAccessesStore | ui/src/stores/access/index.ts1 |
| Workflow Model | WorkflowModel | ui/src/domain/workflow.ts7-23 |
| Workflow Run | WorkflowRunModel | ui/src/domain/workflowRun.ts1 |
| Settings Model | SettingsModel | ui/src/domain/settings.ts13-16 |
| Persistence Settings | usePersistenceSettingsStore | ui/src/stores/settings/index.ts1 |
| SSL Provider Settings | useSSLProviderSettingsStore | ui/src/stores/settings/index.ts1 |
Title: "Frontend Data Flow and Entity Mapping"
Sources: ui/src/repository/workflow.ts6-7 ui/src/repository/workflowRun.ts1 ui/src/repository/certificate.ts6-7 ui/src/repository/settings.ts1 ui/src/stores/access/index.ts1 ui/src/stores/settings/index.ts1
Certimate uses Zustand for global state management, often combined with Immer for immutable updates to complex nested objects.
useWorkflowStore)Manages the lifecycle of a single workflow during editing and execution.
workflowState.init(id) to load workflow data and workflowState.destroy() on unmount.useAccessesStore)Manages the list of cloud provider credentials (AccessModel).
fetchAccesses to retrieve records, which are filtered in components like AccessList ui/src/pages/accesses/AccessList.tsx38-46deleteAccess to remove credentials while maintaining UI consistency ui/src/pages/accesses/AccessList.tsx19Certimate uses specialized stores for different settings categories defined in SETTINGS_NAMES ui/src/domain/settings.ts3-9:
usePersistenceSettingsStore: Manages data retention and expiry warning thresholds (certificatesWarningDaysBeforeExpire, certificatesRetentionMaxDays, workflowRunsRetentionMaxDays) ui/src/domain/settings.ts54-58useSSLProviderSettingsStore: Manages the default ACME CA provider and associated configurations ui/src/domain/settings.ts44-51notifyTemplate, scriptTemplate, and emails (contact emails) ui/src/domain/settings.ts4-8Sources: ui/src/pages/accesses/AccessList.tsx19-46 ui/src/domain/settings.ts3-59 ui/src/stores/settings/index.ts1
The repository layer abstracts the PocketBase SDK, providing a clean API for CRUD and real-time operations.
Standardized methods for get, list, save, and remove are implemented across domain-specific files.
workflow.ts: Handles listing with keyword filters and enabled status ui/src/repository/workflow.ts34-64 It provides subscribe and unsubscribe for real-time workflow updates ui/src/repository/workflow.ts95-101certificate.ts: Provides list with support for expiry state filtering (expiringSoon, expired) based on a stateThreshold (days before expiry) ui/src/repository/certificate.ts31-65 It also includes listByWorkflowRunId to fetch certificates generated by a specific execution ui/src/repository/certificate.ts67-79workflowRun.ts: Manages execution history. It supports real-time subscriptions to specific runs to track progress.settings.ts: Handles retrieval and updates for application-wide settings stored in the settings collection.Real-time updates are handled via the PocketBase subscribe mechanism. For example, WorkflowRunDetail uses subscribeWorkflowRun to refresh its state as the backend workflow engine progresses ui/src/components/workflow/WorkflowRunDetail.tsx41-58
Sources: ui/src/repository/workflow.ts34-101 ui/src/repository/certificate.ts31-79 ui/src/components/workflow/WorkflowRunDetail.tsx41-58
useZustandShallowSelector)Used to prevent unnecessary re-renders when consuming Zustand stores. It allows components to select multiple state slices while only triggering updates if the specific keys change.
usePersistenceSettingsStore(useZustandShallowSelector(["settings", "loadSettings"])) ui/src/pages/certificates/CertificateList.tsx32-34useAccessesStore(useZustandShallowSelector(["loadedAtOnce", "fetchAccesses", "deleteAccess"])) ui/src/pages/accesses/AccessList.tsx19useAntdForm)A utility hook that integrates Ant Design forms with the application's data flow, providing consistent handling for form submission and validation ui/src/hooks/useAntdForm.ts1-10
useVersionChecker)Monitors for application updates by comparing the local version against remote releases ui/src/pages/dashboard/Dashboard.tsx32
Title: "Hook and Component Interaction"
Sources: ui/src/pages/certificates/CertificateList.tsx32-34 ui/src/pages/accesses/AccessList.tsx19 ui/src/pages/dashboard/Dashboard.tsx32 ui/src/hooks/useAntdForm.ts1-10
The WorkflowModel tracks the lifecycle of an automation. It includes metadata like trigger (manual/scheduled), triggerCron, and lastRunStatus ui/src/domain/workflow.ts7-23
Represents a single execution of a workflow. It includes the status (PENDING, PROCESSING, SUCCEEDED, FAILED, CANCELED), startedAt, endedAt, and any associated outputs.
The system uses a flexible SettingsModel to store configuration for various subsystems ui/src/domain/settings.ts13-16
NotifyTemplateContent: Stores reusable templates for notification nodes ui/src/domain/settings.ts25-31PersistenceSettingsContent: Configures data retention policies for workflow runs and certificates ui/src/domain/settings.ts54-59SSLProviderSettingsContent: Configures the default CA and provider-specific ACME settings ui/src/domain/settings.ts44-51EmailsSettingsContent: Manages the list of contact emails for notifications ui/src/domain/settings.ts19-21Sources: ui/src/domain/workflow.ts7-23 ui/src/domain/settings.ts13-59
Refresh this wiki
This wiki was recently refreshed. Please wait 7 days to refresh again.