feat(automation): record rule execution outcomes

This commit is contained in:
2026-06-05 09:32:25 +08:00
parent f4c56bf109
commit 4e2855958d
5 changed files with 238 additions and 27 deletions
+31 -10
View File
@@ -16,9 +16,9 @@ Build GoChat as a Go backend that can directly reuse the frontend from `referenc
## Current Baseline
- Latest implementation checkpoint: `feat(automation): align rule trigger coverage`.
- Latest documentation checkpoint: this checkpoint, recorded with the B9.1b implementation.
- Worktree status at this implementation checkpoint: B9.1b Chatwoot listener trigger coverage is implemented; next active slice is B9.1c execution logs/stop-on-match, followed by B9.1d webhook/email transcript retries and B9.2 macro execution parity.
- Latest implementation checkpoint: `feat(automation): record rule execution outcomes`.
- Latest documentation checkpoint: this checkpoint, recorded with the B9.1c implementation.
- Worktree status at this implementation checkpoint: B9.1c execution outcome logging is implemented; next active slice is B9.1d retryable webhook/email transcript actions, followed by B9.2 macro execution parity.
- `go test ./...` passes.
- Route dump succeeds with `TOTAL: 830` after adding the Chatwoot-compatible applied-SLA index route.
- Route parity artifacts now exist under `docs/parity/` and are generated by `cmd/route_parity`.
@@ -44,12 +44,11 @@ Next ordered checkpoints:
| Order | Slice | Required outcome | Primary verification |
| --- | --- | --- | --- |
| 1 | B9.1c | Automation execution logs, failed-action records, and stop-on-match semantics are explicit and tested. | Rule service/action tests for matched, skipped, failed, and stop-on-match flows. |
| 2 | B9.1d | Webhook and email transcript actions are timeout-bound, retryable, and observable through the worker/action boundary. | Fake HTTP/mailer tests and log/retry metadata assertions. |
| 3 | B9.2 | Macro CRUD and macro execute side effects match Chatwoot frontend expectations. | Macro handler/service tests that reload conversations/messages after execution. |
| 4 | B10 | Audit, CustomRole, and remaining InboxLimit surfaces enforce Chatwoot admin behavior. | Permission matrix tests, audit writer/list tests, inbox/account limit tests. |
| 5 | B11 | Captain/Copilot enterprise screens have real persistence and safe LLM feature gates. | Captain/Copilot handler/service fixtures and disabled-state tests. |
| 6 | B12 | Reused Chatwoot frontend smoke runs repeatably against GoChat. | Checked smoke command plus gap report under `docs/parity/`. |
| 1 | B9.1d | Webhook and email transcript actions are timeout-bound, retryable, and observable through the worker/action boundary. | Fake HTTP/mailer tests and log/retry metadata assertions. |
| 2 | B9.2 | Macro CRUD and macro execute side effects match Chatwoot frontend expectations. | Macro handler/service tests that reload conversations/messages after execution. |
| 3 | B10 | Audit, CustomRole, and remaining InboxLimit surfaces enforce Chatwoot admin behavior. | Permission matrix tests, audit writer/list tests, inbox/account limit tests. |
| 4 | B11 | Captain/Copilot enterprise screens have real persistence and safe LLM feature gates. | Captain/Copilot handler/service fixtures and disabled-state tests. |
| 5 | B12 | Reused Chatwoot frontend smoke runs repeatably against GoChat. | Checked smoke command plus gap report under `docs/parity/`. |
## Execution Snapshot
@@ -139,6 +138,7 @@ This ledger records the committed parity checkpoints that future slices should b
| `feat(automation): align automation rule payloads` | Completed B9.1a automation-rule CRUD contract parity for the reused Chatwoot frontend: list/show/update/clone now return `{ payload }`, create returns the raw rule object, delete returns empty `200 OK`, conditions accept `attribute_key` and Chatwoot operators such as `equal_to`, action params accept frontend arrays, responses serialize `attribute_key`, array `action_params`, Unix `created_on`, and update/delete/clone are account-scoped. | `go test ./internal/handler/api/v1 -run AutomationRule -count=1`; `go test ./internal/automation -run 'AutomationRule\|Condition\|Action' -count=1`; `go test ./internal/handler/api/v1 -count=1`; `go test ./internal/automation -count=1`; `go test ./...`; `git diff --check`. No route changes; route dump remains `TOTAL: 830`. | Continue B9.1b trigger coverage, B9.1c execution logs/stop-on-match, and B9.2 macro payload/execute parity. |
| `docs: detail automation trigger plan` | Fully landed the next B9 tracking contract: current baseline now points at `3403770`, the control board is ordered from B9.1b through B12, B9 status is `Doing`, and B9.1b explicitly follows the current Chatwoot listener events while excluding non-reference `contact_updated` automation triggers. | Documentation-only checkpoint; `git diff --check` passed before commit. | Start B9.1b implementation from the recorded listener/event contract. |
| `feat(automation): align rule trigger coverage` | Completed B9.1b listener/event coverage: automation rules now honor Chatwoot skip rules for automation-origin events, auto-reply conversations, activity messages, and auto-reply emails; listener extraction works from event conversation ID, `conversation_id`, conversation payloads, and message payloads; conversation update/status/priority paths dispatch `changed_attributes`; initial conversation messages and provider webhook messages carry the message/conversation data needed by automation. | `go test ./internal/automation -run 'AutomationRuleListener\|MatchAndExecute\|Condition' -count=1`; `go test ./internal/service -run 'Conversation.*Automation\|Message.*Automation\|ConversationService' -count=1`; `go test ./internal/handler/webhook -run 'Incoming\|Webhook' -count=1`; `go test ./internal/automation -count=1`; `go test ./internal/service -count=1`; `go test ./internal/handler/webhook -count=1`; `go test ./...`; `git diff --check`. No route changes; route dump remains `TOTAL: 830`. | Continue B9.1c execution logs and stop-on-match behavior, then B9.1d retryable webhook/email transcript actions and B9.2 macro parity. |
| `feat(automation): record rule execution outcomes` | Completed B9.1c observability/parity guard: rule evaluations now record skipped condition outcomes, condition failures, event names, aggregate action counts, and per-action success/failure results. Matching rules continue executing in ID order without stop-on-match, matching the current Chatwoot listener loop, and failed actions do not prevent later actions from running. | `go test ./internal/automation -run 'AutomationRuleService_MatchAndExecute\|ExecutionLogService' -count=1`; `go test ./internal/automation -count=1`; `go test ./internal/handler/webhook -run 'Incoming\|Webhook' -count=1`; `go test ./internal/service -run 'Conversation.*Automation\|Message.*Automation\|ConversationService' -count=1`; `go test ./...`; `git diff --check`. No route changes; route dump remains `TOTAL: 830`. | Continue B9.1d retryable webhook/email transcript actions, then B9.2 macro payload/execute parity. |
## Next Slice Contract
@@ -410,7 +410,7 @@ B9 automation and macro execution breakdown:
| --- | --- | --- | --- | --- |
| B9.1a | Align automation-rule CRUD request/response envelopes, condition/action validation, and rule status toggles. | Chatwoot automation rules controller/model and dashboard automation client. | Handler tests for index/show/create/update/delete/toggle payloads and validation failures. | Done by `feat(automation): align automation rule payloads` |
| B9.1b | Implement real rule trigger coverage for Chatwoot automation events: conversation created/updated/opened/resolved and message created. Provider webhook persistence must dispatch into those same conversation/message events. `contact_updated` is not a current Chatwoot automation trigger and stays out unless the local reference/frontend proves otherwise. | `reference/chatwoot/app/listeners/automation_rule_listener.rb`, `reference/chatwoot/app/listeners/base_listener.rb`, existing `channel.Dispatcher` events. | Listener tests prove matching rules execute once per event with account/inbox filters, changed attributes, provider-event reachability, and Chatwoot skip rules. | Done by `feat(automation): align rule trigger coverage` |
| B9.1c | Persist execution logs and stop-on-match behavior, including failed action records. | Chatwoot automation execution/log models and services. | Service tests cover success, skipped, failed, retryable, and stop-on-match flows. | Todo |
| B9.1c | Persist execution logs and stop-on-match behavior, including failed action records. The current Chatwoot listener runs every matching rule, so Go explicitly preserves no-stop-on-match behavior and records it in tests. | `reference/chatwoot/app/listeners/automation_rule_listener.rb`, `reference/chatwoot/app/services/automation_rules/action_service.rb`, Go execution log service. | Service tests cover success, skipped, failed/partial, per-action result records, and all-matching-rules execution. | Done by `feat(automation): record rule execution outcomes` |
| B9.1d | Make webhook and email transcript actions timeout-bound, retryable, and observable. | Chatwoot action services/jobs and Phase 5 worker plan. | Tests use fake HTTP/mailer boundaries and assert retry/log metadata. | Todo |
| B9.2a | Align macro CRUD payloads, visibility rules, and validation. | Chatwoot macros controller/model and dashboard macro client. | Handler tests for raw macro payloads, ownership, account scoping, and delete status. | Todo |
| B9.2b | Execute macro actions against real conversations: labels, status, priority, assignee, team, custom attributes, private notes, and attachments where supported. | Chatwoot macro execution service and conversation/message controllers. | Macro execute tests reload conversation/message rows and assert Chatwoot-shaped response payloads. | Todo |
@@ -511,6 +511,26 @@ env GOCACHE=/tmp/gochat-gocache GOMODCACHE=/tmp/gochat-gomodcache go test ./...
git diff --check
```
B9.1c current checkpoint:
- Automation execution logs now include `event_name`, aggregate action counts, and JSON `action_results` for each action in a matched rule.
- Rules whose event matches but conditions do not match now write `skipped` execution records with `conditions_not_matched`, giving the B9 tracker explicit skipped-flow evidence.
- Condition matcher errors are logged as failed rule evaluations instead of disappearing into process logs only.
- Failed actions record per-action errors while later actions still run, matching Chatwoot `AutomationRules::ActionService#perform` rescue-and-continue behavior.
- The current Chatwoot listener loops through every matching rule; Go preserves this no-stop-on-match behavior and has regression coverage proving two matching rules both execute.
- B9 remains `Doing` because B9.1d retryable webhook/email transcript actions and B9.2 macro parity are still active.
B9.1c verification:
```bash
env GOCACHE=/tmp/gochat-gocache GOMODCACHE=/tmp/gochat-gomodcache go test ./internal/automation -run 'AutomationRuleService_MatchAndExecute|ExecutionLogService' -count=1
env GOCACHE=/tmp/gochat-gocache GOMODCACHE=/tmp/gochat-gomodcache go test ./internal/automation -count=1
env GOCACHE=/tmp/gochat-gocache GOMODCACHE=/tmp/gochat-gomodcache go test ./internal/handler/webhook -run 'Incoming|Webhook' -count=1
env GOCACHE=/tmp/gochat-gocache GOMODCACHE=/tmp/gochat-gomodcache go test ./internal/service -run 'Conversation.*Automation|Message.*Automation|ConversationService' -count=1
env GOCACHE=/tmp/gochat-gocache GOMODCACHE=/tmp/gochat-gomodcache go test ./...
git diff --check
```
B10 admin and limits breakdown:
| Step | Implementation target | Reference source | Required tests | Status |
@@ -1157,3 +1177,4 @@ Verification milestone gates:
- 2026-06-05: B9.1a automation-rule CRUD checkpoint committed as `feat(automation): align automation rule payloads`; automation-rule list/show/update/clone now return Chatwoot `{ payload }`, create returns the raw rule object, delete returns empty `200 OK`, frontend `attribute_key`/`equal_to` conditions and array `action_params` are accepted, responses serialize Chatwoot field names and Unix `created_on`, and get/update/delete/clone are account-scoped. Focused automation handler/service tests, handler and automation package tests, full `go test ./...`, and `git diff --check` passed. Next slice is B9.1b trigger coverage and action side-effect parity.
- 2026-06-05: B9 planning tracker was fully landed for the next handoff: current baseline points at `3403770 feat(automation): align automation rule payloads`, the ordered control board now starts at B9.1b and runs through B12, B9 is marked `Doing`, and B9.1b records the exact Chatwoot listener contract. The current reference listener only subscribes to conversation created/updated/opened/resolved and message created, so `contact_updated` is explicitly not an automation trigger unless a later local reference/frontend audit proves otherwise.
- 2026-06-05: B9.1b automation trigger checkpoint committed as `feat(automation): align rule trigger coverage`; automation listener now covers all current Chatwoot reference events, skips automation-origin/auto-reply/activity auto-reply-email cases, extracts account/conversation context from message and conversation event payloads, conversation update/status/priority paths dispatch `changed_attributes`, initial conversation messages dispatch full message-created context, and provider webhook persistence has a regression proving message-created automation reachability. Focused automation/service/webhook tests, package tests, full `go test ./...`, and `git diff --check` passed. Next slice is B9.1c execution log/stop-on-match parity.
- 2026-06-05: B9.1c execution outcome checkpoint committed as `feat(automation): record rule execution outcomes`; automation evaluations now persist event names, skipped condition outcomes, condition errors, per-action success/failure JSON, and aggregate action counts. Failed actions continue to later actions, and every matching rule still executes in ID order to match the current Chatwoot listener's no-stop-on-match loop. Focused automation tests, automation package tests, relevant service/webhook regressions, full `go test ./...`, and `git diff --check` passed. Next slice is B9.1d retryable webhook/email transcript action delivery.