# Scratchpad ## Status - **Complete**: All notification-only fixtures have business counterparts (144/144) ## Summary by Domain (needed-biz-tests.json) | Domain | To Create | |--------|-----------| | ticket | 71 | | project | 28 | | invoice | 10 | | appointment | 9 | | payment | 4 | | contract | 4 | | schedule | 4 | | technician | 4 | | other | 10 | | **Total** | **144** | ## Progress Tracker ### Phase 1: High-Value Domains #### Ticket Domain (71 fixtures) - [x] Batch 1: ticket-approval-* through ticket-created-assign-contact-owner - [x] Batch 2: ticket-created-assign-idempotent-real through ticket-created-chain-assign-comment-email - [x] Batch 3: ticket-created-client-missing-create-note through ticket-created-email-with-retry - [x] Batch 4: ticket-created-error-creates-comment through ticket-created-log-initial-time - [x] Batch 5: ticket-created-missing-fields-comment through ticket-created-set-custom-fields - [x] Batch 6: ticket-created-set-sla-fields through ticket-merged-add-comment - [x] Batch 7: ticket-message-added-send-response through ticket-updated-status-add-comment - Completed commits: - Batch 1 (commit f230b76e4): 10 fixtures (ticket-approval-* through ticket-created-assign-contact-owner) - Batch 2 (commit 761473599): 10 fixtures (ticket-created-assign-idempotent-real through ticket-created-chain-assign-comment-email) - Batch 3 (commit 2862304a7): 10 fixtures (ticket-created-client-missing-create-note through ticket-created-email-with-retry) - Batch 4 (commit 36f8787d7): 10 fixtures (ticket-created-error-creates-comment through ticket-created-log-initial-time) - Batch 5 (commit 5052a466e): 10 fixtures (ticket-created-missing-fields-comment through ticket-created-set-custom-fields) - Batch 6 (commit eb184c5b8): 10 fixtures (ticket-created-set-sla-fields through ticket-merged-add-comment) - Batch 7 (commit 7cce41cb4): 11 fixtures (ticket-message-added-send-response through ticket-updated-status-add-comment) #### Project Domain (28 fixtures) - [x] Batch 1: project-approval-* through project-created-create-ticket - [x] Batch 2: project-created-* through project-task-completed-callworkflow-next - [x] Batch 3: project-task-* through project-updated-send-email - Completed commits: - Batch 1 (commit 9f1f7a68f): 10 fixtures - Batch 2 (commit afc446abd): 10 fixtures - Batch 3 (commit a801edcf5): 8 fixtures #### Invoice Domain (10 fixtures) - [x] Batch 1: All invoice-* (commit fbf3534e8) #### Appointment Domain (9 fixtures) - [x] Batch 1: All appointment-* (commit bce5c865f) ### Phase 2: Remaining Domains - [x] payment-* (4) (commit c6c209ebb) - [x] contract-* (4) (commit 5e9291fdf) - [x] schedule-* (4) (commit a5e2b109d) - [x] technician-* (4) (commit cbfd38642) - [x] other (10) (commit 622fa750a) ## Notes / Decisions - Strict definition: "business-relevant" means calling domain-modifying actions, not just notifications - `notifications.send_in_app` is NOT business-relevant - it only creates internal notifications - Current coverage: only 14% of fixtures exercise real business actions - Counterparts should preserve the control flow pattern of the original (foreach, tryCatch, etc.) - Counterparts should assert actual DB state changes, not just workflow run success - Implementation approach (batch generator): - Ticket domain counterparts: replace `notifications.send_in_app` → `tickets.add_comment` and assert DB `comments`. - All other domains (project/invoice/appointment/etc): replace `notifications.send_in_app` → `projects.create_task` and assert DB `project_tasks`. - Shared runner: `ee/test-data/workflow-harness/_lib/biz-fixture.cjs` - Uses `workflow_runs.input_json->>'fixtureNotifyUserId'` (and optionally `fixtureDedupeKey`) to wait for the correct run when domain APIs emit their own events (e.g., creating a ticket can also emit `TICKET_CREATED`). - Reuses an existing ticket/project and cleans up only marker-matched rows (comments/tasks) to avoid FK cleanup races when domain APIs emit real events that trigger workflows. - Generator: `tools/workflow-harness/generate-biz-counterparts.cjs` - Local harness env (this worktree): - Server: http://localhost:3010 (docker `prep_1_0_server_ee`) - Postgres: localhost:55432 (db `server`, user `postgres`, password in `secrets/postgres_password`) - Tenant: `d01f7285-da5c-49c4-8eb9-8bf51ee97e2b` (from DB `tenants.tenant`) - API keys in DB (`api_keys`) include: - `workflow harness (auto-generated)` (active) - `workflow harness (generated by iteration loop)` (active) - Known workflow action IDs already used in fixtures: `tickets.add_comment`, `tickets.assign`, `tickets.update_fields`, `projects.create_task`, `crm.create_activity_note`, `scheduling.assign_user`, `email.send`, `tickets.find`, `notifications.send_in_app` ## Existing Business-Relevant Fixtures (Reference) These 24 fixtures already call domain-modifying actions: **Ticket (16):** - ticket-assigned-acknowledge (tickets.add_comment, email.send) - ticket-created-assign-invalid-fails (tickets.assign) - ticket-created-assign-trycatch (tickets.add_comment, tickets.assign) - ticket-created-auto-assign-by-priority (tickets.add_comment, tickets.assign) - ticket-created-create-project-task (projects.create_task) - ticket-created-outage-escalate (tickets.update_fields) - ticket-created-triage-comment (tickets.add_comment) - ticket-escalated-crm-note (crm.create_activity_note) - ticket-priority-changed-audit-comment (tickets.add_comment) - ticket-queue-after-hours-email (email.send) - ticket-reopened-notify-tech (tickets.add_comment) - ticket-status-waiting-on-customer-reminder (email.send) - ticket-tags-billing-route (tickets.update_fields) - ticket-unassigned-return-to-triage (tickets.update_fields) **Project (1):** - project-created-kickoff-tasks (projects.create_task) **Invoice (1):** - invoice-generated-review-task (projects.create_task) **Appointment (1):** - appointment-created-assign-notify (scheduling.assign_user) **Contract (1):** - contract-created-onboarding-task (projects.create_task, crm.create_activity_note) **Schedule (1):** - schedule-block-created (projects.create_task) **Email (1):** - email-inbound-received-ticket-comment (tickets.add_comment) ## Commands / Runbook ```bash # List all notification-only fixtures for a domain grep -l '"notifications.send_in_app"' ee/test-data/workflow-harness/ticket-*/bundle.json | wc -l # Scaffold a new fixture node tools/workflow-harness/scaffold.cjs --name --event --schema # Run a fixture node tools/workflow-harness/run.cjs \ --test ee/test-data/workflow-harness/ \ --base-url http://localhost:3010 \ --tenant \ --cookie-file \ --pg-url \ --force --debug # List available actions grep -rh '"actionId"' ee/test-data/workflow-harness/*/bundle.json | \ sed 's/.*"actionId": "\([^"]*\)".*/\1/' | sort -u ``` ## Gotchas - Some actions require specific permissions (check 47_permissions.cjs seed) - `tickets.add_comment` requires `comment:manage` permission - `email.send` requires `email:process` permission and tenant_email_settings - Cleanup should use HTTP delete with DB fallback for FK constraint issues - Some fixtures reference `tickets.find(...).attributes.*`; ensure JSONata assigns default JSON-serializable values if fixture attributes aren't present. - JSONata escaping: use `\"` not `\\\"` inside expressions