4.6 KiB
4.6 KiB
Tasks: enterprise-react-iphone
Change ID: enterprise-react-iphone
Package: @suaveplan/react-iphone
Target path: react/ui/react-iphone
Prerequisite packages on Verdaccio: @suaveplan/error, @suaveplan/events, @suaveplan/logger, @suaveplan/react-translate, @suaveplan/react-ui
0. Pre-flight (non-negotiable)
- 0.1 Confirm clean working tree (
git statusreports nothing) and no in-flight worktrees with uncommitted work (git worktree listthengit statusin each) - 0.2 If any worktrees exist under
.claude/worktrees/, account for each one: still-active agent, work-pending-merge, or stale-and-prune. Stale worktrees MUST be removed (git worktree remove) before opening a new one — code that has been lost twice on main is the failure mode this guards against. - 0.3 Confirm the package set in
MANIFEST.mdmatchesfind packages -maxdepth 3 -name package.jsoncount. Drift here means a prior change archived without regenerating the manifest.
1. Scaffold
- Create directory tree per proposal layout.
- Write
package.jsonat0.1.0with"sideEffects": false, exports map. - Dependencies:
@suaveplan/error workspace:^,@suaveplan/events workspace:^,@suaveplan/logger workspace:^,@suaveplan/react-translate workspace:^,@suaveplan/react-ui workspace:^,zod catalog:forms,@opentelemetry/api catalog:observability,tslib catalog:build. - Write
tsconfig.json,vitest.config.ts, scripts.
2. Error codes and types
- Define
CallErrorextendingSuaveplanError; codes:CALL_SIGNALING_FAILED,CALL_WEBRTC_FAILED,CALL_MANAGER_NOT_INITIALIZED. - Define public types:
CallState,CallDirection,CallInfo,SignalingMessage,WebRTCConfig,HookExecutionMode,ConnectionQuality,IceState,SignalingState.
3. Services
CallManager
- Basic call state machine:
idle → ringing → active → ended.startCall(),acceptCall(),rejectCall(),endCall(). Emits events via@suaveplan/events. OTel spans for each transition. - Write test + md.
CallManagerEnhanced
- Extends
CallManagerwithconnectionQuality(derived from ICE stats — not hardcoded),iceState,signalingState— all real implementations. - Write test + md.
CallManagerWebRTC
- Wraps
WebRTCProvider, wires ICE + SDP negotiation intoCallManagerstate machine. - Write test (mock
RTCPeerConnectionvia DI) + md.
HookManager
- Sync + async hook pipeline (
HookExecutionMode).register(hook),execute(event): Promise<void>. - Write test + md.
SignalingClient + SignalingChannelAdapter
- WebSocket-backed signaling;
connect(),disconnect(),send(message),onMessage(handler). - Throws
CallError(CALL_SIGNALING_FAILED)on connection failure. - Write test (real WebSocket via
@suaveplan/testingmock server or real WS) + md.
WebRTCProvider
- Manages
RTCPeerConnection;createOffer(),setRemoteDescription(),addIceCandidate(). - Throws
CallError(CALL_WEBRTC_FAILED)on failure. - Write test (DI-injected
RTCPeerConnectionconstructor) + md.
PhoneStateSerializer + ServerStateManager
PhoneStateSerializer— serializes/deserializes call state for server snapshot sync.ServerStateManager— manages server-side state deltas.- Write test + md for each.
4. Hooks
useCallManager— wrapsCallManagerevents viauseSyncExternalStore, returns call state + actions.useCallTimer— elapsed-time counter (seconds) whilecallState === 'active'.- Write tests + stories (playground for each) + md.
5. Components
For each screen (IncomingCallScreen, OutgoingCallScreen, ActiveCallScreen, EndedCallScreen):
- Implement with i18n via
useTranslation. OTel span on mount. - Write test + stories (default, loading/connecting, error, playground) + md.
For video components (VideoStreamRenderer, AudioOnlyContainer, CallVideoContainer):
- Write test + stories + md.
For CallButton + icons:
- Write test + stories + md.
6. E2E
e2e/call-flow.spec.ts— Playwright with injected mockWebRTCProvider+SignalingClient:- Render
IncomingCallScreen, click accept →ActiveCallScreenshown. - Render
ActiveCallScreen, click end →EndedCallScreenshown. - Timer increments during active call.
- Render
7. Verify and publish
bunx turbo lint typecheck test --filter=@suaveplan/react-iphone— green.bunx turbo test:coverage --filter=@suaveplan/react-iphone— 100%.bun scripts/publish.ts --package @suaveplan/react-iphone.- Archive change folder.