139 lines
10 KiB
Markdown
139 lines
10 KiB
Markdown
# 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
|
|
|
|
```text
|
|
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. |