Data model — Process
Generic header record for any long-running background job. The frontend polls GET /processes/{id} or streams GET /processes/{id}/stream (SSE) to drive the job tray UI. Each process has an append-only ProcessEvent log that captures per-step progress.
Table: processes
| Column | Type | Nullable | Description |
|---|---|---|---|
| id | bigint | no | Primary key |
| workspace_id | bigint | yes | Owning workspace |
| user_id | bigint | yes | User who triggered the job |
| type | string | yes | Job type identifier (see below) |
| status | string | no | State machine status (see below) |
| progress_percent | int | yes | 0–100 completion estimate |
| current_step | string | yes | Human-readable label for the running step |
| summary | json | yes | Structured result data populated on completion |
| error_message | string | yes | Exception message if status is failed |
| queue | string | yes | Laravel queue name the job was dispatched to |
| attempts | int | yes | Number of job dispatch attempts |
| related_type | string | yes | Polymorphic model class (e.g. App\Models\AiLocationImportBatch) |
| related_id | bigint | yes | Polymorphic ID pointing to the originating batch record |
| input_payload | json | yes | Snapshot of the job’s input parameters |
| started_at | timestamp | yes | When the job began processing |
| finished_at | timestamp | yes | When the job reached a terminal state |
| created_at | timestamp | — | — |
| updated_at | timestamp | — | — |
Status state machine
| Status | Terminal | Description |
|---|---|---|
pending | no | Created, not yet picked up by a worker |
running | no | Worker is actively processing |
waiting_review | no | Completed a step, paused awaiting user action |
completed | yes | Successfully finished |
failed | yes | Unrecoverable error; error_message populated |
cancelled | yes | User or system cancelled before completion |
POST /processes/{id}/retry transitions failed → pending. POST /processes/{id}/cancel transitions any non-terminal status → cancelled.
Job types
🔴 [NEEDS CLARIFICATION: Confirm the full type enum from the job or process service layer. Known types based on codebase context: ai_location_import, ai_location_improvement, csv_import.]
ProcessEvent log
Every significant step within a job appends a ProcessEvent row. Events are immutable once written — this is an audit trail, not mutable state.
Table: process_events
| Column | Type | Nullable | Description |
|---|---|---|---|
| id | bigint | no | Primary key |
| process_id | bigint | no | Parent process |
| type | string | yes | Event category (e.g. step, error, progress) |
| status | string | yes | Status snapshot at event time |
| progress_percent | int | yes | Progress snapshot at event time |
| step | string | yes | Step label |
| message | string | yes | Human-readable event message |
| payload | json | yes | Structured event data |
| created_at | timestamp | — | — |
| updated_at | timestamp | — | — |
Relations
belongsTo WorkspacebelongsTo UserhasMany ProcessEvent— ordered ascending byid(insertion order)related_type / related_id— polymorphic pointer to the originating batch model (AiLocationImportBatch,AiLocationImprovementBatch, etc.)
SSE streaming
GET /processes/{id}/stream opens a Server-Sent Events connection. The backend emits each new ProcessEvent as it is written, then closes the stream when the process reaches a terminal status or after 25 seconds (whichever comes first). The frontend reconnects automatically if the stream closes before the process is done.
Related pages
- API — Processes — all process endpoints including SSE
- Data model: AiLocationImportBatch — example originating batch model
- Backend: Jobs and processes