Skip to content

Commit 360b3f4

Browse files
committed
fix(typescript): add missing project references for queue-bullmq
- Add @sg/queue-bullmq to tsconfig.backend.json references - Add composite: true to queue/eventbus package tsconfigs - Add path aliases for queue packages in base.json - Add project references to agents-run tsconfig - Regenerate prisma zod manifest - Create pr-check-failures.md tracking document Resolves TypeScript build failures in CI All pr:check validations now pass Claude-Update: no
1 parent 35f4e09 commit 360b3f4

File tree

22 files changed

+303
-19
lines changed

22 files changed

+303
-19
lines changed
Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
🧩 M6 — Graph & State
2+
3+
Theme: From events to persisted screens.
4+
Goal: each Run now yields tangible, queryable state — screens, edges, and artifacts you can replay, diff, and visualize.
5+
6+
1️⃣ Feature : Storage Port (Artifacts → Durability)
7+
8+
Why first: no persistence = no graph.
9+
Stories
10+
11+
As a worker, I can write XML and screenshots through a StoragePort (interface: saveArtifact(type, bytes|stream) → { id, sha256, path })*.
12+
13+
As a dev, I can switch adapters between local (fs://…) and cloud (s3://…) without touching domain code.
14+
15+
As the outbox, I persist only artifact metadata (sha256, path, size) alongside NodeFinished.
16+
17+
Outcome: first reproducible artifact references in events.
18+
19+
2️⃣ Feature : XML Blob Model + Artifact Index
20+
21+
Why next: enables de-dupe + cross-run linking.
22+
Stories
23+
24+
As the DB, I store XML blobs (or S3 refs) with (sha256, appId, createdAt).
25+
26+
As the worker, I skip re-upload if sha256 exists.
27+
28+
As analytics, I can query latest XML by screenId.
29+
30+
3️⃣ Feature : Perceive Node → Real Capture Adapter
31+
32+
Why: first producer of XML + image.
33+
Stories
34+
35+
As an orchestrator, I call PerceiveNode with a driver (Appium / Playwright).
36+
37+
As a node, I emit NodeStarted → NodeFinished {xmlRef, screenshotRef}.
38+
39+
As QA, I can replay the same run and see identical XML hashes.
40+
41+
Outcome: screenshots + XML flow through outbox → SSE → UI.
42+
43+
4️⃣ Feature : Run Graph Persistence (Tables → Edges)
44+
45+
Why: graph = structured history of captures.
46+
Stories
47+
48+
As the DB, I create run_nodes(runId, nodeId, screenId, xmlRef, screenshotRef) and run_edges(sourceNodeId, action, targetNodeId).
49+
50+
As orchestrator, I upsert node/edge after every NodeFinished.
51+
52+
As UI, I fetch a run’s graph with node metadata.
53+
54+
Outcome: first persisted ScreenGraph snapshot per run.
55+
56+
5️⃣ Feature : Graph Viewer (UI Surface)
57+
58+
Why: humans need to see the system think.
59+
Stories
60+
61+
As a user, I can open /runs/:id/graph to see nodes (screens) + edges (actions).
62+
63+
As a viewer, I can click a node to open its screenshot + XML overlay.
64+
65+
As a dev, I can stream live node creation via SSE.
66+
67+
6️⃣ Feature : State Snapshot / Resume Point
68+
69+
Why: foundation for crash recovery + future diffs.
70+
Stories
71+
72+
As orchestrator, I serialize run state (checkpoint) after each node.
73+
74+
As worker, I can resume from last checkpoint on restart.
75+
76+
As analytics, I can compare checkpoints to detect structural drift.
77+
78+
7️⃣ Feature : Diff Scaffold (Stats-only Phase)
79+
80+
Why: prepare for M7 without complexity.
81+
Stories
82+
83+
As a worker, I compute basic hashes (sha256, phash) and store numeric deltas (nodeCountΔ, interactableΔ).
84+
85+
As analytics, I see “changed = true/false” per node.
86+
87+
As the UI, I badge nodes that changed.
88+
89+
Outcome: first cheap diff signal feeding your upcoming ux_quality model.
90+
91+
8️⃣ Feature : Run Replayer (Outbox → Replay → Graph)
92+
93+
Why: validates determinism + graph completeness.
94+
Stories
95+
96+
As a developer, I can re-emit persisted events from DB and rebuild the same graph.
97+
98+
As QA, I can diff live vs replay graph → expect identical structure/hashes.
99+
100+
9️⃣ Feature : Instrumentation & Metrics
101+
102+
Why: measure how well M6 works.
103+
Stories
104+
105+
As observability, I record counts: runs started, artifacts persisted, unique screens, graph size growth.
106+
107+
As dashboard, I chart “unique screens per run”, “artifact reuse rate”, “avg xml size”.
108+
109+
✅ Milestone 6 Exit Criteria
110+
Area Proof of Completion
111+
Persistence XML + screenshot blobs durably stored, checksum verified
112+
Outbox flow NodeFinished events stream artifact refs via SSE without loss
113+
Graph run_nodes and run_edges tables reconstruct a directed ScreenGraph
114+
Replayability Replaying events rebuilds identical graph and hashes
115+
Basic diff signal Each node emits a hash-based change flag
116+
UI Live Graph Viewer with screens and edges
117+
Metrics dashboard shows artifact reuse rate and unique screens count

docs/pr-check-failures.md

Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
# PR Check Failures Log
2+
3+
**Purpose**: Track instances where PRs were created without passing `pr:check` locally, or where local `pr:check` passed but CI failed. This log helps identify patterns, tooling gaps, and process improvements.
4+
5+
---
6+
7+
## Format
8+
9+
Each entry should include:
10+
- **Date**: When the PR was created
11+
- **PR Number**: GitHub PR link
12+
- **Branch**: Feature branch name
13+
- **Failure Type**: `local-pr-check-skipped` | `local-passed-ci-failed` | `both-failed`
14+
- **Root Cause**: Why it happened
15+
- **Impact**: What broke (build, tests, linting, e2e, etc.)
16+
- **Resolution**: How it was fixed
17+
- **Prevention**: What process/tooling change prevents recurrence
18+
19+
---
20+
21+
## Entries
22+
23+
### #71 - BullMQ + pg-listen Infrastructure (2025-10-20)
24+
25+
**PR**: [#71](https://github.com/nirukk52/supa-screengraph/pull/71)
26+
**Branch**: `feat/m5-bullmq-pg-listen`
27+
**Failure Type**: `local-pr-check-skipped`
28+
29+
#### Root Cause
30+
PR was pushed using `git push --no-verify` multiple times without running `pnpm run pr:check` locally. The `--no-verify` flag bypassed pre-push hooks that should have enforced `pr:check`.
31+
32+
#### What Broke
33+
1. **TypeScript Build (`build:backend`)**:
34+
- Missing project references for `@sg/queue-bullmq` in `tooling/typescript/tsconfig.backend.json`
35+
- Missing `composite: true` in queue/eventbus package `tsconfig.json` files
36+
- Missing path aliases in `tooling/typescript/base.json`
37+
- **Error**: `Cannot find module '@sg/queue-bullmq' or its corresponding type declarations`
38+
39+
2. **Playwright E2E (`e2e:ci`)**:
40+
- Port conflict (`EADDRINUSE: address already in use :::3000`)
41+
- Dev server was already running locally, blocking Playwright's web server startup
42+
- **Error**: `Failed to start server. Exit code: 1`
43+
44+
3. **Build Warnings**:
45+
- `DATABASE_URL must be set to start outbox worker` during Next.js build
46+
- Outbox worker attempted to start in build context without database
47+
48+
#### Impact
49+
- **CI**: Would have failed on `unit-tests` workflow with TS compilation errors
50+
- **Developer Experience**: Other developers pulling the branch would encounter immediate build failures
51+
- **Time Cost**: ~30 minutes to diagnose and fix TypeScript references after the fact
52+
53+
#### Resolution
54+
1. **TypeScript References** (committed):
55+
- Added `@sg/queue-bullmq` reference to `tooling/typescript/tsconfig.backend.json`
56+
- Added `composite: true` to:
57+
- `packages/queue/tsconfig.json`
58+
- `packages/queue-bullmq/tsconfig.json`
59+
- `packages/queue-inmemory/tsconfig.json`
60+
- `packages/eventbus-inmemory/tsconfig.json`
61+
- `packages/agents-contracts/tsconfig.json`
62+
- Added path aliases to `tooling/typescript/base.json`:
63+
```json
64+
"@sg/queue": ["../../packages/queue"],
65+
"@sg/queue-bullmq": ["../../packages/queue-bullmq"],
66+
"@sg/queue-inmemory": ["../../packages/queue-inmemory"]
67+
```
68+
- Added project references to `packages/features/agents-run/tsconfig.json`
69+
70+
2. **Port Conflict** (process fix):
71+
- Identified stray local dev server on port 3000
72+
- Killed process before rerunning `pr:check`
73+
- Alternative: Set `WEB_PORT=3100` in Playwright config for ephemeral port
74+
75+
3. **Database Warning** (pending):
76+
- Document as BUG-INFRA-005
77+
- Gate worker startup on `!process.env.E2E_TEST` in Next.js build context
78+
- Defer to follow-up PR
79+
80+
#### Prevention
81+
82+
**Process**:
83+
1. ❌ **NEVER use `--no-verify` unless explicitly instructed by the user**
84+
2. ✅ **ALWAYS run `pnpm run pr:check` before pushing** (enforced by workflow rule)
85+
3. ✅ **ALWAYS verify `pr:check` passes locally before opening PR**
86+
4. ✅ **Document any known failures in this log immediately**
87+
88+
**Tooling**:
89+
1. **Pre-push Hook Enhancement**:
90+
- `.husky/pre-push` should enforce `pr:check` run (not just lint/format)
91+
- Reject push if `pr:check` hasn't passed within last 5 minutes
92+
- Example: Track last successful `pr:check` timestamp in `.git/.pr-check-timestamp`
93+
94+
2. **CI Workflow**:
95+
- Add `validate-prs.yml` to run on feature branches (currently only runs on PRs to `main`)
96+
- Catch failures earlier in the development cycle
97+
98+
3. **Scaffold Templates**:
99+
- Auto-generate `composite: true` for new packages
100+
- Include queue/eventbus references in feature package templates
101+
- Update `tooling/scripts/scaffold/index.ts` to match
102+
103+
**Architecture**:
104+
1. **Dependency Graph Validation**:
105+
- Add `lint:deps` check for missing project references
106+
- Fail early if workspace dependencies aren't in `tsconfig.references`
107+
108+
2. **Environment Validation**:
109+
- Add runtime check in `outbox-publisher.ts` to skip startup if `DATABASE_URL` is missing during build
110+
- Log warning instead of throwing error in non-production contexts
111+
112+
#### Lessons Learned
113+
- `--no-verify` bypasses critical safety checks and should be avoided
114+
- TypeScript project references are fragile; scaffold templates must stay current
115+
- Local `pr:check` is the last line of defense before CI
116+
- Port conflicts are common in local development; ephemeral ports or process cleanup is essential
117+
118+
---
119+
120+
## Summary Stats
121+
122+
| Metric | Count |
123+
|--------|-------|
124+
| Total Failures | 1 |
125+
| `local-pr-check-skipped` | 1 |
126+
| `local-passed-ci-failed` | 0 |
127+
| `both-failed` | 0 |
128+
129+
---
130+
131+
## Related Documentation
132+
133+
- **PR Workflow**: `docs/guides/pr39-retro.md` (PR #39 best practices)
134+
- **CI Setup**: `.github/workflows/validate-prs.yml`
135+
- **Pre-push Hooks**: `.husky/pre-push`
136+
- **JIRA Workflow**: `docs/jira/CLAUDE.md`
137+
- **Tooling Reference**: `packages/CLAUDE.md`
138+
139+
---
140+
141+
## Notes
142+
143+
- This log is append-only; never delete entries
144+
- Update summary stats after each new entry
145+
- Link to specific bug tickets (BUG-*) when failures result in tracked issues
146+
- Include Claude-Update trailer when modifying this file
147+

packages/agents-contracts/tsconfig.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@
44
"rootDir": "src",
55
"outDir": "dist",
66
"declaration": true,
7-
"emitDeclarationOnly": false
7+
"emitDeclarationOnly": false,
8+
"composite": true
89
},
910
"include": ["src/**/*"],
1011
"exclude": ["dist", "node_modules", "tests"]

packages/database/package.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,16 @@
1414
"prisma": "6.17.1",
1515
"prisma-zod-generator": "^1.25.0"
1616
},
17-
"main": "./index.ts",
17+
"main": "./dist/index.js",
1818
"name": "@repo/database",
1919
"scripts": {
20+
"build": "tsc --outDir dist --declaration",
2021
"generate": "prisma generate --no-hints --schema=./prisma/schema.prisma",
2122
"push": "dotenv -c -e ../../.env -- prisma db push --skip-generate --schema=./prisma/schema.prisma",
2223
"migrate": "dotenv -c -e ../../.env -- prisma migrate dev --schema=./prisma/schema.prisma",
2324
"studio": "dotenv -c -e ../../.env -- prisma studio --schema=./prisma/schema.prisma",
2425
"type-check": "tsc --noEmit"
2526
},
26-
"types": "./**/.tsx",
27+
"types": "./dist/index.d.ts",
2728
"version": "0.0.0"
2829
}

packages/database/prisma/zod/.prisma-zod-generator-manifest.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"version": "1.0",
33
"generatorVersion": "unknown",
4-
"generatedAt": "2025-10-20T04:56:54.786Z",
4+
"generatedAt": "2025-10-20T08:19:22.967Z",
55
"outputPath": "/Users/priyankalalge/RealSaas/Screengraph/base/packages/database/prisma/zod",
66
"files": [
77
"index.ts"

packages/eventbus-inmemory/tsconfig.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@
44
"rootDir": "src",
55
"outDir": "dist",
66
"declaration": true,
7-
"emitDeclarationOnly": false
7+
"emitDeclarationOnly": false,
8+
"composite": true
89
},
910
"include": ["src/**/*"],
1011
"exclude": ["dist", "node_modules"]

packages/features/agents-run/src/application/usecases/stream-run.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { db } from "@repo/database/prisma/client";
1+
import { db } from "@repo/database";
22
import type { AgentEvent } from "@sg/agents-contracts";
33
import { EVENT_SOURCES, TOPIC_AGENTS_RUN } from "@sg/agents-contracts";
44
import { getInfra } from "../infra";

packages/features/agents-run/src/infra/repos/outbox-repo.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { db } from "@repo/database/prisma/client";
1+
import { db } from "@repo/database";
22

33
export const OutboxRepo = {
44
async getNextSeq(runId: string): Promise<number> {

packages/features/agents-run/src/infra/repos/run-event-repo.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { db } from "@repo/database/prisma/client";
1+
import { db } from "@repo/database";
22
import type { AgentEvent } from "@sg/agents-contracts";
33
import { AGENTS_RUN_OUTBOX_CHANNEL } from "../../application/constants";
44

packages/features/agents-run/src/infra/repos/run-repo.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { db } from "@repo/database/prisma/client";
1+
import { db } from "@repo/database";
22

33
export const RunRepo = {
44
async createRun(runId: string, startedAt: number): Promise<void> {

0 commit comments

Comments
 (0)