refactor: stricter domain: server-directory
This commit is contained in:
@@ -14,14 +14,22 @@ server-directory/
|
||||
│ └── server-endpoint-state.service.ts Signal-based endpoint list, reconciliation with defaults, localStorage persistence
|
||||
│
|
||||
├── domain/
|
||||
│ ├── server-directory.models.ts ServerEndpoint, ServerInfo, ServerJoinAccessResponse, invite/ban/kick types
|
||||
│ ├── server-directory.constants.ts CLIENT_UPDATE_REQUIRED_MESSAGE
|
||||
│ └── server-endpoint-defaults.ts Default endpoint templates, URL sanitisation, reconciliation helpers
|
||||
│ ├── constants/
|
||||
│ │ └── server-directory.constants.ts CLIENT_UPDATE_REQUIRED_MESSAGE
|
||||
│ ├── logic/
|
||||
│ │ ├── room-signal-source.logic.ts Room → signal-source selector resolution
|
||||
│ │ ├── room-signal-source.logic.spec.ts Unit tests
|
||||
│ │ └── server-endpoint-defaults.logic.ts Default endpoint templates, URL sanitisation, reconciliation helpers
|
||||
│ └── models/
|
||||
│ └── server-directory.model.ts ServerEndpoint, ServerInfo, ServerJoinAccessResponse, invite/ban/kick types
|
||||
│
|
||||
├── infrastructure/
|
||||
│ ├── constants/
|
||||
│ │ └── server-directory.infrastructure.constants.ts Health-check timeout, localStorage keys
|
||||
│ └── services/
|
||||
│ ├── server-directory-api.service.ts HTTP client for all server API calls
|
||||
│ ├── server-endpoint-health.service.ts Health probe (GET /api/health with 5 s timeout, fallback to /api/servers)
|
||||
│ ├── server-endpoint-compatibility.service.ts Semantic version comparison for client/server compatibility
|
||||
│ ├── server-endpoint-health.service.ts Health probe (GET /api/health with 5 s timeout, fallback to /api/servers)
|
||||
│ └── server-endpoint-storage.service.ts localStorage read/write for endpoint list and removed-default tracking
|
||||
│
|
||||
├── feature/
|
||||
@@ -45,8 +53,8 @@ graph TD
|
||||
Health[ServerEndpointHealthService]
|
||||
Compat[ServerEndpointCompatibilityService]
|
||||
Storage[ServerEndpointStorageService]
|
||||
Defaults[server-endpoint-defaults]
|
||||
Models[server-directory.models]
|
||||
Defaults[server-endpoint-defaults.logic]
|
||||
Models[server-directory.model]
|
||||
|
||||
Facade --> Service
|
||||
Service --> API
|
||||
@@ -61,12 +69,12 @@ graph TD
|
||||
click Facade "application/facades/server-directory.facade.ts" "Thin domain boundary" _blank
|
||||
click Service "application/services/server-directory.service.ts" "Orchestrator" _blank
|
||||
click State "application/services/server-endpoint-state.service.ts" "Signal-based endpoint state" _blank
|
||||
click API "infrastructure/server-directory-api.service.ts" "HTTP client for server API" _blank
|
||||
click Health "infrastructure/server-endpoint-health.service.ts" "Health probe" _blank
|
||||
click Compat "infrastructure/server-endpoint-compatibility.service.ts" "Version compatibility" _blank
|
||||
click Storage "infrastructure/server-endpoint-storage.service.ts" "localStorage persistence" _blank
|
||||
click Defaults "domain/server-endpoint-defaults.ts" "Default endpoint templates" _blank
|
||||
click Models "domain/server-directory.models.ts" "Domain types" _blank
|
||||
click API "infrastructure/services/server-directory-api.service.ts" "HTTP client for server API" _blank
|
||||
click Health "infrastructure/services/server-endpoint-health.service.ts" "Health probe" _blank
|
||||
click Compat "infrastructure/services/server-endpoint-compatibility.service.ts" "Version compatibility" _blank
|
||||
click Storage "infrastructure/services/server-endpoint-storage.service.ts" "localStorage persistence" _blank
|
||||
click Defaults "domain/logic/server-endpoint-defaults.logic.ts" "Default endpoint templates" _blank
|
||||
click Models "domain/models/server-directory.model.ts" "Domain types" _blank
|
||||
```
|
||||
|
||||
## Endpoint lifecycle
|
||||
|
||||
@@ -6,7 +6,7 @@ import {
|
||||
import { Observable } from 'rxjs';
|
||||
import { STORAGE_KEY_CONNECTION_SETTINGS } from '../../../../core/constants';
|
||||
import { User } from '../../../../shared-kernel';
|
||||
import { ServerDirectoryApiService } from '../../infrastructure/server-directory-api.service';
|
||||
import { ServerDirectoryApiService } from '../../infrastructure/services/server-directory-api.service';
|
||||
import type {
|
||||
BanServerMemberRequest,
|
||||
CreateServerInviteRequest,
|
||||
@@ -19,15 +19,15 @@ import type {
|
||||
ServerJoinAccessResponse,
|
||||
ServerSourceSelector,
|
||||
UnbanServerMemberRequest
|
||||
} from '../../domain/server-directory.models';
|
||||
} from '../../domain/models/server-directory.model';
|
||||
import {
|
||||
buildRoomSignalSelector,
|
||||
buildRoomSignalSource,
|
||||
type RoomSignalSource,
|
||||
type RoomSignalSourceInput
|
||||
} from '../../domain/room-signal-source';
|
||||
import { ServerEndpointCompatibilityService } from '../../infrastructure/server-endpoint-compatibility.service';
|
||||
import { ServerEndpointHealthService } from '../../infrastructure/server-endpoint-health.service';
|
||||
} from '../../domain/logic/room-signal-source.logic';
|
||||
import { ServerEndpointCompatibilityService } from '../../infrastructure/services/server-endpoint-compatibility.service';
|
||||
import { ServerEndpointHealthService } from '../../infrastructure/services/server-endpoint-health.service';
|
||||
import { ServerEndpointStateService } from './server-endpoint-state.service';
|
||||
|
||||
@Injectable({ providedIn: 'root' })
|
||||
|
||||
@@ -16,14 +16,14 @@ import {
|
||||
hasEndpointForDefault,
|
||||
matchDefaultEndpointTemplate,
|
||||
sanitiseServerBaseUrl
|
||||
} from '../../domain/server-endpoint-defaults';
|
||||
import { ServerEndpointStorageService } from '../../infrastructure/server-endpoint-storage.service';
|
||||
} from '../../domain/logic/server-endpoint-defaults.logic';
|
||||
import { ServerEndpointStorageService } from '../../infrastructure/services/server-endpoint-storage.service';
|
||||
import type {
|
||||
ConfiguredDefaultServerDefinition,
|
||||
DefaultEndpointTemplate,
|
||||
ServerEndpoint,
|
||||
ServerEndpointVersions
|
||||
} from '../../domain/server-directory.models';
|
||||
} from '../../domain/models/server-directory.model';
|
||||
|
||||
function resolveDefaultHttpProtocol(): 'http' | 'https' {
|
||||
return typeof window !== 'undefined' && window.location?.protocol === 'https:'
|
||||
|
||||
@@ -3,7 +3,7 @@ import {
|
||||
buildRoomSignalSelector,
|
||||
buildRoomSignalSource,
|
||||
getSourceUrlFromSignalingUrl
|
||||
} from './room-signal-source';
|
||||
} from './room-signal-source.logic';
|
||||
|
||||
describe('room-signal-source helpers', () => {
|
||||
it('converts signaling urls back to normalized source urls', () => {
|
||||
@@ -1,5 +1,5 @@
|
||||
import type { ServerEndpoint, ServerSourceSelector } from './server-directory.models';
|
||||
import { normaliseConfiguredServerUrl, sanitiseServerBaseUrl } from './server-endpoint-defaults';
|
||||
import type { ServerEndpoint, ServerSourceSelector } from '../models/server-directory.model';
|
||||
import { normaliseConfiguredServerUrl, sanitiseServerBaseUrl } from './server-endpoint-defaults.logic';
|
||||
|
||||
export interface RoomSignalSource {
|
||||
sourceId?: string;
|
||||
@@ -3,7 +3,7 @@ import type {
|
||||
DefaultEndpointTemplate,
|
||||
DefaultServerDefinition,
|
||||
ServerEndpoint
|
||||
} from './server-directory.models';
|
||||
} from '../models/server-directory.model';
|
||||
|
||||
export function sanitiseServerBaseUrl(rawUrl: string): string {
|
||||
let cleaned = rawUrl.trim().replace(/\/+$/, '');
|
||||
@@ -3,7 +3,7 @@ import type {
|
||||
ChannelPermissionOverride,
|
||||
RoomRole,
|
||||
RoomRoleAssignment
|
||||
} from '../../../shared-kernel';
|
||||
} from '../../../../shared-kernel';
|
||||
|
||||
export type ServerEndpointStatus = 'online' | 'offline' | 'checking' | 'unknown' | 'incompatible';
|
||||
|
||||
@@ -11,7 +11,7 @@ import { Store } from '@ngrx/store';
|
||||
import { RoomsActions } from '../../../../store/rooms/rooms.actions';
|
||||
import { UsersActions } from '../../../../store/users/users.actions';
|
||||
import { selectCurrentUser } from '../../../../store/users/users.selectors';
|
||||
import type { ServerInviteInfo } from '../../domain/server-directory.models';
|
||||
import type { ServerInviteInfo } from '../../domain/models/server-directory.model';
|
||||
import { STORAGE_KEY_CURRENT_USER_ID } from '../../../../core/constants';
|
||||
import { DatabaseService } from '../../../../infrastructure/persistence';
|
||||
import { ServerDirectoryFacade } from '../../application/facades/server-directory.facade';
|
||||
|
||||
@@ -36,7 +36,7 @@ import {
|
||||
import { Room, User } from '../../../../shared-kernel';
|
||||
import { SettingsModalService } from '../../../../core/services/settings-modal.service';
|
||||
import { DatabaseService } from '../../../../infrastructure/persistence';
|
||||
import { type ServerInfo } from '../../domain/server-directory.models';
|
||||
import { type ServerInfo } from '../../domain/models/server-directory.model';
|
||||
import { ServerDirectoryFacade } from '../../application/facades/server-directory.facade';
|
||||
import { selectCurrentUser } from '../../../../store/users/users.selectors';
|
||||
import { ConfirmDialogComponent } from '../../../../shared';
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
export * from './application/facades/server-directory.facade';
|
||||
export * from './domain/server-directory.constants';
|
||||
export * from './domain/server-directory.models';
|
||||
export * from './domain/room-signal-source';
|
||||
export * from './domain/constants/server-directory.constants';
|
||||
export * from './domain/models/server-directory.model';
|
||||
export * from './domain/logic/room-signal-source.logic';
|
||||
|
||||
@@ -15,8 +15,8 @@ import {
|
||||
RoomRole,
|
||||
RoomRoleAssignment,
|
||||
User
|
||||
} from '../../../shared-kernel';
|
||||
import { ServerEndpointStateService } from '../application/services/server-endpoint-state.service';
|
||||
} from '../../../../shared-kernel';
|
||||
import { ServerEndpointStateService } from '../../application/services/server-endpoint-state.service';
|
||||
import type {
|
||||
BanServerMemberRequest,
|
||||
CreateServerInviteRequest,
|
||||
@@ -28,8 +28,8 @@ import type {
|
||||
ServerJoinAccessResponse,
|
||||
ServerSourceSelector,
|
||||
UnbanServerMemberRequest
|
||||
} from '../domain/server-directory.models';
|
||||
import type { RoomSignalSourceInput } from '../domain/room-signal-source';
|
||||
} from '../../domain/models/server-directory.model';
|
||||
import type { RoomSignalSourceInput } from '../../domain/logic/room-signal-source.logic';
|
||||
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class ServerDirectoryApiService {
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Injectable, inject } from '@angular/core';
|
||||
import { ElectronBridgeService } from '../../../core/platform/electron/electron-bridge.service';
|
||||
import type { ServerVersionCompatibilityResult } from '../domain/server-directory.models';
|
||||
import { ElectronBridgeService } from '../../../../core/platform/electron/electron-bridge.service';
|
||||
import type { ServerVersionCompatibilityResult } from '../../domain/models/server-directory.model';
|
||||
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class ServerEndpointCompatibilityService {
|
||||
@@ -1,10 +1,10 @@
|
||||
import { Injectable, inject } from '@angular/core';
|
||||
import { SERVER_HEALTH_CHECK_TIMEOUT_MS } from './server-directory.infrastructure.constants';
|
||||
import { SERVER_HEALTH_CHECK_TIMEOUT_MS } from '../constants/server-directory.infrastructure.constants';
|
||||
import type {
|
||||
ServerEndpoint,
|
||||
ServerEndpointHealthResult,
|
||||
ServerHealthCheckPayload
|
||||
} from '../domain/server-directory.models';
|
||||
} from '../../domain/models/server-directory.model';
|
||||
import { ServerEndpointCompatibilityService } from './server-endpoint-compatibility.service';
|
||||
|
||||
@Injectable({ providedIn: 'root' })
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { REMOVED_DEFAULT_SERVER_KEYS_STORAGE_KEY, SERVER_ENDPOINTS_STORAGE_KEY } from './server-directory.infrastructure.constants';
|
||||
import type { ServerEndpoint } from '../domain/server-directory.models';
|
||||
import { REMOVED_DEFAULT_SERVER_KEYS_STORAGE_KEY, SERVER_ENDPOINTS_STORAGE_KEY } from '../constants/server-directory.infrastructure.constants';
|
||||
import type { ServerEndpoint } from '../../domain/models/server-directory.model';
|
||||
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class ServerEndpointStorageService {
|
||||
Reference in New Issue
Block a user