Files
Toju/docs/architecture.md
2026-03-20 03:05:29 +01:00

10 KiB

Frontend Architecture

This document defines the target structure for the Angular renderer and the boundaries between web-safe code, Electron adapters, reusable logic, and feature UI.

Goals

  • Keep feature code easy to navigate by grouping it around user-facing domains.
  • Push platform-specific behavior behind explicit adapters.
  • Move pure logic into helpers and dedicated model files instead of embedding it in components and large services.
  • Split large services into smaller units with one clear responsibility each.

Target Structure

src/app/
  app.ts
  domains/
    <domain>/
      application/           # facades and use-case orchestration
      domain/                # models and pure domain logic
      infrastructure/        # adapters, api clients, persistence
      feature/               # smart domain UI containers
      ui/                    # dumb/presentational domain UI
  infrastructure/
    persistence/            # shared storage adapters and persistence facades
    realtime/               # shared signaling, peer transport, media runtime state
  core/
    constants.ts             # cross-domain technical constants only
    helpers/                 # transitional pure helpers still being moved out
    models/                  # reusable cross-domain contracts only
    platform/
      platform.service.ts    # runtime/environment detection adapters
      external-link.service.ts # browser/electron navigation adapters
      electron/              # renderer-side adapters for preload / Electron APIs
    realtime/                # compatibility/public import boundary for realtime
    services/               # technical cross-domain services only
  features/                  # transitional feature area while slices move into domains/*/feature
  shared/
    ui/                      # shared presentational primitives
    utils/                   # shared pure utilities
  store/                     # ngrx reducers, effects, selectors, actions

Layering Rules

Dependency direction must stay one-way:

  1. domains/*/feature, domains/*/ui, and transitional features/ may depend on domains/, infrastructure/, core/, shared/, and store/.
  2. domains/*/application may depend on its own domain/, infrastructure/, top-level infrastructure/, core/, and store/.
  3. domains/*/domain should stay framework-light and hold domain models plus pure logic.
  4. domains/*/infrastructure may depend on core/platform/, browser APIs, HTTP, persistence, and external adapters.
  5. Top-level infrastructure/ should hold shared technical runtime implementations; core/ should hold cross-domain utilities, compatibility entry points, and platform adapters rather than full runtime subsystems.
  6. core/models/ should only hold shared cross-domain contracts. Domain-specific models belong inside their domain folder.

Responsibility Split

Use these roles consistently when a domain starts to absorb too many concerns:

  • application: Angular-facing facades and use-case orchestration.
  • domain: contracts, policies, calculations, mapping rules, and other pure domain logic.
  • infrastructure: platform adapters, storage, transport, HTTP, IPC, and persistence boundaries.
  • feature: smart components that wire store, routing, and facades.
  • ui: presentational components with minimal business knowledge.

Platform Boundary

Renderer code should not access window.electronAPI directly except inside the Electron adapter layer.

Current convention:

  • Use core/platform/electron/electron-api.models.ts for Angular-side Electron typings.
  • Use core/platform/electron/electron-bridge.service.ts to reach preload APIs from Angular code.
  • Keep runtime detection and browser/Electron wrappers such as core/platform/platform.service.ts and core/platform/external-link.service.ts inside core/platform/ rather than core/services/.
  • Keep Electron-only persistence and file-system logic inside dedicated adapter services such as domains/attachment/infrastructure/attachment-storage.service.ts.

This keeps feature and domain code platform-agnostic and makes the browser runtime easier to reason about.

Models And Pure Logic

  • Attachment runtime types now live in domains/attachment/domain/attachment.models.ts.
  • Attachment download-policy rules now live in domains/attachment/domain/attachment.logic.ts.
  • Attachment file-path sanitizing and storage-bucket selection live in domains/attachment/infrastructure/attachment-storage.helpers.ts.
  • New domain types should be placed in a dedicated model file inside their domain folder when they are not shared across domains.
  • Only cross-domain contracts should stay in core/models/.

Incremental Refactor Path

The repo is large enough that refactoring must stay incremental. Preferred order:

  1. Extract platform adapters from direct renderer global access.
  2. Split persistence and cache behavior out of large orchestration services.
  3. Move reusable types and helper logic into dedicated files.
  4. Break remaining multi-responsibility facades into managers or coordinators.

Current Baseline

The current refactor establishes these patterns:

  • Shared Electron bridge for Angular services and root app wiring.
  • Attachment now lives under domains/attachment/ with application/attachment.facade.ts as the public Angular-facing boundary.
  • Attachment application orchestration is now split across domains/attachment/application/attachment-manager.service.ts, attachment-transfer.service.ts, attachment-persistence.service.ts, and attachment-runtime.store.ts.
  • Attachment runtime types and pure transfer-policy logic live in domains/attachment/domain/.
  • Attachment disk persistence and storage helpers live in domains/attachment/infrastructure/.
  • Shared browser/Electron persistence adapters now live in infrastructure/persistence/, with DatabaseService as the renderer-facing facade over IndexedDB and Electron CQRS-backed SQLite.
  • Auth HTTP/login orchestration now lives under domains/auth/application/auth.service.ts.
  • Chat GIF search and KLIPY integration now live under domains/chat/application/klipy.service.ts.
  • Voice-session now lives under domains/voice-session/ with application/voice-session.facade.ts as the public Angular-facing boundary.
  • Voice-session models and pure route/room mapping logic live in domains/voice-session/domain/.
  • Voice workspace UI state now lives in domains/voice-session/application/voice-workspace.service.ts, and persisted voice/screen-share preferences now live in domains/voice-session/infrastructure/voice-settings.storage.ts.
  • Voice activity tracking now lives in domains/voice-connection/application/voice-activity.service.ts.
  • Server-directory now lives under domains/server-directory/ with application/server-directory.facade.ts as the public Angular-facing boundary.
  • Server-directory endpoint state now lives in domains/server-directory/application/server-endpoint-state.service.ts.
  • Server-directory contracts and user-facing compatibility messaging live in domains/server-directory/domain/.
  • Endpoint default URL normalization and built-in endpoint templates live in domains/server-directory/domain/server-endpoint-defaults.ts.
  • Endpoint localStorage persistence, HTTP fan-out, compatibility checks, and health probes live in domains/server-directory/infrastructure/.
  • infrastructure/realtime/realtime-session.service.ts now holds the shared realtime runtime service.
  • core/realtime/index.ts is the compatibility/public import surface and re-exports that runtime service as RealtimeSessionFacade for technical cross-domain consumers.
  • domains/voice-connection/ now exposes application/voice-connection.facade.ts as the voice-specific Angular-facing boundary.
  • domains/screen-share/ now exposes application/screen-share.facade.ts plus application/screen-share-source-picker.service.ts, and domain/screen-share.config.ts is the real source for screen-share presets/options plus ELECTRON_ENTIRE_SCREEN_SOURCE_NAME.
  • Shared transport contracts and the low-level signaling and peer-connection stack now live under infrastructure/realtime/.
  • Realtime debug network metric collection now lives in infrastructure/realtime/logging/debug-network-metrics.ts; the debug console reads that infrastructure state rather than keeping the metric store inside core/services/.
  • Shared media handling, voice orchestration helpers, noise reduction, and screen-share capture adapters now live in infrastructure/realtime/media/.
  • The old domains/webrtc/* and core/services/webrtc.service.ts compatibility shims have been removed after all in-repo callers moved to core/realtime, domains/voice-connection/, and domains/screen-share/.
  • Multi-server signaling topology and signaling-manager lifecycle extracted from WebRTCService into ServerSignalingCoordinator.
  • Angular-facing signal and connection-state bookkeeping extracted from WebRTCService into WebRtcStateController.
  • Peer/media event streams, peer messaging, remote stream access, and screen-share entry points extracted from WebRTCService into PeerMediaFacade.
  • Lower-level signaling connect/send/identify helpers extracted from WebRTCService into SignalingTransportHandler.
  • Incoming signaling message semantics extracted from WebRTCService into IncomingSignalingMessageHandler.
  • Outbound server-membership signaling commands extracted from WebRTCService into ServerMembershipSignalingHandler.
  • Remote screen-share request state and control-plane handling extracted from WebRTCService into RemoteScreenShareRequestController.
  • Voice session and heartbeat orchestration extracted from WebRTCService into VoiceSessionController.
  • Desktop client-version lookup and endpoint compatibility checks for server-directory live in domains/server-directory/infrastructure/server-endpoint-compatibility.service.ts.
  • Endpoint health probing and fallback transport for server-directory live in domains/server-directory/infrastructure/server-endpoint-health.service.ts.
  • Server-directory HTTP fan-out, endpoint resolution, and API response normalization live in domains/server-directory/infrastructure/server-directory-api.service.ts.

Next Candidates

  • Migrate remaining voice and room UI from transitional features/ into domain-local feature/ and ui/ folders.
  • Migrate remaining WebRTC-facing UI from transitional features/ and shared/ locations into domain-local feature/ and ui/ folders where it improves ownership.