Skip to content

Data Integration Architecture

KrugarValdes edited this page Jan 19, 2026 · 1 revision

Data Integration Architecture

This document outlines the data integration stack inside the TV client: HTTP communication, repository contracts, DTO-to-domain mapping, caching strategies, dependency injection, and the error-handling patterns that keep autoplay features resilient. Use it alongside the TV App overview for cross-feature context and the navigation guide for UI flows.

Overview

The TV application follows a clean three-tier design built on Kotlin Multiplatform. Remote data access, domain logic, and presentation stay isolated so each feature module (Stories, Photos, Events) can evolve independently. The stack emphasizes:

  • A shared HTTP layer powered by a tuned Ktor client.
  • Repositories that expose type-safe models while hiding transport concerns.
  • Mappers that normalize DTOs and enrich them with derived business fields.
  • Functional error propagation using Either/sealed results instead of unchecked exceptions.
  • Multi-level caching (in-memory, disk, snapshot payloads) for offline safety.
  • Dependency injection via modular Koin definitions.

Architecture Overview

architecture-overview.svg

Tier Breakdown

Tier Responsibilities Typical Artifacts
Data Remote APIs, DTOs, mappers, caches Ktor clients, repository implementations
Domain Business contracts, aggregators, feature services Repository interfaces, data providers, validation rules
Presentation Autoplay components, feature controllers, UI state machines Feature components, intent/state models

End-to-End Flow

  1. Autoplay feature requests content from a domain-facing provider.
  2. Provider coordinates one or more repositories (Stories, Photos, Events).
  3. Repositories call API clients, map DTOs into domain models, and enrich data.
  4. Domain models flow into Compose state, with caching + retry along the path.

Data Layer Details

Each feature module contains a self-contained data stack:

Component Purpose
API Client Performs HTTP calls with typed requests
DTO Mirrors backend payloads for serialization
Mapper Converts DTOs to stable domain models
Repository Applies caching, error handling, exposure

Domain Layer

  • Repository interfaces define contracts the presentation tier consumes.
  • Domain models describe business entities shared across features (e.g., stories, teammates, events, photos).
  • Data providers (like the Stories provider) coordinate multiple repositories, merge records, and emit payloads plus warnings.

Presentation Layer

  • Feature controllers depend only on domain interfaces.
  • Autoplay component requests data via providers, observes flows, and manages UI state transitions.
  • Error states surface as banners or diagnostics cards without leaking transport details.

HTTP Communication Layer

HttpClient Configuration

Setting Value / Behavior Purpose
Timeouts 40s request/connect/socket Stable playback on unreliable signage networks
Content Negotiation JSON via Kotlinx Serialization (lenient mode) Automatic parsing + forward compatibility
Authentication Optional bearer token header Secures staging/production API calls
Logging Full request/response logging in debug builds Traceability during QA
Retry Hooks Backoff-aware interceptors Handles transient gateway errors

Data Transformation

DTO Guidelines

  • DTOs mirror backend contracts exactly (field names, optionality, nested payloads).
  • Annotated with Kotlinx Serialization for multiplatform compatibility.
  • Versioned per feature so schema changes do not cascade globally.

Mapper Strategy

Aspect Approach Benefit
Null Safety Default values (empty strings, placeholders) Prevents runtime crashes
Type Conversion Parse ISO dates, numeric types, booleans Domain layer uses strong types
Data Enrichment Merge multiple DTOs (e.g., teammate + XP data) Rich story cards without UI logic
Validation Filter invalid/incomplete records early Keeps autoplay feeds clean

Backend API Integration

data-integration-architecture.svg

Endpoint Method Purpose Auth
/api/v1/events GET Leader ID and calendar events Bearer
/api/v1/teammates GET Employee roster for celebrations Bearer
/api/v1/duolingo/users GET XP leaderboard, streak data Bearer
/api/v1/sport GET Sport/activity stats for signage Bearer
/api/v1/photos GET Synology-backed photo carousel assets Bearer

Server-side services pre-aggregate upstream systems so the TV client receives a stable contract tailored for signage.

Data Providers and Aggregation

  • Stories provider chunks roster fetches (100 items per call), runs external source lookups in parallel, merges by email/username, and emits payloads with warning metadata.
  • Events and Photos providers follow similar patterns: pull upstream data, hydrate domain models, then expose flows consumed by autoplay features.
  • Warnings allow partial renders when one source fails; only full outages halt a feature.

Caching Strategies

Image Caching (Coil3)

Cache Type Configuration Purpose
Memory Cache ~30% of available memory Instant redraws for looping slides
Disk Cache 30 MB Offline access between refresh cycles
Crossfade 100 ms Smooth transitions during autoplay

Feature-Specific Caching

  • Photos: Persists last successful album snapshot so slideshows continue offline.
  • Stories: Stores celebration payloads alongside warning list to avoid duplicate merges.
  • Events: Keeps next rotation locally with timestamps to expire stale promos.

Dependency Injection with Koin

dependency-injection-structure.svg

  • Core module registers HTTP client, serializers, base repositories.
  • Feature modules add their API clients, mappers, repositories, and data providers.
  • Components use dependency injection helpers to obtain services, improving testability.
  • Scope-aware definitions ensure long-lived singletons (HTTP client, caches) coexist with short-lived feature controllers.

Clone this wiki locally