Skip to content

refactor: startup endpoint split + frontend decomposition + perf/bugfix#5

Merged
mabyes1 merged 9 commits into
masterfrom
refactor/startup-endpoint-groups
Jul 22, 2026
Merged

refactor: startup endpoint split + frontend decomposition + perf/bugfix#5
mabyes1 merged 9 commits into
masterfrom
refactor/startup-endpoint-groups

Conversation

@mabyes1

@mabyes1 mabyes1 commented Jul 22, 2026

Copy link
Copy Markdown
Owner

Summary

Backend (Startup.cs 1659→1163 lines)

  • Split low-risk endpoint groups into partial classes: Display, System, OnboardingAssets, Sideboard, Quotas, Streaming
  • Added host endpoint architecture doc with middleware pipeline diagram
  • Pinned DeviceTrustService pairing state-machine with 12 new tests (74 total, all green)

Frontend (index.js 5058→4996 lines, index.css 7873→6-file manifest)

  • Split index.css into 6 ordered @import partials (byte-identical concat proof)
  • Extracted 4 JS modules: device-credentials, client-instance, env-detect, eink-detect
  • Retired energy-wave canvas effect (45fps blur/shadow → no-op stub; pure CSS backgrounds remain)

Bug fix

  • Fixed black frame on initial connection: DXGI returning success+no-new-frame with uninitialized bitmap now falls through to GDI CopyFromScreen

Verification

  • 74/74 backend tests pass
  • node --check on all JS files
  • Dev-run asset probe all 200
  • Installed + ran on target machine via Setup
  • CSS split proven byte-identical via concatenation test

Not included (deliberate)

  • Security vertical (auth/connect/session/devices/pairing) stays inline until test seams exist
  • index.js closure-bound controllers (pairing, quota, stream UI) need factory refactor in future pass

mabyes1 added 9 commits July 22, 2026 16:41
… architecture map

Extract display/deck, system (health/capabilities), onboarding assets (qr + certs), sideboard, and quota endpoints from the Startup.cs UseEndpoints block into dedicated Startup.*.cs partials. Pure move: identical paths, auth gates, services, DTOs, status codes and JSON. Security vertical (auth/connect/session/devices+pairing), streaming, dashboard SSE and root stay inline pending test seams (see docs/technical-debt-roadmap.md). Startup.cs 1659->1239 lines; 62/62 Host tests pass.

Add docs/host-endpoint-architecture.md: middleware pipeline order, endpoint-group to service map, and the five Require* authorization gates.
Move /ws/display, /api/stream/webrtc/offer and /ws/input from Startup.cs into a new MapStreamingEndpoints in Startup.Streaming.cs, co-located with the StreamDisplayAsync/ReceiveInputAsync runtime loops they call. Pure move: same paths, TrustedDevice gate, services, status codes and JSON. ICE/TURN setup stays in MapStreamTransportEndpoints. 62/62 Host tests pass.
Add DeviceTrustPairingFlowTests covering deny path, poll pending/one-shot semantics, pending-approval list, request idempotency, approve-of-unknown/decided, token-based IsTrusted, revoke and clear. Service-level guardrails (no HTTP host, matching existing style) so the auth/pairing vertical can be split out of Startup.cs with a regression net. 74/74 tests pass.
index.css becomes a 6-line @import manifest loading css/00-base-tokens, 10-core, 20-pairing, 30-phone-dashboard, 40-eink-sideboard, 50-activity in the original cascade order. Verified byte-identical: concatenating the partials in order reproduces the original index.css exactly, and each partial is brace-balanced (no rule cut mid-body). No index.html change (single <link> still loads index.css); service worker is retired and there is no CSP, so @import load order == original cascade. Zero visual change by construction; large 10-core.css blob has no safe internal seam and is left for a later pass.
Move the pure cookie + device-token storage helpers (readCookie, writeCookie, writeDeviceCookies, loadStoredDeviceCredentials, load/saveDeviceTokenHistory) and their key constants verbatim into modules/device-credentials.js and import them back. Call sites are unchanged (ES import binds the same names). The stateful persistDeviceCredentials (mutates live deviceToken/deviceId) stays in index.js. Verified: node --check on both files, zero leftover definitions in index.js, 14 exports == 14 imports. Behavior confirmed at install-run (no frontend test harness).
…om index.js

client-instance.js: CLIENT_INSTANCE constants + getOrCreateClientInstanceId (imports readCookie/writeCookie from device-credentials). env-detect.js: isLoopbackHost + isIosUA/isIphoneUA/isMobileUA (pure UA/location primitives). eink-detect.js: EINK_PREF_KEY + readEinkQuery/readEinkCookie/looksLikeBooxScreen/detectEinkHardware. index.js wrappers (isIos/isIphone/isMobileClient) now delegate to env-detect primitives while keeping the devicePreview override path. node --check all 5 files pass, dev-run probes 200.
The animated bezier+blur canvas ran 6 blur+shadow paint calls at 45fps, causing visible lag on RDP and low-GPU machines. The sideboard already ships three pure-CSS background themes (zero runtime cost), making the canvas effect redundant. createEnergyWave() is now a no-op stub so callers don't break.
…rame

When DXGI Desktop Duplication returns success but hasNewFrame=false (desktop static), the bitmap buffer stays all-black if it was freshly allocated. This caused the 'connected but black screen' issue on phones. Fix: fall through to GDI CopyFromScreen when DXGI succeeds with no new frame AND the bitmap has never been populated. Also reset the flag when bitmap is reallocated (resolution change). 74/74 tests pass.
@mabyes1
mabyes1 merged commit 66fa066 into master Jul 22, 2026
1 check passed
@mabyes1
mabyes1 deleted the refactor/startup-endpoint-groups branch July 22, 2026 14:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant