Some checks are pending
Bidi Control Character Guard / bidi-control-guard (push) Waiting to run
Circular Dependency Check / Check for new circular dependencies (push) Waiting to run
Citus Migration Smoke / Combined migrations on single-node Citus (push) Waiting to run
E2E Fresh Install Tests / fresh-install-e2e (push) Waiting to run
ext-v2 guardrails / Run ext-v2 guard and ESLint (push) Waiting to run
Integration Tests / Check for relevant changes (push) Waiting to run
Integration Tests / ${{ (github.event_name == 'schedule' || github.event.inputs.suite == 'full') && 'Full integration suite' || 'Tier-1 integration subset' }} (push) Blocked by required conditions
Mobile checks / Mobile lint + typecheck (push) Waiting to run
Mobile checks / Mobile unit tests (push) Waiting to run
Mobile checks / Mobile dependency audit (report) (push) Waiting to run
Mobile checks / Mobile reproducibility checks (push) Waiting to run
Secrets guard (env backups) / Ensure no tracked env backup files (push) Waiting to run
Temporal Readiness / fast-readiness (push) Waiting to run
Temporal Readiness / docker-parity (push) Waiting to run
TypeScript Type Check / Nx affected typecheck (push) Waiting to run
Unit Tests / Skipped-test budget (push) Waiting to run
Unit Tests / Nx affected unit tests (push) Waiting to run
Unit Tests / Server unit coverage (informational) (push) Waiting to run
Validate Tenant Management Schema / Check for relevant changes (push) Waiting to run
Validate Tenant Management Schema / Validate Tenant Management Schema (push) Blocked by required conditions
EE Workflows Build Guard / ee-workflows-build-guard (push) Waiting to run
Excluded: .git, node_modules, secrets/, compose.env, assemblyscript tgz Source: /opt/alga-psa on psa.joliet.tech
192 lines
5.9 KiB
Markdown
192 lines
5.9 KiB
Markdown
# Business-Relevant Test Counterpart Loop
|
|
|
|
## Goal
|
|
|
|
Create a 1:1 business-relevant counterpart for every notification-only fixture. Each current fixture that only calls `notifications.send_in_app` needs a corresponding fixture that exercises real domain-modifying actions.
|
|
|
|
## Current State
|
|
|
|
- **171 total fixtures** in workflow-harness
|
|
- **24 business-relevant** (14%) - already call domain-modifying actions
|
|
- **144 notification-only** - need business counterparts
|
|
- **2 scaffold** (1%) - minimal harness tests (ticket-created-hello, ticket-created-ignore-system)
|
|
- **3 harness tests** (2%) - runtime/schema validation tests
|
|
|
|
## Classification Criteria
|
|
|
|
| Classification | Definition | Needs Counterpart? |
|
|
|----------------|------------|-------------------|
|
|
| **business-relevant** | Calls domain-modifying actions: `tickets.assign`, `tickets.add_comment`, `tickets.update_fields`, `projects.create_task`, `time_entries.create`, `email.send`, `crm.create_activity_note`, `scheduling.assign_user`, etc. | No |
|
|
| **notification-only** | Only calls `notifications.send_in_app` | **Yes** |
|
|
| **scaffold** | No `action.call` at all (just state.set/assign/return) | No (intentional) |
|
|
| **harness-test** | Tests runtime behavior (paused workflows, schema validation) | No (infrastructure) |
|
|
|
|
## The Iteration Loop
|
|
|
|
Process fixtures **domain by domain**, alphabetically within each domain.
|
|
|
|
### Phase 1: High-Value Domains First
|
|
|
|
1. **ticket** (71 needed) - highest impact, most complex business logic
|
|
2. **project** (28 needed) - task management, status workflows
|
|
3. **invoice** (10 needed) - billing automation
|
|
4. **appointment** (9 needed) - field service scheduling
|
|
|
|
### Phase 2: Remaining Domains
|
|
|
|
5. **payment** (4 needed)
|
|
6. **contract** (4 needed)
|
|
7. **schedule** (4 needed)
|
|
8. **technician** (4 needed)
|
|
9. **company** (2 needed)
|
|
10. **integration** (2 needed)
|
|
11. **task** (2 needed)
|
|
12. **time** (2 needed)
|
|
13. **email** (1 needed)
|
|
14. **capacity** (1 needed)
|
|
|
|
### Step-by-step: For Each Notification-Only Fixture
|
|
|
|
#### 1. Read the current fixture
|
|
|
|
```bash
|
|
cat ee/test-data/workflow-harness/<current-fixture>/bundle.json
|
|
cat ee/test-data/workflow-harness/<current-fixture>/test.cjs
|
|
```
|
|
|
|
Understand:
|
|
- What event triggers it
|
|
- What the fixture name implies it *should* do
|
|
- What control flow patterns it uses (if/else, foreach, tryCatch, callWorkflow)
|
|
|
|
#### 2. Design the business-relevant counterpart
|
|
|
|
The counterpart should:
|
|
- Use the **same event** as the original
|
|
- Preserve the **same control flow pattern** (if the original tests foreach, the counterpart should too)
|
|
- Replace `notifications.send_in_app` with **domain-modifying action(s)**
|
|
- Have a name that reflects the actual business action (see `needed-biz-tests.json` for suggestions)
|
|
|
|
#### 3. Scaffold the new fixture
|
|
|
|
```bash
|
|
node tools/workflow-harness/scaffold.cjs \
|
|
--name <suggested-biz-name> \
|
|
--event <EVENT_NAME> \
|
|
--schema <payload.Schema.v1>
|
|
```
|
|
|
|
#### 4. Implement the bundle.json
|
|
|
|
Copy the control flow structure from the original, then:
|
|
- Replace `notifications.send_in_app` action calls with domain actions
|
|
- Update `dependencies.actions` array
|
|
- Update `inputMapping` for the new action's required fields
|
|
- Keep fixture markers (`vars.marker`, dedupe keys) for test isolation
|
|
|
|
Example transformation:
|
|
```json
|
|
// BEFORE (notification-only)
|
|
{
|
|
"id": "notify",
|
|
"type": "action.call",
|
|
"config": {
|
|
"actionId": "notifications.send_in_app",
|
|
"inputMapping": {
|
|
"title": { "$expr": "vars.title" },
|
|
"body": { "$expr": "vars.body" }
|
|
}
|
|
}
|
|
}
|
|
|
|
// AFTER (business-relevant)
|
|
{
|
|
"id": "add-comment",
|
|
"type": "action.call",
|
|
"config": {
|
|
"actionId": "tickets.add_comment",
|
|
"version": 1,
|
|
"inputMapping": {
|
|
"ticket_id": { "$expr": "payload.ticketId" },
|
|
"comment": { "$expr": "vars.marker & ' ' & vars.body" },
|
|
"is_internal": true
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
#### 5. Implement the test.cjs
|
|
|
|
The test must:
|
|
1. Create prerequisite domain objects (ticket, project, etc.)
|
|
2. Register cleanup hooks (HTTP delete with DB fallback)
|
|
3. Trigger the event via `/api/workflow/events`
|
|
4. Wait for the run to complete
|
|
5. **Assert the business outcome** by querying the DB
|
|
|
|
```javascript
|
|
// Assert the domain action happened
|
|
const comments = await ctx.db.query(`
|
|
SELECT * FROM comments
|
|
WHERE ticket_id = $1 AND comment LIKE $2
|
|
`, [ticketId, `[fixture ${testId}]%`]);
|
|
ctx.expect.ok(comments.rows.length > 0, 'comment was created');
|
|
```
|
|
|
|
#### 6. Run and iterate
|
|
|
|
```bash
|
|
node tools/workflow-harness/run.cjs \
|
|
--test ee/test-data/workflow-harness/<new-fixture> \
|
|
--base-url http://localhost:3010 \
|
|
--tenant <uuid> \
|
|
--cookie-file <path> \
|
|
--pg-url <postgres-url> \
|
|
--force --debug
|
|
```
|
|
|
|
Triage failures:
|
|
- **Fixture bug**: Wrong JSONata, missing fields, bad cleanup → fix in fixture
|
|
- **Harness bug**: Auth issues, polling errors → fix in `tools/workflow-harness/`
|
|
- **Product bug**: Action fails unexpectedly → fix in `server/`
|
|
|
|
#### 7. Commit when green
|
|
|
|
```bash
|
|
git add ee/test-data/workflow-harness/<new-fixture>/
|
|
git commit -m "test(workflow-harness): add <new-fixture> business counterpart for <original-fixture>"
|
|
```
|
|
|
|
#### 8. Update progress tracker
|
|
|
|
Mark the fixture as done in `SCRATCHPAD.md` and proceed to next.
|
|
|
|
## Batching Strategy
|
|
|
|
Given 144 fixtures to create, batch by domain:
|
|
|
|
| Domain | Count | Estimated Batches |
|
|
|--------|-------|-------------------|
|
|
| ticket | 71 | 7 batches of 10 |
|
|
| project | 28 | 3 batches of ~10 |
|
|
| invoice | 10 | 1 batch |
|
|
| appointment | 9 | 1 batch |
|
|
| others | 26 | 3 batches |
|
|
|
|
**Total: ~16 commit batches**
|
|
|
|
## Files
|
|
|
|
- Coverage analysis: `coverage-analysis.json`
|
|
- Needed tests with suggestions: `needed-biz-tests.json`
|
|
- Progress tracker: `SCRATCHPAD.md`
|
|
|
|
## Definition of Done
|
|
|
|
- [ ] All 144 notification-only fixtures have business-relevant counterparts
|
|
- [ ] Each counterpart passes with `--force --debug`
|
|
- [ ] Each counterpart asserts a real database change (not just run SUCCEEDED)
|
|
- [ ] All fixtures committed with descriptive messages
|
|
|
|
When complete, output `<promise>DONE</promise>`.
|