7.0 KiB
SSE Refresh Noise Reduction Implementation Plan
For agentic workers: REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (
- [ ]) syntax for tracking.
Goal: Reduce unnecessary realtime reloads on scoped conversation folder pages without breaking global conversation refresh behavior.
Architecture: Keep server-side event names stable and narrow consumption at scoped clients. The shared Web realtime refresh utility accepts optional device scope, while the Android folder activity applies the same project-first, device-only fallback filter.
Tech Stack: Next.js App Router, TypeScript node:test, Android Java native activities, Server-Sent Events.
Task 1: Add Device Scope To Shared Web Refresh Filtering
Files:
-
Modify:
src/lib/realtime-refresh.ts -
Test:
tests/realtime-refresh-utils.test.ts -
Step 1: Write the failing tests
assert.equal(
shouldRefreshRealtimeEvent({
eventType: "conversation.updated",
eventData: JSON.stringify({ deviceId: "mac-studio" }),
projectIds: ["project-a", "project-b"],
deviceId: "mac-studio",
}),
true,
);
assert.equal(
shouldRefreshRealtimeEvent({
eventType: "conversation.updated",
eventData: JSON.stringify({ deviceId: "windows-box" }),
projectIds: ["project-a", "project-b"],
deviceId: "mac-studio",
}),
false,
);
- Step 2: Run the focused test and verify the new device-scope test fails
Run: npx tsx --test tests/realtime-refresh-utils.test.ts
Expected: the new device-scope case fails before deviceId support exists in RealtimeRefreshScope.
- Step 3: Add minimal device scope support
export interface RealtimeRefreshScope {
projectId?: string;
projectIds?: string[];
deviceId?: string;
deviceIds?: string[];
conversationUpdatedNotes?: string[];
}
Then parse deviceId from the JSON payload and require scoped listeners to match at least one scoped project or device identifier before refreshing.
- Step 4: Run the focused test and verify it passes
Run: npx tsx --test tests/realtime-refresh-utils.test.ts
Expected: all realtime refresh utility tests pass.
Task 2: Wire Web Folder Device Scope
Files:
-
Modify:
src/components/app-runtime.tsx -
Modify:
src/app/conversations/folders/[folderKey]/page.tsx -
Test:
tests/project-scoped-realtime-refresh.test.ts -
Step 1: Write the failing route wiring assertion
assert.match(
folderPage,
/deviceId=\{folder\.deviceId\}/,
"expected folder page to scope device-only refreshes to the folder device",
);
- Step 2: Run the route test and verify the assertion fails
Run: npx tsx --test tests/project-scoped-realtime-refresh.test.ts
Expected: the assertion fails until the folder page passes deviceId.
- Step 3: Pass device scope through the runtime component
<RealtimeRefresh
projectIds={folder.threads.map((thread) => thread.projectId)}
deviceId={folder.deviceId}
events={["conversation.updated", "project.messages.updated"]}
/>
Also pass deviceId and deviceIds from RealtimeRefresh into shouldRefreshRealtimeEvent.
- Step 4: Run the route test and verify it passes
Run: npx tsx --test tests/project-scoped-realtime-refresh.test.ts
Expected: the folder route wiring test passes.
Task 3: Mirror Filtering In Android Folder Activity
Files:
-
Modify:
android/app/src/main/java/com/hyzq/boss/ConversationFolderActivity.java -
Test:
tests/android-folder-realtime-refresh.test.ts -
Step 1: Write the failing Android source assertion
assert.match(
source,
/String payloadDeviceId = event\.payload\.optString\("deviceId", ""\)\.trim\(\);/,
"expected folder activity to inspect device-scoped realtime payloads",
);
- Step 2: Run the Android static test and verify it fails
Run: npx tsx --test tests/android-folder-realtime-refresh.test.ts
Expected: the test fails until the folder activity reads deviceId.
- Step 3: Add project-first and device-only filtering
String payloadProjectId = event.payload.optString("projectId", "").trim();
if (!payloadProjectId.isEmpty()) {
return trackedProjectIds.contains(payloadProjectId)
|| (!targetProjectIds.isEmpty() && targetProjectIds.contains(payloadProjectId))
|| (targetProjectId != null && targetProjectId.equals(payloadProjectId));
}
String payloadDeviceId = event.payload.optString("deviceId", "").trim();
if (payloadDeviceId.isEmpty() || folderDeviceId == null || folderDeviceId.isEmpty()) {
return false;
}
return payloadDeviceId.equals(folderDeviceId);
- Step 4: Run the Android static test and verify it passes
Run: npx tsx --test tests/android-folder-realtime-refresh.test.ts
Expected: the Android folder realtime filtering test passes.
Task 4: Verify Integration
Files:
-
Verify:
src/lib/realtime-refresh.ts -
Verify:
src/components/app-runtime.tsx -
Verify:
src/app/conversations/folders/[folderKey]/page.tsx -
Verify:
android/app/src/main/java/com/hyzq/boss/ConversationFolderActivity.java -
Verify:
scripts/deploy-server.sh -
Step 1: Run focused realtime tests
Run: npx tsx --test tests/realtime-refresh-utils.test.ts tests/project-scoped-realtime-refresh.test.ts tests/android-folder-realtime-refresh.test.ts
Expected: all focused realtime tests pass.
- Step 2: Run deployment script guard test
Run: npx tsx --test tests/deploy-server-script.test.ts
Expected: the deploy script tests pass and assert .project, .classpath, and .settings are excluded from rsync.
- Step 3: Run broader realtime page tests
Run: npx tsx --test tests/realtime-refresh-utils.test.ts tests/project-scoped-realtime-refresh.test.ts tests/android-folder-realtime-refresh.test.ts tests/config-pages-realtime-refresh.test.ts tests/config-state-events.test.ts tests/settings-page-realtime-refresh.test.ts tests/settings-state-events.test.ts tests/status-pages-realtime-refresh.test.ts
Expected: all selected realtime and event contract tests pass.
- Step 4: Run project gates
Run: npm run lint
Expected: lint exits 0.
Run: npm run build
Expected: production build exits 0.
- Step 5: Stage only intended files
git add src/lib/realtime-refresh.ts src/components/app-runtime.tsx 'src/app/conversations/folders/[folderKey]/page.tsx' tests/realtime-refresh-utils.test.ts tests/project-scoped-realtime-refresh.test.ts tests/android-folder-realtime-refresh.test.ts android/app/src/main/java/com/hyzq/boss/ConversationFolderActivity.java scripts/deploy-server.sh tests/deploy-server-script.test.ts docs/superpowers/specs/2026-04-10-sse-refresh-noise-reduction-design.md docs/superpowers/plans/2026-04-10-sse-refresh-noise-reduction.md
Expected: generated IDE metadata under android/.project, android/.settings, android/app/.project, android/app/.settings, and android/app/.classpath remains untracked.