Each rule now has one owning contract; others point to it: validation and multi-step rules live in forms-validation (modal-workflows references them), pagination metadata lives in go-api (table-management references it), the async task flow lives in go-background-tasks (go-api references it), backup git-safety checks live in backup-management (go-database references it). Remove the leftover Vapor/Aqua baseline mention and stale kit/patterns paths, compress the batch-file-upload ADR narrative, and drop content-free pattern READMEs. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
54 lines
2.1 KiB
Markdown
54 lines
2.1 KiB
Markdown
# Contract: Modal Workflows
|
|
|
|
Version: 1.1
|
|
|
|
## State Machine
|
|
|
|
Every modal has exactly these states:
|
|
|
|
```
|
|
closed → open → submitting → success | error
|
|
↓
|
|
cancel → closed
|
|
```
|
|
|
|
- `open`: form visible, submit enabled.
|
|
- `submitting`: form disabled, spinner on submit button, no double-submit possible.
|
|
- `success`: close modal, show toast, refresh affected data.
|
|
- `error`: stay open, show error message inline, re-enable form.
|
|
- `cancel`: close without changes, no confirmation needed unless form is dirty.
|
|
|
|
## Rules
|
|
|
|
- Destructive actions (delete, archive, bulk remove) require a separate confirmation modal — not
|
|
just a disabled button. Confirmation modal must name the target: "Delete component ABC-123?"
|
|
- Never close a modal automatically on error — keep it open so the user can retry or copy the error.
|
|
- Submit button text must describe the action: "Save", "Delete", "Archive" — not "OK" or "Confirm".
|
|
- Modal title must match the action: "Edit Component", "Delete Asset" — not generic "Modal".
|
|
- Escape key and clicking the backdrop close the modal (unless in `submitting` state).
|
|
|
|
## Validation
|
|
|
|
Validation UX follows the `forms-validation` contract (server-side on submit, inline field
|
|
errors, form-level summary, human-readable messages).
|
|
|
|
## htmx Pattern (server-rendered modals)
|
|
|
|
```
|
|
POST /api/entity → 200 OK + HX-Trigger: "entitySaved" (success)
|
|
→ 422 Unprocessable + partial HTML (validation error, re-render form)
|
|
→ 500 + error message (server error)
|
|
```
|
|
|
|
- On success: server sends `HX-Trigger` header, JS listener closes modal and refreshes list.
|
|
- On validation error: server re-renders the form partial with inline errors (422, per `go-api`).
|
|
- On server error: show generic error toast, log full error server-side.
|
|
|
|
## Multi-Step Modals
|
|
|
|
Staged flows follow the `forms-validation` multi-step rules. Modal-specific:
|
|
|
|
- Use only when the workflow genuinely requires staged input (e.g. import preview → confirm).
|
|
- Show a step indicator (Step 1 of 3).
|
|
- Single-step edits must NOT be split into multi-step without good reason.
|