Skip to content
CAI
Software that uses CAICheck a score

thomaskioko/tv-maniac

61.9

Weak · 22 September 2026

119.5k

lines of production code

Kotlin

with Swift

5

measurements over time

CAI band scale
CAI trend line
CAI lens gauges

What this system is

This system is a cross-platform TV show tracking and discovery application for Android and iOS that aggregates metadata from TMDB and syncs user activity with Trakt and Simkl. It provides comprehensive library management features including watch history tracking, ratings, custom lists, and a calendar of upcoming episodes, all supported by a robust offline-first data layer. The app also includes utility features such as automatic backups, deep linking, and customizable theming to enhance the user experience.

How it got here

2021–2025 — Multi-provider data layer and UI foundation

119 changes.

This period established the core architecture for a multi-provider TV tracking application, integrating Trakt, TMDB, and Simkl APIs with a robust SQLDelight-based local database. It introduced a comprehensive data layer featuring pagination, caching, and synchronization logic, alongside a new Metro dependency injection framework and standardized domain interactors. The work also delivered foundational iOS and Android UI components, including a design system with customizable themes, alongside essential developer tooling and CI/CD pipelines.

2026 — multi-platform foundation and sync infrastructure

233 changes.

This period focused on establishing a robust multi-platform foundation by migrating the dependency injection system to Metro and implementing a unified background task scheduler for Android and iOS. It introduced comprehensive data layers for core features such as followed shows, library management, and the calendar, while simultaneously building the sync infrastructure to handle provider-specific activity checkpoints and background synchronization workers.

Features

Adaptive API rate limiting with exponential backoff

The network layer now includes an adaptive rate limiter that caps concurrent API calls to six and applies exponential backoff with jitter when rate limits are hit. This behavior helps prevent overwhelming the server and improves resilience during high load or throttling events.

core/network-util/implementation · high confidence

Add Android home screen widgets for upcoming episodes

Users can now add two new widgets to their Android home screen: an 'Up Next' widget that lists the next few episodes of tracked shows, and an 'Up Next Poster' widget that displays a single episode with a large poster image. These widgets are built using Android Glance, support resizing and different layout configurations based on available space, and automatically apply the app's current theme (light or dark) to match the user's system preferences.

features/widget · high confidence

Add Genre Shows screen to browse shows by category

Users can now view a paginated grid of shows filtered by a specific genre or category. This change introduces the Genre Shows feature across the app, including the Android UI (Compose) and iOS (SwiftUI) screens, the shared presenter logic for handling paging and navigation, and the corresponding unit and screenshot tests. The screen displays show posters in a grid, supports pull-to-refresh, handles loading and error states, and allows users to tap a show to view its details or navigate back.

features/genre-shows, ios/Packages/GenreShows · high confidence

Add Lists and List Detail screens with Liquid Glass support

Users can now view their saved lists in a grid layout and drill down into individual list details. The new Lists screen displays a collage of list items, while the List Detail screen shows the shows contained within a specific list. Both screens support the new Liquid Glass visual style (with a legacy fallback) and include functionality to rename, remove items from, or delete lists entirely, along with standard loading, empty, and error states.

ios/Packages/Lists · high confidence

Add SQLDelight column adapters for database persistence

The database layer now includes a set of new SQLDelight column adapters (Id, Instant, Int, Provider, String, and WatchStatus) that handle the serialization and deserialization of specific data types to and from the SQLite storage format. This ensures that complex types like timestamps, enums, and comma-separated lists are correctly persisted and retrieved by the application.

data/database/sqldelight/src/commonMain/kotlin/com.thomaskioko.tvmaniac.db/adapters · high confidence

Add ability to create and manage show lists

Users can now create new lists and toggle shows between existing lists via a new sheet interface. This change introduces the ShowListSheet SwiftUI view, which displays a list of user-defined lists with toggles to add or remove shows, and includes a field for creating new lists. The implementation includes the necessary mapper extensions to convert internal state to UI models, a presenter-based view controller for handling actions, and snapshot tests to verify the visual appearance of the sheet in various states (empty, with lists, creating new list).

ios/Packages/ShowList · high confidence

Add cross-platform internet connectivity monitoring

The app now includes a core connectivity module that monitors internet availability on Android, iOS, and JVM platforms. This introduces an \InternetConnectionChecker\ API and platform-specific implementations that track connection state changes (using Android's ConnectivityManager and iOS's Network framework) and expose reconnection events via Kotlin Flows, enabling the application to react to network status updates.

core/connectivity/implementation · high confidence

Add domain logic for home screen widgets

The app now includes the core domain layer required to support home screen widgets on Android and iOS. This change introduces the data models for widget content (WidgetShow, WidgetSnapshot), an interactor to fetch the next episodes for the watchlist, and a publisher that handles downloading posters and writing widget snapshots to local storage. It also adds a background worker and initializer to periodically refresh widget data and update it in real-time when the watchlist or theme changes.

widget · high confidence

Add iOS 'Up Next' home screen widget

This change introduces the iOS implementation for the 'Up Next' home screen widget within the Widgets package. It adds the SwiftUI views (UpNextWidgetView) and state models (UpNextWidgetState) required to display upcoming episodes on the iOS home screen, supporting small, medium, and large widget families with theme-aware rendering. The diff also includes the snapshot reader logic to load widget data and a theme resolver to apply specific app themes (e.g., Light, Dark, Terminal) to the widget interface. Additionally, snapshot tests are added to verify the visual appearance of the widget across different sizes, themes, and content states (content, empty, placeholder).

ios/Packages/Widgets · high confidence

Add iOS statistics screen

The iOS Statistics screen is now available, providing a comprehensive overview of viewing habits. Users can see total watch time, a heatmap of episodes watched over time, and summary tiles for metrics like titles tracked and watch streaks. The screen also includes detailed breakdowns by year, month, and day of the week, as well as sections for genres, release years, watch status, and ratings. Additionally, users can view their most watched and highest rated shows.

ios/Packages/Statistics · high confidence

Add iOS widget and trailers screen

The iOS app now includes an 'Up Next' home screen widget that displays the next episode from the user's watchlist, supporting small, medium, and large sizes with theme-aware styling. Additionally, a new Trailers screen has been added, allowing users to view and play show trailers directly within the app using a YouTube player integration.

ios · high confidence

The app now stores popular shows locally using SQLDelight and supports paginated loading via AndroidX Paging. Users benefit from faster access to popular show lists and reduced network usage, as the system caches data and checks for request expiration before fetching new pages.

data/popularshows/implementation/src/commonMain · high confidence

Add show-list feature for managing show lists

The show-list feature now allows users to view, create, and manage lists of shows. This includes a new presenter layer that maps list data and handles actions, a UI component that displays lists in a modal bottom sheet with options to toggle shows in lists and create new custom lists, and comprehensive tests for the presenter logic and UI screenshots.

features/show-list · high confidence

Add upcoming shows data layer with pagination and caching

This change introduces the complete data implementation for the upcoming shows feature, including a new database DAO, repository, and caching store. Users can now view upcoming TV shows with support for paginated loading via AndroidX Paging, ensuring smooth scrolling and efficient memory usage. The system caches show data locally using SQLDelight and validates cache freshness against a request manager, automatically fetching fresh data from the network when the cache expires or a force refresh is triggered. The implementation handles data mapping from external sources (TMDB and Trakt) and persists show details like titles, posters, and overviews.

data/upcomingshows/implementation · high confidence

Add watch date selection for episodes and shows

Users can now specify when they watched an episode, season, or show. A new modal sheet presents options to mark the content as watched 'Just now', on its 'Release date', an 'Unknown date', or a custom date and time. The presenter logic handles the state management, including enabling the release date option only when an air date is available, and automatically prompting for a rating after marking an episode as watched for the first time.

features/watchdate-selection · high confidence

Add watchlist sorting and list style preferences

Users can now customize how their watchlist is displayed by choosing a list style and a sort order. The sort order options include sorting by when items were added (ascending or descending), by release date (ascending or descending), or by title (ascending or descending). These preferences are persisted and applied to the watchlist view.

data/watchlist-prefs/api, data/watchlist-prefs/implementation · high confidence

Added app startup and baseline profile benchmarks

The benchmark module now includes automated performance tests for the application's startup time and baseline profile generation. Users can now measure cold-start performance under partial and no-compilation modes using the Android Macrobenchmark library, and generate baseline profiles to improve runtime performance.

benchmark · high confidence

Added background synchronization for favorites

Users can now trigger a background sync of their favorite items, with the option to force a refresh. This change introduces the domain-layer interactor responsible for coordinating the synchronization process with the favorites repository.

favorites · high confidence

Added domain layer for observing recently watched episodes

The recently-watched module now includes the domain logic to retrieve a list of recently watched episodes. This change introduces the ObserveRecentlyWatchedInteractor, which queries the EpisodeRepository to return a flow of RecentlyWatchedEpisode objects, defaulting to a limit of 20 items.

recently-watched · high confidence

Added sync interactor for Start Watching data

A new domain interactor, SyncStartWatchingInteractor, has been introduced to handle the synchronization of Start Watching data. This component coordinates with the StartWatchingRepository and WatchedEpisodeSyncRepository to sync the user's watchlist and watched episodes, supporting an optional force refresh parameter.

start-watching · high confidence

Android backup destination and local data store implementation

This change introduces the Android-specific implementation for the backup data layer. It adds \AndroidBackupDestination\, which handles writing and reading backup files to either standard local file paths or Android \content://\ URIs (allowing users to choose specific folders via the DocumentsContract API), and \AndroidBackupLocationPermissions\ to persist URI permissions for those folders. Additionally, it registers the \DeviceLocalDataStore\ binding in \AndroidDeviceLocalDataStoreBindingContainer\, configuring an \androidx.datastore\ instance to store settings in the app's internal files directory.

data/backup/implementation/src/androidMain · high confidence

Automated episode notification scheduling and background sync

The app now automatically schedules notifications for upcoming episodes of followed shows. A new background worker runs every six hours to refresh season details, sync calendar data, and arm notifications for new episodes. This process is managed by an initializer that only activates when the user is connected to a sync provider (like Trakt or Simkl) and has explicitly enabled episode notifications in settings; disabling notifications or disconnecting the account will cancel the worker and clear pending alerts.

domain/notifications · high confidence

Automatic background backups and post-restore metadata sync

The app now supports automatic backups that run on a user-configurable interval (daily, weekly, or monthly) to a chosen folder, with a default location applied if none is set. If the backup location becomes unavailable, the app clears the setting to prompt the user for a new one. Additionally, after restoring a backup, the app automatically syncs show metadata to ensure content details are up to date, and this sync also triggers on network reconnection to refill any missing information.

domain/backup · high confidence

Automatic backup and restore capabilities added

Users can now configure automatic backups with customizable intervals, storage locations, and file names, while also supporting manual backup export and restore operations. The system includes background workers to handle scheduled auto-backups and post-restore metadata synchronization for shows, ensuring data integrity and up-to-date information after a restore.

backup · high confidence

Automatic crash-report context enrichment

The app now automatically attaches key context details to crash reports without requiring user identifiers. A new TelemetryContextInitializer monitors the active sync provider (Trakt, Simkl, or none), sign-in status, premium subscription status, and online/offline connectivity, updating the crash reporter's custom keys in real time. This ensures that any future crashes include this operational context to aid debugging, while explicitly avoiding the collection of user IDs.

domain/telemetry · high confidence

Backup API contract and data models introduced

This change introduces the core API interfaces and data models for the backup feature within the \data/backup/api\ module. It defines the \BackupRepository\ for creating, writing, and restoring backups, alongside specific contracts for managing automatic backup preferences (\AutoBackupPreferences\), file system interactions (\BackupDestination\, \BackupLocationPermissions\), and post-restore metadata handling (\ShowRefillReporter\, \RestoredListWriter\). The diff also establishes the backup file format versioning (v1, JSON) and enumerates specific failure modes for both export and import operations, laying the groundwork for the automatic backup logic and settings UI implemented in other modules.

data/backup/api · high confidence

Centralized app configuration and platform metadata via new appconfig module

The app now uses a dedicated appconfig module to manage service credentials and platform-specific metadata. This change introduces interfaces and default implementations for Simkl, TMDb, and Trakt configurations, which are now bound via the Metro dependency injection framework to read credentials from build-time constants. Additionally, platform metadata (version, package name, and platform type) is automatically provided for both Android and iOS, decoupling debug state from the build configuration.

core/appconfig/implementation · high confidence

Domain logic for creating, managing, and syncing user lists

This change introduces the core domain interactors for the new lists feature, enabling users to create, rename, and delete lists, as well as toggle shows within them. It includes logic to sync pending local changes to Trakt when the active provider supports lists, observe user lists and specific show associations, and fetch missing show details (posters) for items in a list. The implementation enforces a 50-character limit on list names and handles Trakt synchronization by attaching the user's slug only when the provider supports lists and a user is signed in.

domain/lists, lists · high confidence

Enhanced calendar episode formatting and date grouping

The calendar domain now provides structured episode information and improved date organization. A new \CalendarEpisodeFormatter\ standardizes how episode details are displayed, formatting season and episode numbers as 'S\#\#E\#\#' and optionally appending the episode title (e.g., 'S02E05 · The One'). Additionally, the \ObserveCalendarInteractor\ now groups calendar entries by date, allowing users to view episodes organized by their air date rather than as a flat list. This change also includes comprehensive tests for the new week calculation and episode grouping logic.

domain/calendar · high confidence

Episode detail sheet now tracks play count and supports rating and unwatching

The episode detail sheet now displays the total number of times an episode has been watched (play count) and allows users to rate episodes via a dedicated rating sheet. The sheet also supports marking episodes as unwatched with a confirmation dialog, and action availability is context-aware: for example, options to open the show or season are hidden when viewing from the season details source. Haptic feedback is provided when marking an episode as watched.

features/episode-sheet · high confidence

Establishes project scaffolding and developer tooling

Initializes the repository with essential configuration files, including a \.gitignore\ that excludes build artifacts and secrets, a \CHANGELOG.md\ for version tracking, and a \CONTRIBUTING.md\ outlining setup and architecture. Adds developer tooling such as \.editorconfig\ for Kotlin formatting, \.swiftlint.yml\ and \.swiftformat\ for Swift code style enforcement, and \git-hooks.yml\ to run pre-commit checks. Includes a \Brewfile\ for dependency management, a \local.properties.template\ for API key configuration, and a \version.txt\ defining the initial release version 0.1.2.

(repo-wide) · high confidence

Expanded Trakt API integration with new remote data sources

The Trakt API module now exposes a comprehensive set of remote data sources, enabling users to access detailed show information (trending, popular, favorited, watched, and related shows), manage personal watchlists and custom lists, track episode history and sync progress, view user statistics and favorites, and retrieve community ratings. This update also introduces calendar viewing for upcoming episodes, genre filtering, and robust authentication handling via token management, providing a much deeper integration with Trakt's ecosystem for content discovery and personal tracking.

api/trakt/api · high confidence

Implement paged genre shows with Trakt integration and request expiration

The genre data layer now supports fetching shows by genre via a new paged source backed by the Trakt API, replacing the previous single-page approach. This change introduces request expiration handling to ensure data freshness, using a dedicated \RequestManagerRepository\ to validate cached pages against a time threshold. The implementation includes new stores (\GenreShowsStore\, \TraktGenresStore\) and DAOs (\DefaultTraktGenreDao\) to manage database transactions and paging state, along with comprehensive tests for the repository and DAO logic.

data/genre/implementation · high confidence

The trending shows feature now fetches data from Trakt instead of TMDB, integrating a new repository, DAO, and store implementation. Users benefit from a robust paging system that allows seamless scrolling through trending content, with local caching and request expiration handling to optimize performance. The implementation includes specific database operations for upserting and observing trending shows by page, ensuring that the UI receives accurate, paginated lists of shows with their metadata.

data/trendingshows/implementation · high confidence

Implemented local storage and repository for tracking followed TV shows

Users can now have their followed shows persisted locally on the device. This change introduces the data layer for the 'followed shows' feature, including a SQLDelight-backed DAO and a repository that manages the lifecycle of followed items. The system supports adding and removing shows, tracks pending synchronization actions (upload or delete) for later sync with external providers like Trakt, and provides real-time observation of follow status via Kotlin Flows.

data/followedshows/implementation/src/commonMain · high confidence

Initial i18n generator module with localized strings and plurals for English, German, and French

The i18n/generator module now provides the foundational localization infrastructure for the app, including base string resources and plural rules for English, German, and French. This adds support for localized UI text across key areas such as the Discover tab (e.g., 'Up Next', 'Trending'), the 'My Shows' watchlist, Settings (including theme, image quality, and sync options), and episode tracking dialogs. The module also introduces plural support for counts like seasons, episodes, and watched items, along with platform-specific resolution helpers for Android and iOS to ensure proper formatting of these localized strings in the user interface.

i18n/generator · high confidence

Initial iOS and Android CI/CD pipeline configuration

This change introduces the foundational fastlane configuration for the project, establishing automated build, test, and deployment workflows for both iOS and Android platforms. For iOS, it defines lanes for building the app and KMP XCFramework, running snapshot and UI tests on the iPhone 17 Pro simulator, managing signing certificates via Match, and submitting builds to TestFlight and the App Store. For Android, it adds lanes to deploy AABs to the Play Store and distribute APKs via Firebase App Distribution. The setup includes specific test configurations, such as retry logic for UI tests and compilation caching, alongside linting and formatting tools for Swift code.

fastlane · high confidence

Introduce Calendar data module with repository and DAO interfaces

This change adds the foundational data-layer interfaces for the new Calendar feature within the \data/calendar/api\ module. It defines the \CalendarRepository\ for observing and fetching calendar entries, the \CalendarDao\ for local database operations (upserting, deleting, and querying entries by date range), and the \CalendarRemoteDataSource\ for retrieving remote calendar data. These interfaces establish the contract for how the application will access and manage calendar data, supporting the upcoming integration with external services like Simkl.

data/calendar/api · high confidence

Introduce Followed Shows data layer with Trakt ID support

The application now includes a dedicated data layer for managing followed TV shows, introducing a repository and database access object that support both Trakt IDs and TMDB boundary IDs. This change enables users to track shows using their Trakt identifiers while maintaining compatibility with TMDB-based lookups, and adds support for pending upload and delete actions to handle synchronization states.

data/followedshows/api · high confidence

Introduce Image Quality API interfaces

The image loading module now exposes public interfaces for managing image quality preferences. Users and dependent modules can interact with \ImageQualityPreference\ to observe quality settings via a Flow, and use \ImageQualityProvider\ to retrieve the current quality or observe changes to it, enabling more flexible control over image resolution and loading behavior.

core/imageloading/api · high confidence

Introduce Rating Sheet for shows, seasons, and episodes

Users can now rate individual shows, seasons, and episodes via a new modal bottom sheet. The feature includes a presenter that manages state and navigation, a UI component built with Compose that displays the target's title, subtitle, and poster/backdrop, and allows users to select a score or remove an existing rating. The implementation supports haptic feedback on score selection and includes comprehensive unit and screenshot tests to ensure correct behavior across different content types.

features/rating-sheet · high confidence

Introduce Start Watching feature with grid UI and presenter logic

Users can now view their 'Start Watching' list in a dedicated screen featuring a poster grid, pull-to-refresh sync, and search filtering. The presenter manages the list state, sorting (by title or release year), and sync triggers, while the UI renders the grid using Compose and handles navigation to show details.

features/start-watching · high confidence

Introduce TvManiacKit iOS package with multi-provider OAuth and UI customization

The new TvManiacKit package provides the iOS application entry point and core infrastructure, including an AppDelegate that initializes the application graph, Firebase, and background task scheduling. It introduces a multi-account authentication system via the TraktAuthKit dependency, allowing users to sign in through multiple OAuth providers configured at runtime. The package also enables user-facing UI customizations, including font size adjustment, poster style customization (width, corner radius), and a selection of visual themes (such as Terminal, Autumn, and Crimson), along with haptic feedback support.

ios/Packages/TvManiacKit · high confidence

Introduce Up Next data module with repository abstraction

The Up Next feature now has a dedicated data module that separates the repository interface from its implementation. The new \UpNextRepository\ interface defines methods to observe the next episodes for the watchlist, observe completed shows, and manage the user's sort preference. The \DefaultUpNextRepository\ implementation binds this interface using the Metro dependency injection framework, fetching next episode data from the database while respecting the user's preference for including special episodes, and persisting sort options via the datastore.

data/upnext/implementation · high confidence

Introduce automated background sync and structured 'Continue Watching' views

The Continue Watching module now includes a new \ContinueWatchingSyncWorker\ that runs a periodic background sync every 12 hours, respecting the user's account connection status and sync preferences. A \ContinueWatchingTasksInitializer\ manages this schedule and triggers immediate syncs on network reconnection to ensure data consistency. On the presentation side, the domain layer now provides structured data flows for the UI: \ObserveUpNextInteractor\ and \ObserveUpNextSectionsInteractor\ deliver sorted and grouped 'Up Next' episodes (categorized into 'Watch Next' and 'Stale' based on a 16-day inactivity threshold), while \ObserveWatchlistSectionsInteractor\ provides a similar 'Watch Next' vs. 'Stale' grouping for the watchlist based on a 21-day threshold. These changes enable the app to automatically keep the user's continue-watching state in sync and present it in organized, actionable sections.

domain/continue-watching · high confidence

Introduce backup and restore functionality for shows, episodes, and preferences

This change adds the core data-layer implementation for creating and restoring application backups. The new \DefaultBackupRepository\ handles exporting show metadata, watched status, ratings, and user preferences into a versioned JSON file, and importing them back into the local database. The \BackupImporter\ manages the restoration process, including resolving shows via TMDB IDs, restoring seasons and episodes, and syncing followed shows and ratings with connected accounts when enabled. A safety copy mechanism is included before restoration to prevent data loss, and the \BackupJson\ component ensures backward compatibility by checking the backup file version against the current supported format.

data/backup/implementation/src/commonMain · high confidence

Introduce cast data access interfaces

New API interfaces for cast data have been added, defining how the application retrieves and observes cast information for shows and seasons. The CastRepository interface specifies methods to fetch show cast details (with an option to force a refresh) and observe cast lists for both shows and specific seasons. The underlying CastDao interface provides the data access layer, including upsert operations for cast entities and reactive flows to observe changes in show and season cast data.

data/cast/api · high confidence

Introduce centralized screenshot testing utilities

The project now includes a new core module for screenshot testing that provides reusable utilities for capturing Compose UI screenshots across different devices and themes. This module introduces a Roborazzi-based helper that automatically captures UI states in both light and dark modes, configurable via a change threshold of 0.01f to reduce false positives, and supports overriding output filenames for specific test cases.

core/screenshot-tests · high confidence

Introduce core notification API interfaces

This change adds the foundational API contracts for the notification system within the \core/notifications/api\ module. It defines the \NotificationManager\ interface, which exposes methods for scheduling, canceling, and retrieving episode notifications, along with constants for deep-link extras used when users interact with notifications. It also introduces the \NotificationChannel\ enum to categorize notification types (such as episodes airing and developer channels) and the \NotificationIconProvider\ interface to allow platform-specific customization of notification icons, including a debug variant.

core/notifications/api · high confidence

The app now supports the custom 'tvmaniac' URL scheme to navigate directly to content. Users can open links like 'tvmaniac://show/1399' to view show details, or 'tvmaniac://episode/1399/1/2' to jump to a specific season and episode. The implementation handles standard URL structures, ignoring query parameters and fragments, and safely rejects malformed or unknown link formats.

core/deeplink/api, core/deeplink/implementation · high confidence

Introduce dual-path Continue Watching sync with Nitro support

The Continue Watching feature now supports two distinct sync strategies: a new Nitro path using Trakt's \/sync/progress/up\_next\_nitro\ endpoint for premium users, and a standard Progress path using the canonical watched-shows feed joined with playback episodes. The \DefaultContinueWatchingRepository\ routes to the appropriate fetcher based on a \useNitro\ flag, allowing the app to leverage enhanced data from Nitro when available while maintaining reliability for standard users. This change also includes a new \ContinueWatchingDao\ and \DefaultContinueWatchingDao\ implementation to manage local entries, including upserts, deletions, and deriving membership from watched episodes for providers without native continue-watching feeds.

data/continue-watching/implementation · high confidence

Introduce favorites data and domain layers

Added the foundational data and domain layers for the Favorites feature, including the \FavoritesDao\ and \FavoritesRepository\ interfaces in the data layer, and the \ObserveFavoritesInteractor\ and \SyncFavoritesInteractor\ in the domain layer. This enables the application to observe and synchronize a user's Trakt favorited shows, with tests verifying the interactor behavior.

data/favorites/api, domain/favorites · high confidence

The app now includes a dedicated data layer for featured shows, introducing \DefaultFeaturedShowsDao\ for SQLite persistence and \DefaultFeaturedShowsRepository\ to coordinate data fetching and caching. Users will see featured content populated from the database, with the repository limiting the displayed list to 12 items and supporting both cached retrieval and forced refreshes via the underlying store.

data/featuredshows/implementation/src/commonMain · high confidence

The application now includes a dedicated data layer for managing featured shows, introducing the FeaturedShowsDao and FeaturedShowsRepository interfaces. These components enable fetching and observing featured content with explicit pagination support (via a page parameter) and the ability to force a data refresh, laying the groundwork for displaying curated show lists in the UI.

data/featuredshows/api/src/commonMain/kotlin/com/thomaskioko/tvmaniac/data/featuredshows/api · high confidence

Introduce iOS Rating Sheet UI with Liquid Glass styling and haptic feedback

The RatingSheet package now includes a new SwiftUI-based UI for iOS that allows users to rate shows, seasons, and episodes. The implementation features a 1-10 score grid with haptic feedback on selection, support for poster or backdrop images, and a 'Remove rating' button. The sheet utilizes the Liquid Glass visual variant for supported iOS versions and includes snapshot tests to verify the appearance of unrated, rated, and season-rated states.

ios/Packages/RatingSheet · high confidence

Introduce local favorites management with remote sync capability

Users can now manage a local list of favorite shows, which is persisted in the local database and can be synchronized with the active provider's remote favorites when supported. The implementation includes a data layer that handles local storage via SQLDelight and resolves internal show identifiers, while the repository layer orchestrates the sync process, respecting provider capabilities and allowing for forced refreshes.

data/favorites/implementation/src/commonMain · high confidence

Introduce local ratings data layer with offline-first sync support

This change adds the backend data layer for user ratings, enabling users to rate shows, seasons, and episodes with full offline support. The implementation introduces \DefaultRatingsDao\ and \DefaultProviderMetaDao\ to persist ratings locally via SQLDelight, and \DefaultRatingsRepository\ to manage the lifecycle of these ratings. Ratings are stored with a pending action state, allowing users to rate content without an internet connection; these local changes are then synchronized with remote providers (such as TMDB) in the background when connectivity is restored. The repository also exposes aggregated data for the statistics dashboard, including user rating distributions and lists of highest-rated shows.

data/ratings/implementation/src/commonMain · high confidence

Introduce local rewatch session tracking and sync infrastructure

The application now tracks rewatch activity locally, allowing users to record every time an episode is watched and maintain persistent play counts even when offline. This change adds a new data layer (\DefaultRewatchSessionDao\) that manages rewatch sessions, episode viewings, and totals via SQLDelight, while also wiring up the dependency injection bindings (\ActiveRewatchSyncProviderDataSourceBindingContainer\, \RewatchMultibindings\) to select the active sync provider based on the current account. Users benefit from accurate, persistent statistics for their rewatching habits, with data ready to be synced to external providers like Simkl when a connection is available.

data/rewatch/implementation/src/commonMain · high confidence

Introduce memory-aware image caching and diagnostic logging infrastructure

The CoreKit package now includes a new \ImageCacheManager\ that configures the Nuke image pipeline with memory-aware limits, automatically reducing cache sizes and concurrent loads on low-memory devices to improve performance and stability. A \MemoryMonitor\ system has been added to track memory pressure and escalate cache clearing actions during memory warnings, while new \CoreLogger\ and \DiagnosticLogger\ protocols, along with a \DefaultDiagnosticLogger\ implementation, provide a structured way to record breadcrumbs and errors for diagnostics. Additionally, a \FirebaseRemoteConfigBridge\ and its no-op fallback are introduced to integrate Firebase Remote Config for feature flags, and a \StubImageDataLoader\ is provided to prevent UI tests from fetching real images.

ios/Packages/CoreKit · high confidence

Introduce provider-aware search with recent search history

The search data layer now supports searching via the user's active sync provider (Trakt or Simkl), caching results per provider so that switching accounts yields distinct result sets. Recent searches are persisted locally, deduplicated case-insensitively, limited to the ten most recent entries, and returned in reverse chronological order. The implementation includes the SearchDao and SearchRepository interfaces, their default implementations bound via Metro dependency injection, and comprehensive unit tests for the DAO, repository, and caching store.

data/search/implementation · high confidence

Added the RecommendedShowsDao and RecommendedShowsRepository interfaces to the recommended shows module. These interfaces define the contract for persisting recommended shows (via upsert, observe, and delete operations) and fetching them from external sources (via fetchRecommendedShows with optional force refresh), establishing the foundational data access layer for this feature.

data/recommendedshows/api · high confidence

The app now includes a dedicated data module for recommended shows, implemented via a new repository, DAO, and caching store. This feature fetches related content by combining data from Trakt and TMDB, storing the results locally with a unified identifier strategy that maps between TMDB and Trakt IDs. Users benefit from a more robust and cached experience when viewing show recommendations, with the system handling data persistence and expiration checks automatically.

data/recommendedshows/implementation/src/commonMain · high confidence

Introduce rewatch tracking data layer

Added the core data interfaces for the new rewatch feature, including the \RewatchRepository\ for managing session lifecycle (start, add episode, close, finish), \RewatchSessionDao\ for local database operations, \RewatchSyncProviderDataSource\ for syncing with external providers, and \RemoteRewatchSessionStatus\ to handle session states.

data/rewatch/api · high confidence

Introduce the Continue Watching feature with sectioned watchlist and up-next views

Users can now view their Continue Watching content, organized into 'Watch Next' and 'Stale' sections for both shows and upcoming episodes. The presenter handles sorting (by last watched, release date, or title), search filtering, and syncing with connected accounts. The UI renders list items with show progress, status, and episode details, while the presenter logic supports marking episodes as watched, long-pressing to edit watch dates, and prompting for ratings based on user preferences.

features/continue-watching · high confidence

Introduce the More Shows feature with categorized browsing and pull-to-refresh

The \:features:more-shows\ module now provides a new screen for browsing shows across multiple categories, including Upcoming, Trending, Popular, Top Rated, and Start Watching. The \MoreShowsPresenter\ manages the state and data fetching for these categories using \androidx.paging\ for efficient list loading, while the \MoreShowsScreen\ UI renders the content in a responsive grid layout with pull-to-refresh support and error handling. This change also includes the necessary navigation routing via \MoreShowsRoute\ and unit tests for the presenter logic.

features/more-shows · high confidence

Introduce the Statistics screen with watch history analytics

A new Statistics screen is now available, presenting a comprehensive overview of your viewing habits. The feature includes summary tiles for metrics like total watch time, watch streaks, and titles tracked, alongside a heat map visualizing daily activity. Users can explore detailed breakdowns by genre, release year, and watch status, as well as lists of their most-watched and highest-rated shows. The screen supports pull-to-refresh for data updates and handles empty states or locked (premium) content appropriately.

features/statistics · high confidence

Introduce top-rated TV shows data layer with pagination and caching

The application now supports fetching and displaying top-rated TV shows. This change adds the complete data implementation for this feature, including a SQLDelight-backed DAO for persisting show details, a repository that manages paging via a RemoteMediator, and a caching store that fetches data from the Trakt API and enriches it with details from TMDB. Users can now browse a paginated list of top-rated shows, with the system handling background caching, request expiration, and database upserts automatically.

data/topratedshows/implementation · high confidence

Introduce watch status tracking for TV shows

The application now tracks and displays the watch status (Watchlist, Watching, or Completed) for TV shows. This change adds a new data layer that persists status updates to the local database and exposes counts of shows per status via reactive flows, allowing the UI to reflect real-time progress. The implementation includes a repository that resolves external show identifiers to internal database keys and a DAO for efficient status queries and updates.

data/watch-status/implementation · high confidence

Introduces Firebase Crashlytics integration with platform-specific crash reporting

The logger module now integrates Firebase Crashlytics to capture and report application crashes. On Android, the system uses the Firebase SDK to record exceptions with custom keys and user IDs, while iOS utilizes the CrashKios library for equivalent crash reporting capabilities. A new \CompositeLogger\ delegates logging calls to both local console output (via Kermit) and the remote crash reporter, ensuring that errors are captured in both places. The implementation includes deduplication logic to prevent redundant crash reports for identical failures and allows users to toggle crash collection via preferences.

core/logger/implementation · high confidence

This change adds the core data-layer components for the popular shows feature, including the \PopularShowsDao\ interface for database operations, a \PopularShowsRepository\ that exposes methods for fetching and observing show data (including paginated results via \PagingData\), and a \PopularShowsInteractor\ to orchestrate the data fetching logic. These interfaces establish the contract for retrieving popular TV shows with support for force refresh and pagination.

data/popularshows/api · high confidence

Introduces offline connectivity and account-limit banners, plus Liquid Glass support on iOS

The root feature now displays an offline connectivity banner that informs users when the app is offline and when it reconnects, and an account-limit banner that prompts users to upgrade their Trakt subscription. On iOS, the app now supports the Liquid Glass visual style, controlled by a feature flag. These changes are implemented via new presenter logic, UI components, and platform-specific availability checks in the root module.

features/root · high confidence

Introduces platform-agnostic background task scheduling API

The application now uses a new, shared API for managing background work, replacing platform-specific implementations with a unified interface. This change introduces a \BackgroundTaskScheduler\ for registering, executing, and canceling periodic tasks, a \BackgroundWorker\ interface for defining the business logic of background jobs, and a \WorkerFactory\ to resolve these workers by name at runtime. This allows background tasks to be defined once in the common codebase while being dispatched by platform-specific schedulers (Android and iOS), ensuring consistent behavior and easier maintenance of background features like sync and watchlist updates.

core/tasks/api · high confidence

Introduces request manager API with configurable expiration for data requests

The data layer now exposes a RequestManagerRepository interface and a RequestTypeConfig enum to manage the validity and expiration of various data requests. This allows the application to track when specific data types (such as featured shows, watchlist metadata, or Trakt syncs) were last fetched and determine if they are still valid based on defined duration thresholds, enabling more efficient caching and synchronization strategies.

data/request-manager/api · high confidence

Introduction of Localizer interface for internationalization

The i18n/api module now exposes a Localizer interface that defines the contract for retrieving localized strings and plural forms. This interface provides methods to fetch single strings and pluralized strings based on resource keys and quantities, establishing the foundational API for platform-specific localization implementations within the application.

i18n/api · high confidence

Introduction of library sorting options

A new enum class LibrarySortOption has been added to define available sorting criteria for the library. This change introduces specific sort configurations based on rank, date added, release date, and title, each supporting ascending or descending order, enabling users to organize their media library content according to these attributes.

data/library/api/src/commonMain/kotlin/com/thomaskioko/tvmaniac/data/library/model · high confidence

Introduction of subscription feature access API

The application now exposes a new API layer for managing subscription-based features. This includes an \AccountType\ enum to distinguish between Premium, Free, and None accounts, and a \SubscriptionFeature\ enum listing specific capabilities such as Episode Notifications, Calendar, Custom Themes, List View Types, Quick Rate, Statistics, Cloud Backup, and Widget Theming. The \SubscriptionManager\ interface allows the application to check access rights for these features via synchronous checks or reactive flows, while \SubscriptionStatusProvider\ exposes the current subscription status (Premium, Free, Unknown) to the rest of the app.

data/subscription/api · high confidence

Library screen now supports compact and detailed list layouts

The iOS Library screen now offers two additional viewing modes—Compact and Detailed—accessible via the layout menu alongside the existing Grid and List options. The Compact layout displays a compact row with a poster and metadata, while the Detailed layout shows a large backdrop image with a gradient overlay. These premium layouts are locked for non-premium users, indicated by a locked hint and an upgrade action in the menu. The update also includes a new Sort Options sheet for filtering by sort criteria, genres, and status, and introduces a Liquid Glass visual variant for the library interface when enabled.

ios/Packages/Library · high confidence

Library view supports multiple list styles with premium layout restrictions

The Library feature now offers users the ability to switch between compact, detailed, list, and grid layouts. Premium layouts (compact and detailed) are gated behind a subscription check; if the user lacks access, the view defaults to a free layout (list or grid) and locks the style selector. When access is granted, the previously stored premium layout is restored. The library presenter also handles sorting (by rank, added date, release year, or title) and filtering by genre and show status.

features/library · high confidence

My Shows screen adds compact and detailed layout options

The My Shows screen now supports compact and detailed list styles in addition to the existing grid and list views. Users can switch between these layouts via the toolbar menu, with the compact view displaying a row-based episode list and the detailed view showing a card-based layout with a progress bar overlay. This change also introduces a sort options sheet to allow users to organize their watchlist by added date, release date, or title.

ios/Packages/MyShows · high confidence

New API modules for Simkl, TMDB, and Trakt integrations

This change introduces dedicated API modules for three external services: Simkl, TMDB, and Trakt. The Simkl module adds support for ratings, rewatch sessions, show search, sync history, and user stats. The TMDB module provides data models for show details, seasons, episodes, credits, and watch providers. The Trakt module includes models for authentication and episode tracking. These modules establish the foundational data structures and remote data source interfaces required for multi-provider content and tracking integration.

api · high confidence

New Android home screen widgets for Up Next and poster views

Users can now add Android home screen widgets to the app. The new UpNextWidget displays a list of upcoming episodes with titles and season/episode labels, while the UpNextPosterWidget shows a single poster view for the next episode. Both widgets respect the user's theme setting and provide deep links to open the corresponding episodes within the app.

ui · high confidence

New Calendar data layer with Metro DI and Simkl integration support

This change introduces the core data implementation for the Calendar feature, including the DefaultCalendarDao for SQLite persistence, the DefaultCalendarRepository for managing calendar entries and syncing, and the Metro dependency injection bindings (CalendarMultibindings) to wire up remote data sources. The repository logic supports fetching calendar data via a pluggable remote source system, enabling integration with providers like Simkl as indicated by the commit messages, while the DAO handles upserting and observing calendar entries mapped to internal show identifiers.

data/calendar/implementation/src/commonMain · high confidence

New Compose UI components added to the design system

The Android design system now includes a suite of new Jetpack Compose components, such as AnimatedCountText, AvatarComponent, TvManiacBanner, CastCard, CollapsibleSection, and TvManiacAlertDialog. These additions provide reusable building blocks for displaying animated statistics, user avatars, persistent top-of-screen notifications, cast information, expandable content sections, and customizable alert dialogs, enhancing the consistency and visual fidelity of the app's interface.

android-designsystem/src/main/kotlin/com/thomaskioko/tvmaniac/compose/components · high confidence

New Compose UI extension utilities for gradients, scrolling, and layout

The Android design system now includes a new set of Compose extension functions in the \compose.extensions\ package to simplify common UI patterns. Developers can now apply vertical gradient backgrounds or scrim overlays with configurable decay and stops using \contentBackgroundGradient\, \backgroundGradient\, and \verticalGradientScrim\. List interactions are enhanced with \calculateScrollOffset\ to create peek effects in lazy lists, and layout management is streamlined with a \PaddingValues.copy\ helper for selectively duplicating padding values.

android-designsystem/src/main/kotlin/com/thomaskioko/tvmaniac/compose/extensions · high confidence

New DAO implementations for episodes, next episodes, and watched history

The application introduces three new data access objects—DefaultEpisodesDao, DefaultNextEpisodeDao, and DefaultWatchedEpisodeDao—to handle episode metadata, upcoming episode tracking, and watched history respectively. DefaultEpisodesDao manages episode upserts, lookups by show/season/episode number, and fetching upcoming episodes from followed shows. DefaultNextEpisodeDao provides flows for next episodes in a watchlist and completed shows. DefaultWatchedEpisodeDao handles marking episodes as watched, updating watched dates, and retrieving statistics such as recently watched episodes, most watched shows, and watched show composition (genres and years). These DAOs are bound to their respective API interfaces using the Metro dependency injection framework.

data/episode/implementation/src/commonMain/kotlin/com/thomaskioko/tvmaniac/episodes/implementation/dao · high confidence

New Debug Menu for testing and diagnostics

A new debug menu has been added to the application, providing a centralized interface for developers and testers to trigger and monitor internal system states. The menu allows users to manually trigger library and Up Next synchronization, schedule immediate or delayed episode notifications, and inspect the status of authentication tokens (including expiry and refresh timestamps). It also includes controls to override the account type (Free/Premium) for testing, open the feature flags interface, and generate test crash reports or non-fatal error logs for telemetry. The feature is implemented as a multiplatform presenter and UI screen, complete with unit tests and screenshot tests to ensure visual consistency across devices.

features/debug · high confidence

New Feature Flags management screen

Users can now view, search, and manage application feature flags through a new dedicated screen. This interface allows toggling flags on or off, sorting and filtering the list, and resetting local overrides. It also supports force-refreshing flags from the remote configuration service to ensure the latest settings are applied.

features/feature-flags · high confidence

New Feature Flags management screen with Liquid Glass support

The Feature Flags screen has been rebuilt as a standalone SwiftUI view within the FeatureFlags package, introducing a modern interface that supports the new Liquid Glass visual style when enabled. Users can now search, sort, and group flags by type, toggle individual settings, and reset flags to their defaults or force a refresh from remote configuration. The screen also includes snapshot tests to ensure visual consistency across light and dark modes.

ios/Packages/FeatureFlags · high confidence

New Kotlin Flow and Decompose utility extensions

The core base module now includes new extension functions to simplify common reactive patterns. Developers can combine up to 13 Kotlin \Flow\ instances using the new \combine\ overloads in \Combine.kt\. Lifecycle-aware coroutine scopes are provided via \DecomposeUtils.kt\, allowing seamless conversion between Decompose \Value\ and Kotlin \StateFlow\ while respecting component lifecycle states. Additionally, \FlowExtensions.kt\ introduces a \minTrueDuration\ operator to enforce minimum duration constraints on boolean flows.

core/base/src/commonMain/kotlin/com/thomaskioko/tvmaniac/core/base/extensions · high confidence

New Lists feature with detail management screens

Users can now view their personal lists and manage them in detail. The new Lists screen displays all user-created lists, while the List Detail screen allows users to rename, delete, or remove specific shows from a list. The implementation includes the presenter logic for handling these actions, the UI screens for rendering the lists and details, and comprehensive unit tests for the presenters.

features/lists · high confidence

New Profile Screen with Watch History and List Management

The iOS Profile screen has been rebuilt to display a comprehensive user dashboard, including sections for recently watched shows, watch progress (with in-progress/completed filtering), favorite shows, and user-created lists. The interface now supports managing lists via a dedicated selector view, allows toggling shows in and out of lists, and integrates with Simkl and Trakt authentication providers. The layout features a scrollable header with parallax effects and uses the app's design system for consistent theming.

ios/Packages/Profile · high confidence

New Progress feature with Up Next and Calendar tabs

The app introduces a new Progress section, accessible via a tabbed interface, that consolidates the 'Up Next' episodes list and a 'Calendar' view of upcoming shows. This change adds the necessary navigation, presenter logic, and UI components to display these two distinct views within a single feature module, along with screenshot tests to verify the visual rendering of both tabs and loading states.

features/progress · high confidence

New Progress tab with Up Next and Calendar views

The Home package now includes a dedicated Progress tab in the main navigation, featuring an Up Next list for upcoming episodes and a Calendar view for scheduled content. Users can sort the Up Next list by last watched or air date, mark episodes as watched, and navigate weeks in the calendar. The tab is integrated into the existing tab bar alongside Discover, My Shows, and Profile.

ios/Packages/Home · high confidence

New Start Watching data layer for released, unstarted shows

This change introduces the backend data layer for the Start Watching feature, enabling the app to identify and display shows that have been followed, have aired their first episode, and are not yet in the Continue Watching list. The implementation adds a new DAO and repository that query the local database for these specific conditions, while a remote data source and store sync the user's 'Plan to Watch' lists from Trakt and Simkl providers into the local schema. Unit tests verify the filtering logic, ensuring shows with future air dates, already watched episodes, or pending unfollow actions are correctly excluded.

data/start-watching/implementation · high confidence

New SyncActivityInteractor for fetching Trakt activities

A new domain interactor has been introduced in the sync-activity module to handle fetching the latest activities from the Trakt API. This component wraps the TraktActivityRepository and exposes a simple interface that accepts a force-refresh parameter, allowing users to trigger an immediate update of their watchlist and activity data when needed.

sync-activity · high confidence

New TMDB API interface definitions for show data and network sources

The \api/tmdb/api\ module now exposes a set of new Kotlin interfaces that define the contract for interacting with The Movie Database (TMDB). These include \TmdbConfig\ for API key management, \TmdbShowsNetworkDataSource\ for discovering, searching, and retrieving details about TV shows (including genres, credits, and watch providers), \TmdbShowDetailsNetworkDataSource\ for specific show details and recommendations, and \TmdbSeasonDetailsNetworkDataSource\ for season-specific information. This establishes the foundational API layer for fetching TV show metadata.

api/tmdb/api · high confidence

New Trakt remote data source implementations

The Trakt API integration now includes concrete implementations for fetching calendar data, managing episode watch history, handling custom lists and watchlists, retrieving user ratings, accessing show details and search results, syncing playback progress, managing OAuth tokens, and retrieving user profile statistics. These new data sources enable features such as viewing upcoming show calendars, tracking episode viewing history, creating and managing personal watchlists, rating shows and episodes, searching for content, and monitoring watched progress across the Trakt service.

api/trakt/implementation/src/commonMain/kotlin/com/thomaskioko/trakt/service/implementation/api · high confidence

New base interactor classes and dedicated database dispatchers

The core base module now provides new abstract interactor classes (Interactor, ResultInteractor, SubjectInteractor) that standardize how background tasks are executed, including support for synchronous execution and automatic timeout handling. Additionally, a new AppCoroutineDispatchers model introduces separate coroutine dispatchers for database read and write operations, allowing for more granular control over concurrency in data access layers.

base · high confidence

New cast data module with multi-provider support

A new cast data module has been added, introducing a \ShowCastStore\ that fetches cast information from both Trakt and The Movie Database (TMDB) sources. The implementation uses a \DefaultCastRepository\ and \DefaultCastDao\ to manage local storage via SQLDelight, resolving TMDB IDs to internal IDs and upcasting cast members from either provider. This change decouples the schema from a single provider, allowing the app to aggregate cast data from multiple sources while maintaining caching and validation logic.

data/cast/implementation/src/commonMain · high confidence

New core paging module with Keyed, Offset, and Remote Mediator implementations

A new \core/paging\ module has been introduced, providing three key components for data pagination: \KeyedQueryPagingSource\ for key-based SQLDelight queries, \OffsetQueryPagingSource\ for offset-based queries with support for prepend/append/refresh logic, and \PaginatedRemoteMediator\ for handling remote data fetching with error reporting and telemetry. These classes replace ad-hoc paging logic, offering a unified, transaction-safe approach to loading paginated data from both local databases and remote sources.

paging · high confidence

New core paging module with SQL paging support and remote mediator tests

A new \core/paging\ module has been introduced to centralize pagination logic. It provides a \CommonPagingConfig\ object defining a default page size and a 6-hour cache expiration time. The module includes a \QueryPagingSource\ implementation that enables paging through SQLDelight \Query\ objects, supporting both offset-based and keyset-based strategies. Additionally, tests have been added for \PaginatedRemoteMediator\ to verify error reporting behavior during data fetches.

core/paging · high confidence

New core utilities for error mapping and item-level loading states

The core/view module now includes an ErrorToStringMapper interface for converting exceptions into user-readable strings and a launchUpdating extension function that manages per-item progress indicators and global loading counters during asynchronous operations.

core/view · high confidence

New core view utilities for loading states and UI message management

The core/view module introduces foundational components for handling asynchronous operations and user feedback. InvokeStatus defines a sealed hierarchy for tracking invocation states (Started, Success, Error), while ObservableLoadingCounter provides a thread-safe mechanism to track concurrent loading operations via atomic counters. UiMessageManager handles the display of transient UI messages, supporting both simple error/success notifications and the deduplication/combination of similar errors to prevent notification spam. These utilities enable consistent loading indicators and robust error reporting across the application.

view · high confidence

New data layer for browsing shows by genre

The application now includes a dedicated data layer for genre-based content discovery. This introduces interfaces for managing genre metadata (GenreDao, TraktGenreDao) and a repository (GenreRepository) that supports fetching shows filtered by genre slug and category (Popular, Trending, Top Rated, Most Watched). The implementation leverages Android Paging for efficient, paginated lists of shows and integrates with Trakt for genre synchronization, enabling users to browse TV shows organized by genre.

data/genre/api · high confidence

This change introduces a suite of new data store implementations that fetch content from Trakt and TMDB, cache it locally, and manage synchronization. Specifically, it adds a CalendarStore for upcoming episodes, a FavoritesStore to sync user favorites with TMDB images, a FeaturedShowsStore for trending content, a GenreShowsStore for browsing shows by genre, a LibraryStore for the user's watchlist, and a ProgressContinueWatchingFetcher to track ongoing viewing progress. It also includes an UpcomingEpisodesStore for episode air dates, a DefaultTraktGenreDao for genre data persistence, and platform-specific backup handling for iOS. These components collectively enable the app to display personalized and curated content lists by integrating remote provider data with local database storage.

implementation · high confidence

New database schema and queries for activity sync, backups, and calendar

The local database now includes new tables and SQLDelight queries to support activity synchronization checkpoints, comprehensive data backup and restore operations, and a TV episode calendar. Users can now back up and restore their followed shows, watch history, ratings, and lists, while the app tracks sync progress per provider and stores upcoming episode air dates for calendar integration.

data/database/sqldelight/src/commonMain/sqldelight/com/thomaskioko/tvmaniac/db · high confidence

New developer tooling and CI automation scripts

The repository now includes a suite of automation scripts to streamline development and CI workflows. A new \setup.sh\ script provides a one-command environment setup for both Android and iOS, handling local properties, Git hooks, and toolchain installation. iOS development is supported by \build-kmp-framework.sh\ to build and cache the KMP XCFramework, \ios-framework-size.sh\ and \ios-framework-size-analysis.py\ to track and attribute framework binary size, and \framework-cache-key.sh\ for CI caching. CI integrity is improved with \check-localization.py\ to enforce translation parity, \report-workflow-runs.py\ to analyze pipeline performance, and \write-build-number.sh\ to manage versioning. Code quality is enforced via \spotless-staged.sh\ for Kotlin formatting and a new Git hook system using \lefthook\.

scripts · high confidence

New domain interactors for episode tracking, sync, and watched-date management

The domain/episode module now includes a set of new interactors that power episode-specific features: ObserveEpisodeByIdInteractor and ObserveShowWatchProgressInteractor expose real-time episode and show progress data; ShouldShowDatePickerInteractor checks whether the custom watch-date setting is enabled; MarkEpisodeWatchedInteractor, MarkEpisodeUnwatchedInteractor, and MarkWatchedAtInteractor handle marking episodes as watched, unwatched, or setting a specific watched date (including marking previous episodes/seasons and recording rewatch viewings); SyncPendingUploadsInteractor and PendingUploadsWorker coordinate background sync of pending episodes, followed shows, and lists to the active provider (skipping lists if the provider does not support them); ResolveEpisodeIdInteractor resolves cached episode IDs; and SyncShowEpisodeWatchesInteractor forces a watch-status sync for a show. Tests are added for all these interactors to verify their behavior.

domain/episode · high confidence

New domain layer for observing and syncing start-watching shows

This change introduces the core domain logic for the 'Start Watching' feature, specifically adding the \ObserveStartWatchingInteractor\ to stream the list of shows a user is currently watching and the \SyncStartWatchingInteractor\ to synchronize watched episodes and watchlist data with the repository. The interactor tests confirm that observing emits the correct show list and that syncing respects force-refresh parameters, laying the groundwork for the UI to display and update this data.

domain/start-watching · high confidence

New domain logic for episode watch tracking and synchronization

The episode domain module now includes dedicated interactors to manage viewing status and sync state. Users can mark episodes as watched or unwatched, with support for marking previous episodes and seasons as watched in a single action. The system also tracks the specific date an episode was watched, allowing for rewatch tracking and date editing. Additionally, a background worker automatically syncs pending watch updates to external services every six hours, ensuring watch history remains consistent across devices.

episode · high confidence

New domain logic for user ratings and rating prompts

This change introduces the core domain-layer interactors for the ratings feature, enabling users to view, submit, and remove ratings for shows, seasons, and episodes. It adds \ObserveRatingInteractor\ and \RateInteractor\ to handle reading and writing user ratings, \RemoveRatingInteractor\ to delete them, and \RefreshCommunityRatingInteractor\ to update community scores. Additionally, \ObserveRatingTargetInteractor\ provides metadata (titles, images) for the items being rated, while \ShouldPromptForRatingInteractor\ implements the logic to determine when to prompt users to rate an episode based on subscription status and previous interactions.

ratings · high confidence

New domain models and interactor for user profile and statistics

The user domain module now includes new data classes for UserProfile and UserStats, along with an UpdateUserProfileData interactor. This interactor fetches the user profile, retrieves statistics, and conditionally syncs pending lists if the active provider supports them, providing the foundational data structures and logic for displaying user-specific information and stats.

user · high confidence

New domain models and interactors for the calendar feature

This change introduces the core domain layer for the calendar feature, adding new Kotlin files that define how calendar data is structured and processed. It includes \CalendarWeekCalculator\ for computing date ranges and labels, \FetchCalendarInteractor\ for retrieving calendar data from the repository, and \ObserveCalendarInteractor\ for observing and grouping calendar entries by date and show. New model classes (\DateLabel\, \GroupedCalendarEntry\, \GroupedEpisodeEntry\) are added to represent the structured data used by the UI, enabling the calendar to display grouped episodes with formatted dates and show information.

calendar · high confidence

New episode tracking and watch progress APIs

The application introduces a comprehensive set of repository and data-source interfaces for managing episode watch status and progress. Users can now track watched episodes with specific dates, observe watch progress for individual seasons or entire shows, and view upcoming episodes from followed series. The system supports marking episodes, seasons, or entire shows as watched (including cascading to previous episodes/seasons), and synchronizes this state with Trakt, including batch upserts and handling of missing metadata like genres and release years.

data/episode/api · high confidence

New episode watch tracking and sync data layer

The application now includes a dedicated data layer for tracking episode watch status and synchronizing it with external providers. This change introduces a new repository implementation that manages marking episodes and seasons as watched, observing watch progress, and handling batch synchronization of watched history. It also adds a sync repository to handle pending uploads, updates, and deletions of watched episodes, ensuring that local watch history is kept in sync with connected accounts like Trakt or Simkl. Additionally, a request store is added to manage caching and expiration of sync requests.

data/episode/implementation/src/commonMain/kotlin/com/thomaskioko/tvmaniac/episodes/implementation · high confidence

New feature flag management domain layer

The feature-flags module now includes a new domain layer for managing feature flags, introducing a \FeatureFlagRow\ data class to represent individual flag states and an \ObserveFeatureFlagRowsInteractor\ to retrieve and observe these flags. This interactor supports sorting by title, key, or date, filtering via text search, and observing real-time changes in flag values and sources, providing the foundational data structure and logic for displaying and managing feature flags in the application.

feature-flags · high confidence

New feature flag system with Firebase Remote Config and debug overrides

The feature flags module has been restructured to support remote configuration via Firebase Remote Config, allowing flags to be toggled dynamically without app updates. This change introduces a new API for defining boolean flags (such as Account Switch, Continue Watching Nitro, Paywall, Liquid Glass, and Simkl Login) with metadata like titles and descriptions, which are now visible in a debug screen. The system supports local overrides for debugging, persists these overrides across restarts, and provides a mechanism to refresh and observe flag states in real-time. Additionally, platform-specific implementations (like the iOS RemoteConfigBridge) are included to handle the underlying remote config interactions.

core/feature-flags/api · high confidence

New file and JSON storage abstractions for widget data

The application introduces a new core files module that provides platform-specific file management and JSON serialization capabilities. This includes a \FileManager\ interface for basic read/write/delete operations and a \JsonFileManager\ interface for handling typed JSON objects, with concrete implementations for Android and iOS. This change enables the application to persist widget data locally using structured JSON files, replacing any previous ad-hoc storage mechanisms.

core/files/api, core/files/implementation · high confidence

New i18n implementation with platform-specific localization and error mapping

The i18n module now includes a complete localization infrastructure: a \Localizer\ interface implemented by \MokoResourcesLocalizer\ which delegates to platform-specific \PlatformLocalizer\ instances (Android, iOS, JVM) to resolve string resources, plurals, and formatted strings. An initializer (\MokoLocaleInitializer\) observes locale changes via \distinctUntilChanged\ to update the global locale context. Additionally, a \LocalizedErrorToStringMapper\ is registered to convert technical errors (sync, backup, account) into user-facing localized messages. Tests verify correct string resolution across English, French, and German locales.

i18n/implementation · high confidence

New iOS Calendar screen with week navigation and premium locking

The iOS Calendar feature is now available as a dedicated screen within the app. Users can browse upcoming episodes by week using a navigation header with previous/next controls. The view supports loading, empty, and login-required states, and includes a premium overlay that locks the calendar content behind an upgrade prompt. The implementation includes the CalendarScreen, CalendarPageContent, and CalendarEpisodeItemView components, along with snapshot tests to verify the UI states.

ios/Packages/Calendar · high confidence

New iOS Design System with Themeable UI Components

The iOS DesignSystem package has been restructured to provide a comprehensive, themeable foundation for the app's user interface. This change introduces a unified \TvManiacTheme\ protocol and specific implementations (Light, Dark, Terminal, Autumn, Aqua, Amber, Snow, Crimson) that bundle colors, typography, spacing, and shape tokens. It adds reusable SwiftUI components such as \ProviderButton\ for OAuth flows, \PremiumOverlayModifier\ for locked content, and standardized button/text styles. The system also includes environment-based feature toggles for haptic feedback, Liquid Glass, and spoiler blurring, along with responsive layout tokens that mirror Android's width size classes to ensure consistent cross-platform behavior.

ios/Packages/DesignSystem · high confidence

New iOS UI component library for TvManiac

The iOS Components package now includes a comprehensive set of reusable SwiftUI views, establishing the visual foundation for the app. This release introduces layout and navigation aids such as \CarouselView\ (with auto-scroll and paging), \CollapsibleSection\, \ChevronTitle\, and \CenteredFullScreenView\. It adds interactive controls including multiple button styles (\FilledImageButton\, \OutlinedButton\, \CircularButton\, \FilledVerticalIconButton\ with haptic feedback support), \ChipView\, and \FilterChip\. Visual feedback is handled by \TvManiacBanner\ (with error/warning/success/info styles), \BadgeChip\ variants (Premiere, New, Lock), \AnimatedCountText\ (odometer-style transitions), and \CircularIndicator\ (progress dots). Utility components like \AboutSheet\, \AccountLimitBannerView\, \BorderTextView\, and \ImageConfiguration\ (for TMDB image resizing) are also provided, along with core extensions for geometry and size change detection.

ios/Packages/Components · high confidence

New iOS data models and widget snapshot support

The iOS Models package introduces a comprehensive set of new data structures to support the app's UI and widget features. This includes models for show details (SwiftShow, SwiftPosterImage), episode tracking (SwiftEpisode, SwiftContinueTrackingEpisode, SwiftNextEpisode), cast and genres, as well as provider and trailer information. Additionally, the package adds support for iOS widgets by defining WidgetSnapshot and WidgetContainer models, which handle theme settings and cached entry data, along with corresponding unit tests to ensure reliable serialization and deserialization of widget state.

ios/Packages/Models · high confidence

New interactor for fetching curated genre content

A new FetchGenreContentInteractor has been added to the genre domain module. This component handles the logic for fetching content for a curated set of genre slugs (such as action, comedy, drama, etc.) by delegating to the GenreRepository. It supports fetching shows for a specific category and allows for forced refreshes, integrating with the application's coroutine dispatchers for background execution.

genre · high confidence

New interactor for fetching similar shows

A new SimilarShowsInteractor has been added to the domain layer to handle the logic for retrieving similar TV shows. This component wraps the SimilarShowsRepository, executing the fetch operation on an I/O dispatcher and accepting a show ID along with an optional force-refresh flag as parameters.

similarshows · high confidence

New layout and appearance settings for the Discover screen and posters

Users can now customize the layout and visual style of the app through new settings. This includes toggling haptic feedback, adjusting font size, and blurring unwatched episode images. Additionally, users can hide specific sections in the Discover screen and customize poster styles, such as width and corner shape.

domain/settings · high confidence

New library data access interfaces for sorting, list style, and synchronization

The library module now exposes explicit interfaces for managing library data, including \LibraryRepository\, \LibraryDao\, and \LibraryRemoteDataSource\. Users can now have their library content sorted using configurable options and displayed in different list styles, with these preferences persisted locally. The repository also introduces methods to observe and save these settings, as well as to trigger library synchronization and check sync status, enabling better control over how and when library data is updated.

data/library/api/src/commonMain/kotlin/com/thomaskioko/tvmaniac/data/library · high confidence

New library data layer with sorting, list styling, and sync capabilities

This change introduces the core implementation for the TV library feature, adding a new data access object (DefaultLibraryDao) and repository (DefaultLibraryRepository) that manage local storage and synchronization of followed shows. Users can now view their library with configurable sorting options (by rank, date added, release year, or title) and apply custom list styles, with preferences persisted via Datastore. The repository handles syncing library state with remote providers (like Trakt), managing pending follow/unfollow actions, and fetching associated watch provider information for each show.

data/library/implementation/src/commonMain/kotlin/com/thomaskioko/tvmaniac/data/library/implementation · high confidence

New locale provider with platform-specific language selection and persistence

The app now includes a new locale management system that allows users to select and persist their preferred language across sessions. This change introduces a \LocaleProvider\ API and platform-specific implementations for Android, iOS, and JVM, which handle retrieving the system's default locale, listing available preferred locales, and applying language changes. The implementation uses Metro for dependency injection and persists the user's language choice via a \LanguagePreference\ interface, ensuring the selected language is remembered between app launches.

core/locale/implementation · high confidence

New modular Settings UI components for iOS

The iOS Settings package has been restructured to use a new set of modular SwiftUI views, introducing dedicated pages for Account management (including multi-account switching), Appearance (theme and image quality selection), Backup (export, import, and automatic backup configuration), Layout (font size, poster style, and discover section toggles), and general sections like Privacy, Info, and Licenses. This change replaces the previous monolithic implementation with a component-based architecture that supports features such as haptic feedback on toggles, live preview for poster styles, and premium-locked settings overlays.

ios/Packages/Settings · high confidence

New network utility API and error handling models

The network utility layer now exposes a structured API for handling HTTP requests and errors. This includes an ApiRateLimiter interface to manage request throttling, Ktor plugins for checking internet connectivity and reporting API errors, and extension functions for safe HTTP requests and paging. New model classes define specific exceptions for authentication failures, network issues, and serialization errors, along with logging utilities to report API failures with context like provider, method, and status code.

core/network-util/api/src/commonMain · high confidence

New ratings data layer and API interfaces

The ratings data layer has been initialized with new API interfaces that define how ratings are stored, retrieved, and synchronized. This includes \RatingsRepository\ for rating shows, seasons, and episodes, \RatingsDao\ for local database operations (including pending actions for sync), \RatingsRemoteDataSource\ for network calls to add/remove/observe ratings, and \ProviderMetaDao\ for provider-specific metadata. These interfaces establish the contract for the ratings feature, supporting user ratings, community ratings, and sync mechanisms.

data/ratings/api · high confidence

New ratings domain module with sync and observation logic

The ratings domain module now includes core logic for observing and syncing user and community ratings. This change introduces the ObserveCommunityRatingInteractor to stream community ratings, the RatingsSyncInitializer to handle background synchronization of pending user ratings and initial data loading, and the associated dependency injection bindings. Comprehensive test coverage has been added for these new components, as well as for existing rating interactors (ObserveRating, Rate, RefreshCommunityRating, RemoveRating, and ShouldPromptForRating), ensuring correct behavior for show, season, and episode rating operations.

domain/ratings · high confidence

New settings and preferences exposed via Datastore API

The Datastore API now exposes a comprehensive set of user preference types and repository methods, allowing the app to persist and observe a wider range of customization options. Users can now configure theme variants (including Terminal, Autumn, Aqua, Amber, Snow, and Crimson), adjust image quality (with a new 'Auto' setting), and customize poster appearance via corner styles (Sharp, Classic, Rounded, Pill) and width scales. Additional preferences include list style choices (Grid, List, Compact, Detailed), season sorting order (Oldest/Nearest first), and toggles for background sync, automatic backups (with interval and folder selection), and including specials when marking seasons watched. The API also supports language persistence, discover section visibility, and trailer opening behavior.

data/datastore/api · high confidence

New statistics data layer and calculation logic

The statistics module now includes a complete data layer and calculation engine to power the new statistics dashboard. This change introduces the \ObserveWatchStatisticsInteractor\ to aggregate data from episode, rating, and rewatch repositories, and the \WatchStatisticsCalculator\ to compute detailed metrics such as total watch time, watch streaks, genre and release year breakdowns, and daily/monthly/yearly watch counts. It also adds the \SyncStatisticsInteractor\ to handle syncing watched episodes and user ratings, along with the necessary domain models (e.g., \WatchStatistics\, \WatchDuration\, \GenreCount\) to represent these new insights.

statistics · high confidence

New theme and image quality domain models

The application now exposes a new set of visual customization options through the domain layer. Users can choose from nine distinct visual themes—including System, Light, Dark, Terminal, Autumn, Aqua, Amber, Snow, and Crimson—each with specific dark/light mode settings and display ordering. Additionally, a new ImageQuality enum allows for control over image resolution with options for Auto, High, Medium, and Low quality.

domain/theme · high confidence

New utility interfaces for date/time, formatting, and app checks

The core utility API module now exposes three new interfaces: DateTimeProvider for date and time operations (including system default timezone usage, epoch conversion, and formatting), FormatterUtil for string formatting tasks (such as TMDB image paths, number rounding, duration formatting, and compact number display), and AppUtils for checking if the YouTube player is installed. These interfaces provide a standardized contract for common utility functions used across the application.

core/util/api · high confidence

New watch provider data access interfaces

The application introduces new API interfaces for managing watch provider data. WatchProviderDao defines database operations for upserting, fetching, observing, and deleting watch provider records associated with shows. WatchProviderRepository provides a higher-level interface to fetch watch providers for a specific show (with an option to force a refresh) and observe changes to those providers via a Flow.

data/watchproviders/api · high confidence

Redesigned Profile screen with multi-account support and new content sections

The Profile screen has been completely redesigned to support a new multi-account architecture, allowing users to connect and sync content via both Trakt and Simkl. The interface now features a comprehensive set of content sections including User Lists, Progress (with Completed/In-Progress filters), Recently Watched, and Favorites, alongside a new Stats card displaying watch time and episode counts. The UI also includes a dedicated unauthenticated state to guide new users through the discovery and tracking features.

features/profile · high confidence

Rewatch tracking data layer and tests

The rewatch module now includes the domain interactors and unit tests required to track rewatch sessions. This adds the ability to start and finish rewatch sessions for shows, observe rewatch status and support, and sync rewatch data, along with comprehensive tests for the session lifecycle and episode watching logic.

domain/rewatch · high confidence

Search screen now displays genre rows and recent searches alongside search results

The search experience has been enhanced to show genre-based content rows (such as Popular, Trending, Top Rated, and Most Watched) and a list of recent searches on the main search screen, in addition to standard text-based search results. Users can now browse shows by genre category and quickly re-run previous searches via clickable chips, with the ability to clear the recent search history. The UI also includes a loading shimmer effect for search results and proper empty/error states.

features/search · high confidence

Show details now display watch progress and continue-watching episodes

The Show Details screen now integrates watch progress into the season list, showing how many episodes have been watched for each season. It also features a new Continue Watching section that displays the next unwatched episodes for followed shows, allowing users to easily resume their viewing.

domain/showdetails · high confidence

Simkl authentication support added

Users can now authenticate with Simkl to sync their account data. This change introduces the necessary implementation components, including an OAuth-based authentication manager for launching the web view, a repository for managing authentication state and tokens, and the client configuration pointing to Simkl's OAuth endpoints.

data/simklauth/implementation · high confidence

Simkl integration: new remote data sources for ratings, rewatch, and sync

This change introduces the Simkl implementation layer for ratings, rewatch sessions, and general sync operations. Users can now sync their show ratings (add/remove), manage rewatch sessions (read/write/close, requiring a Simkl Premium tier), and sync watched history and watchlist status (add/remove from watchlist, fetch last activities) with the Simkl service. The implementation includes dedicated remote data sources for these features, HTTP client configuration for Simkl APIs, and dependency bindings to integrate these capabilities into the application.

api/simkl/implementation/src/commonMain · high confidence

Trakt sync provider implementation added

The Trakt integration now includes a complete set of data source adapters for syncing user activity and library data. Users can now sync their watch history (including episode-level details and rewatch counts), manage their watchlist, track ratings for shows, seasons, and episodes, view calendar entries for upcoming episodes, search for shows, and access their "Plan to Watch" list via the Trakt provider.

api/trakt/implementation/src/commonMain/kotlin/com/thomaskioko/trakt/service/implementation/sync · high confidence

Unified multi-provider OAuth authentication system

The app now supports authenticating with multiple sync providers (such as Trakt and Simkl) through a single, provider-agnostic OAuth infrastructure. This change introduces a centralized \AuthStateHolder\ that manages and persists tokens per provider, ensuring that login states are isolated so that logging out of one service does not affect others. On Android, the system uses AppAuth to handle the authorization flow, while iOS delegates to native coordinators via a callback mechanism. Tokens are securely stored using Android DataStore and iOS Keychain respectively, and the new architecture allows new providers to be added by simply supplying their configuration without duplicating OAuth logic.

data/oauth/implementation · high confidence

User lists can now be created, edited, and deleted with offline support and Trakt synchronization

This change introduces the complete data layer for user-managed lists, allowing you to create, rename, and delete lists locally, with changes queued for synchronization to Trakt when a connection is available. The implementation uses a local database to store list metadata and associated shows (identified by TMDB IDs), supporting offline-first operations and conflict resolution for pending actions like renames or deletions. It also includes logic to restore lists from backups and fetch list contents from Trakt, ensuring that local changes are eventually consistent with the remote service.

data/lists/api, data/lists/implementation · high confidence

Widget domain layer and test infrastructure introduced

The domain/widget module now provides the core logic for home screen widgets, including interactors to observe the watchlist and apply a dedicated widget theme (falling back to the app theme or respecting subscription access), a WidgetPublisher interface for delivering show data and theme settings, and a WidgetTasksInitializer that schedules background refreshes when widgets are installed. This entry covers the domain contracts, DI bindings, and the comprehensive test suite (including fake implementations and snapshot fixture validation) that verifies this behavior.

domain/widget · high confidence

iOS Crashlytics configuration interface introduced

A new Kotlin interface, CrashlyticsConfiguration, has been added to the iOS-specific logger module. This interface defines the contract for configuring Crashlytics on iOS, exposing a read-only isConfigured property and a method to enable or disable data collection. This change establishes the API layer for integrating Crashlytics error reporting on iOS devices.

core/logger/api/src/iosMain · high confidence

iOS framework module initialization and dependency injection setup

The iOS framework module is now initialized with a Metro-based dependency injection system, defining the application and view-presenter graphs to wire up core services like logging, configuration, and background tasks. This includes an iOS-specific implementation for downloading and managing widget posters, enabling the app to display dynamic content in iOS widgets. The module also introduces a comprehensive dependency graph documentation in the README and includes unit tests to verify the correct initialization of the application graph and platform metadata.

ios-framework · high confidence

API

New API interfaces for season details data access

The \data/seasondetails/api\ module now exposes \SeasonDetailsDao\ and \SeasonDetailsRepository\ interfaces, defining the contract for fetching season details, episodes, images, and continue-tracking state. This establishes the data-layer API for season-specific information retrieval and synchronization.

data/seasondetails/api · high confidence

New data access interfaces for similar shows

The application introduces new API interfaces for managing similar shows data. The SimilarShowsDao interface defines database operations for upserting, observing, and deleting similar show records, while the SimilarShowsRepository interface exposes methods to fetch similar shows (with an option to force a refresh) and observe the list of similar shows for a given show ID.

data/similar/api · high confidence

New navigation API interfaces for multi-stack routing and result handling

The navigation module now exposes a new public API in \navigation/api\ that defines the contracts for the app's multi-stack navigation model. This includes the \Navigator\ interface, which provides methods for pushing routes, switching tabs, and managing back stacks, as well as \BaseRoute\, \NavRoute\, and \NavRoot\ interfaces to distinguish between stack entries and tab anchors. The API also introduces \NavigationResultRegistry\ for handling results between destinations, \NavDestination\ for mapping routes to UI components, and serializer interfaces (\BaseRouteSerializer\, \NavRootSerializer\, \NavRouteSerializer\) to support state preservation. Additionally, \OverlayRoute\ and associated child wrappers (\RootChild\, \SheetChild\) enable modal overlay support.

navigation/api · high confidence

Architecture

Datastore implementation migrated to Metro DI and decoupled architecture

The local preferences storage layer has been refactored to use the Metro dependency injection framework, replacing the previous binding mechanism. This change introduces a decoupled architecture where platform-specific DataStore instances (e.g., Android) are provided via \DataStorePlatformBindingContainer\, while common preference logic is handled by dedicated classes like \DatastoreCrashReportingPreference\ and \DefaultDatastoreRepository\. Users benefit from a more modular and testable data layer that cleanly separates platform bindings from core preference operations.

data/datastore/implementation/src/commonMain · high confidence

Introduces Metro DI infrastructure and qualifiers for dependency injection

The core/base module now includes the foundational components for the Metro dependency injection framework. This adds an \AppInitializers\ class to manage synchronous and asynchronous app startup tasks, an \ActivityScope\ for scoping, and a comprehensive set of qualifiers (such as \ApplicationContext\, \SimklApi\, \FeatureFlagLocalsDataStore\, and various coroutine scopes) that define how dependencies are bound and injected throughout the application.

core/base/src/commonMain/kotlin/com/thomaskioko/tvmaniac/core/base · high confidence

Presenter layer refactored into modular, feature-specific components

The presentation layer has been restructured to use dedicated presenter modules for each feature area, including Calendar, Continue Watching, Debug, Discover, Episode Sheet, Feature Flags, Genre Shows, Home, Library, Lists, More Shows, My Shows, and Profile. Each module now defines its own sealed action interfaces and state data classes, replacing the previous monolithic or loosely organized presenter structure. This change improves code organization, testability, and maintainability by isolating UI logic per feature.

presenter · high confidence

Show details domain logic modularized into specific interactors

The show details feature has been refactored to use a modular domain structure, replacing monolithic logic with dedicated interactors for fetching cast, seasons, episodes, trailers, and watch providers. This change introduces new domain models for ShowDetails, Casts, Providers, Season, Show, and Trailer, and updates the FollowShowInteractor to handle library synchronization and metadata syncing asynchronously. Users benefit from a more maintainable codebase that supports better separation of concerns for show-related data operations.

showdetails · high confidence

Behavioural changes

43 commits (6 fixes) modifying data/database/sqldelight/src/commonMain/sqldelight/com/thomaskioko/tvmaniac/schemas

A change to existing behaviour in data/database/sqldelight/src/commonMain/sqldelight/com/thomaskioko/tvmaniac/schemas — 43 commits (6 fixs), 44 files.

data/database/sqldelight/src/commonMain/sqldelight/com/thomaskioko/tvmaniac/schemas · medium confidence · unverified

Account manager now supports multiple sync providers

The account management system has been refactored to support multiple authentication providers (such as Trakt and Simkl) simultaneously. The new DefaultAccountManager implementation manages a map of repositories keyed by provider, allowing users to connect and switch between different sync sources. The system automatically resolves the active provider based on login state and selection, exposes connection events for each provider, and centralizes token refresh and error handling across all connected accounts.

data/account-manager/implementation · high confidence

Account switching now enforces a timeout during provider connection

The account-switcher now includes a new interactor that handles connecting to and switching between provider accounts. This change introduces a 2-minute timeout for the OAuth connection process; if the account does not connect within this window, the switch operation fails with an error rather than hanging indefinitely. This ensures users receive immediate feedback if a provider connection attempt stalls.

account-switcher · high confidence

Account switching now preserves local tracking data and pushes pending changes

When switching between Trakt and Simkl accounts, the app now pushes any pending local changes (such as watched episodes and followed shows) to the current provider before switching, and it no longer clears your watch history or tracked shows during the logout process. The switch operation now logs out of the old provider, clears only the account credentials (preserving tracking data), activates the new provider, and triggers a background resync of your profile, library, and continue-watching status to ensure the new account's data is up to date.

domain/account-switcher · high confidence

Android background tasks now use WorkManager with Metro DI

The Android implementation of the background task scheduler has been replaced to use AndroidX WorkManager instead of the previous platform-specific scheduling mechanism. This change introduces a new AndroidTaskScheduler that manages periodic and one-time tasks via WorkManager, along with a SchedulerDispatchWorker to route and execute those tasks. Dependency injection for WorkManager is now handled through a Metro binding container, ensuring the scheduler is properly wired into the app's dependency graph.

core/tasks/implementation/src/androidMain · high confidence

Application initialization now uses Metro DI and configures WorkManager and StrictMode

The app's entry point has been refactored to use the Metro dependency injection framework, replacing the previous setup. This change introduces explicit configuration for AndroidX WorkManager via a custom WorkerFactory and enables StrictMode checks in debug builds to help detect performance issues like leaked objects or network violations.

app/src · high confidence

Background worker factory now exposes registered worker names

The DefaultWorkerFactory implementation now exposes a workerNames property that returns the set of registered background worker names. This allows consumers to query which workers are available in the system, supporting better introspection and management of background tasks within the application.

core/tasks/implementation/src/commonMain · high confidence

Calendar feature now requires Premium subscription access

The Calendar feature has been updated to enforce a paywall, restricting access to Premium subscribers. The new \CalendarPresenter\ and \CalendarScreen\ components now check subscription status via \SubscriptionManager\ and display a locked state with upgrade prompts when the user lacks access. This change introduces a behavioral shift where the calendar is no longer available to free users, aligning with the new paywall UI component.

features/calendar · high confidence

Centralized settings domain model and interactor

The settings domain layer now exposes a unified \SettingsPreferences\ model and an \ObserveSettingsPreferencesInteractor\ that aggregates all user preferences into a single observable stream. This includes layout-specific options (haptic feedback, season sorting, font size, poster dimensions, and corner styles), general app settings (theme, image quality, background sync, notifications, crash reporting, and debug menu), and widget theming. A \PremiumAccess\ data class is also introduced to track feature-gated capabilities such as backup, custom themes, and quick rating.

settings · high confidence

Centralized sync state tracking and error reporting

The application now uses a unified \SyncObserver\ to monitor synchronization status and handle errors. Users will see a consistent 'syncing' indicator in the UI that accurately reflects multiple concurrent operations, and sync failures (such as rate limits or account limits) are now captured and reported for better diagnostics.

core/syncstate/implementation · high confidence

Continue Watching section now includes Watchlist and Completed Shows

The Continue Watching area has been expanded to display three distinct sections: the existing Up Next episodes, a new Watchlist section showing shows the user is tracking, and a new Completed Shows section for finished series. This consolidation means users can now manage their watch progress, upcoming episodes, and completed titles from a single unified view, with the domain layer updated to fetch and merge data from the Up Next, Watchlist, and watched history sources.

continue-watching · high confidence

Database layer refactored to support multi-provider IDs and new tracking features

The local database module has been restructured to support multiple data providers (Trakt, Simkl, TMDB) by introducing a \Provider\ enum and a \ShowIdResolver\ for mapping external IDs to internal database keys. This change consolidates watchlist and 'up next' data into a 'Continue Watching' view, adds support for tracking rewatch sessions, ratings, and followed shows, and implements a schema migration strategy that rebuilds the database if the on-disk version mismatches the expected schema.

data/database/sqldelight/src/commonMain/kotlin/com.thomaskioko.tvmaniac.db · high confidence

Database schema migrations for Trakt sync and watch progress tracking

This update introduces a series of database migrations (1 through 30) that fundamentally restructure the local data layer to support Trakt synchronization and improved watch tracking. The schema migrates primary identifiers from TMDB to Trakt IDs, introduces tables for followed shows, watch providers, and custom lists, and replaces cached progress counts with live SQL views for accurate 'Continue Watching' and 'Up Next' displays. It also adds support for calendar entries, genre-based show lists, and refined episode airing logic to ensure only released content is tracked.

data/database/sqldelight/src/commonMain/sqldelight/com/thomaskioko/tvmaniac/migrations · high confidence

Debug build now shows a distinct notification icon and initializes debug notifications

In debug builds, the app now uses a dedicated debug bug icon (ic\_debug\_bug) for notifications instead of the standard launcher icon, and a new initializer automatically manages the visibility of debug notifications based on the episode notification setting. This change is implemented via new debug-specific components (DebugNotificationIconProvider, DebugNotificationInitializer, and its DI binding) that replace the production notification icon provider and ensure debug notifications are shown or dismissed in sync with user preferences.

app/src/debug/kotlin · high confidence

Debug builds can now override remote feature flags locally

Developers can now override remote feature flags in debug builds using a local DataStore, which takes precedence over Firebase Remote Config values. This change introduces platform-specific implementations (AndroidRemoteConfig and IosRemoteConfig) that feed into a shared RemoteConfigState, wrapped by DebugRemoteConfig/IosDebugRemoteConfig to handle the override logic. The system also supports real-time updates from the remote provider and adjusts fetch intervals based on the debug configuration.

core/feature-flags/implementation · high confidence

Decentralized screen and sheet rendering via multibindings

The navigation UI now uses a decentralized rendering model where individual feature modules contribute their own screen and sheet renderers. New classes, ScreenContent and SheetContent, allow each feature to define a matcher and a Compose composable, which are collected via Hilt multibindings into sets. A new CompositionLocal, LocalScreenContents, provides access to these registered renderers at the root, enabling the navigation layer to dispatch screens and sheets without maintaining direct imports of feature-specific UI code.

navigation/ui · high confidence

Discover and More Shows screens adopt Liquid Glass styling with scroll-edge effect controls

The Discover and More Shows screens on iOS now support the new Liquid Glass visual style, which provides a translucent, glass-like appearance for the navigation bar and toolbar when scrolling. This change also hides the scroll-edge effects (glows/shadows) at the top and bottom of the scroll views to ensure a cleaner, more consistent look under the new styling. The implementation includes a fallback to the legacy toolbar design for older iOS versions or when Liquid Glass is disabled. Additionally, the Discover screen now features a custom pull-to-refresh indicator that appears at the top of the scroll view, and the More Shows screen uses a standard system refreshable behavior. These changes are part of a broader effort to align the iOS design system with the latest Apple design guidelines.

ios/Packages/Discover · high confidence

Discover feature refactored to use Decompose components

The domain layer for the Discover feature has been refactored to use Decompose components. This change introduces new interactor classes (ObserveFeaturedShowsInteractor, ObservePopularShowsInteractor, ObserveTopRatedShowsInteractor, ObserveTrendingShowsInteractor, ObserveUpcomingShowsInteractor) that extend SubjectInteractor and are injected via Metro. Corresponding unit tests have been added for each interactor to verify their behavior with fake repositories.

domain/discover · high confidence

Discover screen restructured into modular Decompose presenters

The Discover feature's presentation layer has been refactored to use a Decompose-based component hierarchy, splitting the screen into distinct child presenters for Featured, Catalog, Up Next, and Start Watching sections. This change introduces a new \:features:discover:nav\ module for navigation routing and a \:features:discover:presenter\ module containing the logic for each section, allowing for better state management and testability. The main \DiscoverShowsPresenter\ now aggregates the state from these children to drive the overall UI, while specific presenters handle their own data fetching and navigation actions, such as opening show details or navigating to more shows.

features/discover · high confidence

Episode notifications now persist across reboots and handle scheduling errors gracefully

The Android notification system now survives device reboots by registering a BootCompletedReceiver that re-arms scheduled alarms for pending episode notifications. To improve reliability, the implementation skips scheduling if notifications are disabled and clears corrupted data if deserialization of pending notifications fails. Additionally, the Android notification window start time is now calculated as the maximum of the scheduled time and the current time, ensuring alarms are set correctly for past-due episodes.

core/notifications/implementation · high confidence

Genre module adopts Metro DI and refactors interactor usage

The genre domain module has been updated to use the Metro dependency injection framework, replacing the previous DI approach. This change includes the introduction of GenreShowsInteractor, which now explicitly uses Metro's @Inject annotation for dependency injection, and involves removing unused classes and updating initializers to align with the new DI architecture. The interactor itself fetches genres with shows using the injected repository and coroutine dispatchers.

domain/genre · high confidence

Home screen navigation restructured into modular presenter and UI components

The home screen's internal architecture has been refactored to separate concerns into distinct \nav\, \presenter\, and \ui\ modules. This change introduces a new \HomePresenter\ that manages the active tab state (Discover, Progress, My Shows, Profile) and exposes a \hostState\ for the UI to observe. The \HomeScreen\ Composable now consumes this presenter to render a bottom navigation bar and a tab content area, utilizing the \Decompose\ library for managing the back stacks of each tab. This modularization improves testability, as evidenced by the new \HomePresenterTest\ suite, and clarifies the dependency graph between the home feature and other navigation roots.

features/home · high confidence

Improved reliability of iOS background task scheduling

The iOS background task scheduler now uses a short initial delay (5 minutes) when first scheduling or resubmitting tasks, preventing rapid app foreground/background cycles from indefinitely pushing the execution time forward. It also eagerly registers all background task handlers at app launch and only resubmits requests that the system has actually dropped, ensuring background jobs run more predictably and reliably.

core/tasks/implementation/src/iosMain · high confidence

Introduce multi-provider account management API

The account management API has been refactored to support multiple synchronization providers (Trakt and Simkl) instead of a single backend. This change introduces a new \AccountManager\ interface to handle active provider selection and account switching, alongside dedicated interfaces for authentication (\AccountAuthRepository\, \AuthManager\) and provider configuration (\AuthClientConfig\). The system now uses a \SyncProviderSource\ enum to distinguish between Trakt and Simkl, allowing the application to manage connections and authentication states for either provider dynamically.

data/account-manager/api · high confidence

Introduce typed ID wrapper classes for database entities

Added a new file defining specific value classes (e.g., CastId, EpisodeId, ShowId, TraktId) to wrap Long identifiers. This change enforces type safety for database primary keys, ensuring that different entity IDs are not accidentally mixed up in queries or data structures.

sqldelight · high confidence

Introduces Metro-based interactor for observing season details

The Season Details domain module now includes an interactor class that uses the Metro dependency injection framework to combine observations of season images, season details, and cast information into a single result stream. This change replaces previous implementation patterns with a new interactor structure that aggregates data from the season details and cast repositories.

domain/seasondetails · high confidence

Introduces new UI banners and restructures the iOS app root navigation

The iOS app now displays an Account Limit banner prompting users to upgrade to Trakt VIP when limits are reached, and an Offline Banner that indicates connectivity status (warning when offline, success when back online). The root navigation structure has been reorganized into a new \RootNavigationView\ that manages the tab bar, splash screen, and overlays for these banners. Additionally, the \ScreenRegistryBootstrap\ has been updated to register new screens and sheets, including the Lists, List Detail, Genre Shows, Trailers, Statistics, and Watch Date Selection features, ensuring they are properly wired into the navigation system.

ios/Packages/Root · high confidence

Introduces provider-scoped activity sync checkpoints

The sync-activity module now tracks per-consumer sync positions scoped to the active provider (e.g., Trakt, Simkl) instead of using a single shared timestamp. This prevents one provider's sync marks from suppressing reads for another, ensuring that switching accounts or adding new providers does not cause sync collisions or lost progress. The implementation includes a new \ActivitySyncRepository\ API, Trakt-specific data access and fetching layers, and comprehensive tests verifying checkpoint isolation across providers, consumers, and activity types.

data/sync-activity/implementation · high confidence

A new FeaturedShowsInteractor class has been added to the featured shows API module, implementing the Interactor pattern to handle fetching featured shows. This component uses the FeaturedShowsRepository and AppCoroutineDispatchers to execute the fetch operation on an I/O dispatcher, marking a shift towards explicit interactor-based architecture for this data source.

data/featuredshows/api/src/commonMain/kotlin/com/thomaskioko/tvmaniac/data/featuredshows/api/interactor · high confidence

Library remote data sources are now collected via multibindings

The library module now uses dependency-injection multibindings to collect all registered LibraryRemoteDataSource implementations. An active source is automatically selected by matching the provider of the currently active account, allowing the system to support multiple data sources and switch between them based on the user's account context.

data/library/implementation/src/commonMain/kotlin/com/thomaskioko/tvmaniac/data/library/implementation/di · high confidence

Library sync now runs as a scheduled background worker with reconnect handling

Library synchronization has been refactored to use a dedicated \LibrarySyncWorker\ that runs periodically (every 12 hours) in the background, rather than inline. The \SyncTasksInitializer\ now manages this schedule, starting the worker only when the user is logged in and background sync is enabled, and cancelling it otherwise. Additionally, the system now detects network reconnections and triggers a non-forced library sync to ensure data stays up-to-date after connectivity is restored. This change includes the necessary dependency injection bindings and comprehensive tests for the worker, initializer, and interactor logic.

domain/library · high confidence

Library synchronization logic restructured with new interactor classes

The library sync process has been refactored into dedicated domain interactors: \SyncLibraryInteractor\ and \ObserveLibraryInteractor\. The sync interactor now explicitly manages the sequence of operations, including syncing the library watchlist, updating watched episodes, and performing a fan-out to sync metadata for followed shows only when the watchlist has changed. It also includes a new step to backfill missing genres for watched shows. The observe interactor provides a flow of library items, supporting query filtering, sorting options, and a 'followed only' toggle. This change centralizes the sync orchestration and observation logic within the domain layer.

library · high confidence

Logger module split into public API interfaces

The logger module has been refactored to separate its public contract from its implementation. New public interfaces have been introduced in the API layer: \Logger\ for standard logging operations (debug, info, warning, error) and exception recording, \CrashReporter\ for specific crash-reporting actions like setting user IDs and custom keys, and \CrashReportingPreference\ to observe crash-reporting settings. Additionally, \CrashReportKeys\ provides a centralized set of constants for crash report metadata. This change decouples the logging API, allowing the underlying implementation (such as Firebase Crashlytics) to be swapped or updated without affecting code that depends on the logger.

core/logger/api/src/commonMain · high confidence

Logout now preserves local viewing history and ratings

Logging out no longer deletes your local watch history, ratings, rewatch sessions, or locally created lists. The new logout implementation distinguishes between account-specific data (such as favorites, synced lists, calendar entries, and provider metadata) which is cleared, and personal tracking data (watched episodes, followed shows, continue-watching status, ratings, and rewatch sessions) which is retained for the next session.

data/logout/implementation · high confidence

Logout preserves tracking data and saves last user ID

The new LogoutInteractor in the domain/logout module now saves the current Trakt user ID to the datastore before clearing account data. This ensures that tracked shows and watch history are preserved during logout, addressing the previous behavior where such data might have been lost. The interactor also handles logging out of the active provider if one is connected, and does nothing if no provider is active.

domain/logout · high confidence

Migrate date-time and formatting utilities to Metro DI

The date-time and formatting utilities in the core/util/implementation module have been refactored to use the Metro dependency injection framework. Platform-specific implementations (Android and iOS) for AppUtils and FormatterUtil are now registered via Metro bindings, and the shared DefaultDateTimeProvider is wired with a system clock and the platform formatter. This change standardizes how date parsing, formatting, and app-integrity checks are provided across the app, ensuring consistent behavior for date calculations and number formatting.

core/util/implementation · high confidence

Migrate dependency injection to Metro

The app's dependency injection system has been migrated to the Metro library. This change introduces new Application and Activity graphs that manage core app components, including authentication managers, navigation, and debug configuration, replacing the previous DI implementation.

app/src/main/kotlin/com/thomaskioko/tvmaniac/app/di · high confidence

Migrate similar shows data layer to new store and DAO implementation

The similar shows feature now uses a dedicated \DefaultSimilarShowsDao\ and \SimilarShowStore\ to manage data persistence and fetching. This change introduces a new repository implementation that coordinates between a caching store (which fetches related shows from Trakt and details from TMDB) and a local database, ensuring that similar show lists are stored and retrieved efficiently using the new DAO interface.

data/similar/implementation · high confidence

Migration to Metro dependency injection

The application's dependency injection system has been migrated to Metro. This change introduces new binding containers for the TMDB and Trakt API implementations to provide HTTP client engines, registers the application context in the base module, and updates app-level utilities like the notification icon provider and worker factory to use Metro's injection capabilities.

(repo-wide) · high confidence

Migration to Metro dependency injection framework

The application's dependency injection system has been migrated to the Metro framework. This change introduces new binding containers that provide core infrastructure components, including coroutine dispatchers and scoped coroutine scopes (IO, Main, Computation) with integrated crash handling. It also establishes multibindings for application initializers, allowing for modular registration of both synchronous and asynchronous startup tasks.

core/base/src/commonMain/kotlin/com/thomaskioko/tvmaniac/core/base/di · high confidence

My Shows feature restructured into Continue Watching and Start Watching tabs

The My Shows section has been refactored to replace the previous Watchlist view with two distinct tabs: 'Continue Watching' and 'Start Watching'. This change introduces a new tabbed interface that aggregates content from both the Continue Watching and Start Watching features, allowing users to switch between their ongoing series and new shows they intend to watch. The UI includes support for search, sorting options (by title, release date, or date added), and list style preferences (grid, list, compact, detailed), with layout options potentially locked behind a premium subscription.

features/my-shows · high confidence

The navigation layer has been updated to use Kotlinx Serialization for all route definitions. Every feature module (such as Discover, Library, My Shows, Lists, and Settings) now exposes its navigation targets as \@Serializable\ data objects or classes implementing \NavRoute\ or \NavRoot\. Parameters for screens like Show Details, Season Details, and List Details are also defined as serializable data classes, enabling type-safe, serialized navigation across the application.

nav · high confidence

The navigation implementation now automatically preserves the active tab, per-tab back stacks, and overlay state when the app is backgrounded or the device is rotated. This is achieved by introducing a unified, annotation-driven serializer system (DefaultBaseRouteSerializer, DefaultNavRootSerializer, DefaultNavRouteSerializer) that dynamically composes polymorphic serializers for all registered navigation routes and roots. The DefaultNavigator uses these serializers with Decompose's state management to ensure that navigation state is serialized and restored seamlessly, preventing data loss during lifecycle events.

navigation/implementation · high confidence

The app now uses a new MainActivity that initializes the ActivityGraph, handles deep links from intents and notifications (opening specific shows or debug menus), and manages the splash screen exit animation. It enables edge-to-edge display with dynamic status and navigation bar styling based on the user's selected theme (light/dark/system), and configures the root Compose UI with theme, font size, poster scaling, and haptic feedback settings.

app/src/main/kotlin/com/thomaskioko/tvmaniac/app · high confidence

New Season Details UI with episode tracking and haptic feedback

The Season Details screen has been rebuilt with a new SwiftUI-based interface that includes a collapsible episode list, a horizontal cast carousel, and an image gallery view. Users can now mark episodes as watched via a checkmark button, with support for a long-press action to select previous episodes. The interface provides visual feedback for watch progress and includes haptic feedback on iOS when toggling the watched state.

ios/Packages/SeasonDetails · high confidence

New customizable themes and responsive layout system

The app introduces several new visual themes—Amber, Snow, Crimson, Terminal, Autumn, and Aqua—allowing users to change the app's appearance beyond the standard light and dark modes. Additionally, a new responsive layout engine has been implemented, enabling users to customize poster and backdrop card sizes (scale) and corner radii, while automatically adjusting grid columns and spacing based on the device's window width.

android-designsystem/src/main/kotlin/com/thomaskioko/tvmaniac/compose/theme · high confidence

New debug menu with Liquid Glass styling

The iOS debug menu has been rebuilt using SwiftUI, introducing a new \DebugScreen\ and \DebugMenuView\ that support the Liquid Glass visual style (with a legacy fallback). This update adds specific debug capabilities, including the ability to switch between Premium and Free account types, and provides a standardized list-based UI for triggering actions like notifications and syncs.

ios/Packages/Debug · high confidence

New episode detail sheet with watch-date selection and play-count display

The iOS episode detail sheet now includes a play count indicator for re-watched episodes, displays the episode's rating and vote count, and supports selecting or updating the date an episode was watched via a new selection sheet (offering 'Just now', 'Release date', 'Other date', or 'Unknown date'). The sheet also features a shimmer loading state to prevent layout flashing, applies the Liquid Glass visual variant, and triggers haptic feedback when marking an episode as watched or unwatched.

ios/Packages/EpisodeDetail · high confidence

New iOS app entry point with toast notifications, deep linking, and lifecycle management

The iOS app now uses a new \iOSApp.swift\ entry point that integrates a \ToastManager\ for displaying user notifications, handles deep links via \onOpenURL\ to open shows and episodes, and manages app lifecycle states (active, inactive, background) using SwiftUI's \scenePhase\. It also includes a \RootToastForwarder\ view to bridge internal toast states to the UI and a \RootNavigationView\ for navigation.

ios/ios · high confidence

New show reconciliation and Trakt ID resolution logic

This change introduces the implementation for reconciling TV shows and resolving missing Trakt identifiers. The new DefaultShowReconciler ensures that shows are properly linked by creating stubs in the database when a TMDB ID is found (including via IMDB lookup) and preventing the overwriting of existing show metadata. Additionally, the TraktShowIdResolver automatically looks up and stores Trakt IDs for shows that are missing them, using the active provider context to determine when to perform these lookups. The DefaultTvShowsDao implementation supports these operations with specific upsert and external ID handling, backed by new unit tests verifying the reconciliation and ID resolution behaviors.

data/shows/implementation · high confidence

Optimized image loading with quality-aware caching and Metro DI

The app now uses a new image loading implementation that adapts to the user's selected image quality setting (Low, Medium, High, or Auto). This change introduces a TMDb interceptor that automatically resizes images from TMDb to match the chosen quality level, reducing bandwidth and improving load times. Additionally, the disk cache size for images is now dynamic: it scales based on the quality setting (e.g., 125MB for Low, 250MB for Medium/Auto, 500MB for High) to better manage storage. The entire image loading infrastructure, including the Coil image loader, OkHttp client, and quality provider, has been migrated to use the Metro dependency injection framework.

core/imageloading/implementation · high confidence

Redesigned Show Details screen with modular sections and Liquid Glass navigation

The iOS Show Details screen has been rebuilt using a modular component architecture, breaking the view into distinct sections for the header, cast, providers, trailers, similar shows, and season progress. This refactor introduces a new parallax header with a Liquid Glass navigation bar that transitions between a standard iOS toolbar and a custom glass overlay based on scroll position. Users will see a more structured layout with dedicated horizontal scroll areas for cast members, watch providers (sourced from JustWatch), and trailers, alongside a new season progress card that visualizes watched episodes and allows quick season selection.

ios/Packages/ShowDetails · high confidence

Redesigned iOS search experience with poster grid and recent searches

The iOS search interface has been overhauled to display search results as a poster grid and includes a new section for recent searches. Users can now browse shows by genre, view results in a grid layout with metadata like year and episode count, and quickly re-run previous searches via a scrollable list of recent queries.

ios/Packages/Search · high confidence

Refactored episode notification scheduling and management

The notification module has been restructured to improve reliability and maintainability. The \ScheduleEpisodeNotificationsInteractor\ now preserves existing alarms for episodes whose notification time has already passed, preventing duplicate or missed alerts. A new \ScheduleDebugEpisodeNotificationInteractor\ allows developers to trigger test notifications for debugging purposes. Additionally, \ToggleEpisodeNotificationsInteractor\ now manages the notification state and rationale display, while \RefreshUpcomingSeasonDetailsInteractor\ and \SyncCalendarInteractor\ handle metadata synchronization with rate limiting and provider feature checks.

notifications · high confidence

Request manager repository implementation and validation logic

The \DefaultRequestManagerRepository\ is introduced to handle request persistence and validation. It now uses an injected \DateTimeProvider\ for time-sensitive operations instead of system calls, and implements \isRequestValid\ to check if requests have expired based on a configurable threshold. The repository also includes logic to clear sync-related requests and supports upserting and deleting request records in the local database.

data/request-manager/implementation/src/commonMain · high confidence

Rewatch tracking now supports session-based recording and syncing

The rewatch feature has been updated to track viewing activity through explicit sessions. Users can now start and finish rewatch sessions for specific shows, and individual episodes watched during these sessions are recorded with timestamps. The system also includes a mechanism to synchronize pending rewatch data with external services, ensuring that viewing history is kept up to date across platforms.

rewatch · high confidence

Season details data layer migrated to TMDB with new caching and mapping logic

The season details implementation has been updated to fetch metadata from The Movie Database (TMDB) instead of Trakt. This change introduces a new caching strategy using the Store5 library to manage season details and episodes, along with a dedicated mapper (TmdbSeasonMapper) to convert TMDB responses into the app's internal data models. The repository now handles synchronization with request expiration checks and persists cast information alongside season images. Additionally, the data access object (DefaultSeasonDetailsDao) has been refactored to use specific SQLDelight query types and includes logic for managing season images and deleting records within database transactions.

data/seasondetails/implementation · high confidence

Season details domain logic migrated to new interactor modules

The season details feature now uses a dedicated set of domain interactors to manage season data and watch status. This includes new logic for fetching season details, observing watch progress, and handling watched/unwatched states (including marking previous seasons as watched and clearing plays when a season is removed). The domain models for season details, cast, and images have also been updated to support these operations.

seasondetails · high confidence

The season details screen has been refactored to support new user interactions. Users can now rate a season, which opens a dedicated rating sheet. Long-pressing an episode's watched status opens a date selection dialog to edit the watch date. Additionally, users can view a gallery of season images via a bottom sheet. The screen also displays season progress, cast, and images, with state management handled by a new presenter layer.

features/season-details · high confidence

Seasons data layer API restructured with new query methods

The Seasons data API has been updated to expose new repository and DAO interfaces that support fetching seasons by show ID, observing seasons via Kotlin Flows, and retrieving the latest season for followed shows. The API now includes methods to filter out special seasons, update image URLs, and delete season data, reflecting a shift towards more granular data access patterns using SQLDelight-generated types.

data/seasons/api · high confidence

Seasons data layer migrated to Metro DI and SQLDelight with new query capabilities

The seasons data implementation has been rewritten to use the Metro dependency injection framework (replacing previous bindings) and integrates with SQLDelight for database access. This change introduces new data-fetching capabilities, including the ability to retrieve the latest season for followed shows and filter out special seasons. The repository now also respects user preferences for including special seasons via Datastore, and the DAO layer uses a show ID resolver to handle identifier mapping internally.

data/seasons/implementation · high confidence

Settings screen restructured with new presenter, UI components, and navigation

The Settings screen has been refactored into a modular architecture comprising a new presenter layer, UI components, and navigation module. Users will see a reorganized Settings interface with distinct pages for Appearance, Behavior, Notifications, Privacy, Info, Licenses, Account, Layout, Discover Sections, Poster Style, Backup, and Widget Appearance. The presenter now manages complex state including account switching, backup operations, and premium feature locks, while the UI layer provides reusable Compose components for settings rows, sections, and loading states. Navigation has been decoupled into a separate module with its own dependency graph.

features/settings · high confidence

Show details now fetch from TMDB with Trakt fallback and persist via SQLDelight

The show details data layer has been rewritten to primarily fetch TV show metadata from the TMDB API, falling back to Trakt only when a Trakt ID is available to resolve the TMDB identifier. This change introduces a new \ShowDetailsStore\ that handles caching and validation, a \ShowDetailsDao\ backed by SQLDelight for local persistence, and a \DefaultShowDetailsRepository\ that coordinates between the store and the DAO. Users will see show details populated from TMDB sources, with seasons and cast information also persisted locally, improving data consistency and reducing reliance on Trakt for core metadata.

data/showdetails/implementation · high confidence

Show details screen logic is modularized into distinct child presenters

The Show Details feature has been refactored to use a modular component architecture. The main \ShowDetailsPresenter\ now delegates specific responsibilities to separate child presenters for the header, seasons/episodes, cast, providers, trailers, and similar shows. This change introduces a new \ShowDetailsChildScope\ to manage the lifecycle of these sub-components and updates the navigation routing to use annotation-based code generation. For users, this ensures that individual sections of the show details page (such as cast lists or episode tracking) can be refreshed and managed independently, improving responsiveness and maintainability of the screen's behavior.

features/show-details · high confidence

Standardized genre naming and improved show data merging

The shows data layer now standardizes genre names to ensure consistency between Trakt and TMDB sources, handling specific mappings like splitting 'Action & Adventure' into separate genres. Additionally, a new utility merges local and network show data more intelligently, preserving local details like overviews and ratings when network data is incomplete, and introduces a DAO interface with upsert-merging capabilities to support this behavior.

data/shows/api · high confidence

TMDB network layer refactored with Metro DI and enhanced HTTP resilience

The TMDB API implementation has been restructured to use the Metro dependency injection framework, replacing previous binding mechanisms with explicit \@ContributesBinding\ and \@Provides\ declarations in \TmdbBindingContainer\. The HTTP client now includes an \HttpRequestRetry\ plugin that automatically retries requests on 5xx errors and rate-limit responses (429) using exponential backoff, improving reliability during network instability. Additionally, network logging is now strictly controlled by the debug configuration, ensuring verbose HTTP logs are only emitted in debug builds to reduce noise in production.

api/tmdb/implementation/src/commonMain · high confidence

Top Rated Shows data layer adds pagination and Metro DI

The Top Rated Shows data module now supports paginated fetching of top-rated TV shows, exposing repository and DAO methods that accept page numbers and force-refresh flags to optimize data loading. The repository interface has been updated to return paginated data streams, and the interactor class has been introduced to handle the business logic for fetching shows. Additionally, the interactor now uses Metro for dependency injection, replacing the previous mechanism.

data/topratedshows/api · high confidence

Trailer data access layer refactored to use new DAO and repository interfaces

The trailer data module has been restructured to introduce new \TrailerDao\ and \TrailerRepository\ interfaces. The DAO now exposes methods for upserting, retrieving, and deleting trailers by show ID, including reactive observation via Kotlin Flows. The repository interface abstracts the data source, providing methods to observe trailers, fetch them with an optional force-refresh capability, and check for YouTube player availability. This change replaces previous implementation details with a cleaner, interface-based contract for trailer data operations.

data/trailers/api · high confidence

Trailers data layer migrated to Metro DI and Store5

The trailers data implementation has been refactored to use the Metro dependency injection framework (replacing the previous system) and the Store5 caching library. This change updates the DefaultTrailerDao and DefaultTrailerRepository to use Metro's @ContributesBinding and @SingleIn annotations, and modifies the repository to fetch trailer data via Store5's fresh/get extensions, ensuring consistent caching behavior for trailer content.

data/trailers/implementation · high confidence

Trakt API client now includes authentication guard and enhanced retry logic

The Trakt HTTP client implementation has been updated to include a new \TraktAuthGuard\ plugin that prevents outgoing requests to authenticated endpoints if the user is not logged in, providing a defense-in-depth measure against race conditions during logout. The client also features improved error handling with specific messages for rate limits (HTTP 420/429) and server errors, along with an exponential backoff retry strategy for 5xx and rate-limit responses. Additionally, the dependency injection setup for the Trakt service has been migrated to use the Metro framework via \TraktBindingContainer\.

api/trakt/implementation/src/commonMain/kotlin/com/thomaskioko/trakt/service/implementation · high confidence

Trakt token refresh is now automated and handles revoked tokens

The Trakt authentication flow now automatically refreshes access tokens in the background every five hours, ensuring uninterrupted sync without requiring the user to re-authenticate. This change introduces a dedicated background worker that detects when tokens are expiring soon and proactively updates them. Additionally, the system now correctly handles token revocation errors (such as invalid\_grant or 401 responses) by terminating the session and prompting the user to log in again, rather than failing silently or retrying indefinitely.

data/traktauth/implementation · high confidence

The trending shows data module has been restructured to introduce a clean API layer consisting of new interfaces for the DAO, Repository, and Interactor. This change enables paginated fetching of trending shows via \PagingSource\ and \Flow\<PagingData\>\, allowing users to browse content in chunks rather than loading everything at once. The repository now supports force-refresh logic and page-based observation, while the interactor handles the background execution of fetch operations. Additionally, explicit API visibility modifiers have been applied to these new interfaces to enforce public contracts.

data/trendingshows/api · high confidence

Up Next screen now preserves scroll position and supports sorting

The Up Next screen now remembers its scroll position when covered by other screens (such as Show Details) and automatically scrolls to the top when the sort order is changed between Last Watched and Air Date. This behavioral change improves navigation continuity and ensures the list view remains intuitive when users switch sorting preferences.

features/upnext · high confidence

Upcoming shows data layer now supports pagination and force refresh

The upcoming shows data layer has been updated to support paginated data fetching and force refresh capabilities. The \UpcomingShowsRepository\ now exposes \getPagedUpcomingShows\ returning \PagingData\ for efficient list handling, alongside \fetchUpcomingShows\ which accepts a \forceRefresh\ parameter to bypass local cache when needed. The \UpcomingShowsDao\ interface provides \getPagedUpcomingShows\ as a \PagingSource\ and \pageExists\ to validate page availability, while the \UpcomingShowsInteractor\ coordinates these operations using the Metro DI framework.

data/upcomingshows/api · high confidence

User data layer refactored to support multi-provider sync and reactive profiles

The user data module has been restructured to support multiple sync providers (such as Trakt and Simkl) by introducing a \UserRemoteDataSource\ interface and a multibinding mechanism that selects the active provider based on the current account. User profiles and statistics are now fetched via \Store\ instances (\UserStore\ and \UserStatsStore\) that handle caching, validation, and persistence to the local database. The \UserDao\ and \UserStatsDao\ implementations now expose reactive \Flow\-based APIs for observing user profiles and stats, automatically combining user data with library backdrops and formatted watch-time statistics. This change enables the app to seamlessly switch between providers and ensures that user profile data and statistics are kept in sync with the active account.

data/user/implementation · high confidence

User profile observation and list synchronization behavior

The user domain now includes an interactor to observe the current user's profile, which combines the account connection state with user data to determine authentication status. Additionally, the logic for updating user profile data has been refined to conditionally handle list operations based on the active provider: it now syncs pending lists and fetches user lists only when the Trakt provider is active, while skipping these steps for Simkl or unauthenticated states.

domain/user · high confidence

Watch providers now deduplicate brand variants to show canonical services

The watch provider data layer now automatically collapses duplicate or variant entries for the same streaming service into a single canonical brand. Previously, users might have seen multiple entries for services like MGM+ (e.g., "MGM+", "MGM Plus", "MGM+ Amazon Channel") or Amazon Prime Video (e.g., "Amazon Prime Video with Ads"). The new implementation uses a word-prefix matching algorithm to identify these variants and keeps only the shortest, canonical name (e.g., "MGM Plus" or "Amazon Prime Video"), ensuring a cleaner and less confusing list of available providers.

data/watchproviders/implementation · high confidence

iOS API clients now use Darwin HTTP engine via Metro DI

The TMDB and Trakt API implementations on iOS now explicitly register the Ktor Darwin HTTP engine through the Metro dependency injection framework. This change introduces platform-specific binding containers that provide the network engine, ensuring that API calls on iOS devices utilize the native Darwin stack rather than a generic or stub implementation.

api/tmdb/implementation/src/iosMain, api/trakt/implementation/src/iosMain · high confidence

iOS DataStore initialization now supports state clearing via environment variable

The iOS-specific DataStore binding has been updated to check for the \TVMANIAC\_CLEAR\_STATE\ environment variable during startup. When this variable is set to "1", the application will automatically delete the existing DataStore file before initializing, allowing users or testers to reset app preferences to a clean state without manual intervention.

data/datastore/implementation/src/iosMain · high confidence

iOS Simkl API uses stubbed HTTP engine in tests

On iOS, the Simkl API integration now explicitly provides a stub HTTP engine (StubHttpEngine) when available, falling back to the native Darwin engine otherwise. This change decouples the platform-specific HTTP client configuration for the Simkl module, ensuring that test environments can intercept or mock network requests without affecting the production Darwin-based implementation.

api/simkl/implementation/src/iosMain · high confidence

iOS database driver initialization and dependency injection updated

The iOS database layer now uses a new IosDatabaseDriverBuilder that configures SQLite with WAL journaling and explicitly forces migration execution during driver creation to ensure schema upgrades run before the database is closed. Additionally, the iOS-specific dependency injection container now supports clearing the local database state via the TVMANIAC\_CLEAR\_STATE environment variable, allowing tests or users to start with a fresh database instance.

data/database/sqldelight/src/iosMain · high confidence

Fixes

Improved background job handling and uncaught exception management

The app now provides more robust handling for background tasks and uncaught errors. A new \AppScopeLauncher\ allows background work (such as sync operations) to continue even if the user navigates away, while ensuring that failures are logged rather than causing silent crashes. Additionally, a centralized \CoroutineCrashUtil\ now captures uncaught coroutine exceptions, allowing the app to handle or report them consistently. Background jobs are managed by a dedicated \SyncCoroutineScope\ that supports graceful cancellation with a timeout, ensuring that in-flight work is cleaned up properly during logout or process shutdown.

core/base/src/commonMain/kotlin/com/thomaskioko/tvmaniac/core/base/coroutines · high confidence

Test coverage

Add Home screen test tags for UI automation; Added Compose UI test robots for app screens; Added Compose journey tests for Simkl integration and provider switching; Added FakeApiRateLimiter for testing; Added FakeBackgroundTaskScheduler for testing; Added FakeCastRepository for testing; Added FakeDatastoreRepository for testing; Added FakeFileManager for testing; Added FakeGenreRepository for testing; Added FakeListRepository for testing list operations; Added FakeNotificationManager for testing; Added FakePopularShowsRepository for testing; Added FakeProviderFeatures for testing; Added FakeRequestManagerRepository for testing; Added FakeRewatchRepository for testing; Added FakeSeasonDetailsRepository for testing; Added FakeSeasonsRepository for testing; Added FakeUserRepository for testing; Added FakeWatchlistPrefsRepository for testing; Added JVM tests for Trakt remote data sources; Added UI flow tests for the Calendar screen; Added UI tests for the My Shows flow; Added comprehensive database migration tests; Added cross-platform database testing infrastructure; Added custom instrumentation test runner for test application injection; Added database migration test utilities; Added fake Trakt remote data sources for testing; Added fake data source for ratings testing; Added fake data sources for Simkl API testing; Added fake data sources for episode testing; Added fake implementations for activity sync testing; Added fake implementations for feature flag testing; Added fake implementations for show data layer testing; Added fake internet connection checker for testing; Added fake network data sources for TMDB show details and shows; Added fake repository for testing Featured Shows; Added fake repository implementations for testing; Added i18n testing utilities for localization verification; Added iOS integration test infrastructure for stubbed HTTP and fixtures; Added iOS test infrastructure for dependency injection; Added integration test infrastructure and reconnect sync flow test; Added integration test stubs and fixtures for Trakt, Simkl, and TMDB services; Added integration tests for Discover flow navigation and tracking; Added integration tests for Settings flow and offline behavior; Added integration tests for search flow and genre navigation; Added integration tests for season and episode tracking flows; Added integration tests for show details interactions; Added integration tests for the Up Next flow; Added integration tests for the episode sheet user flow; Added integration tests for user list creation, management, and deletion flows; Added navigation testing utilities; Added screenshot and functional tests for design system components; Added test activity for Compose integration tests; Added test double for Up Next repository; Added test doubles for the watch status data layer; Added test fakes for Trakt authentication and token refresh; Added test fakes for app metadata, date/time, and formatting utilities; Added test fakes for backup data layer components; Added test fakes for core, data, and API layers; Added test fakes for language and locale providers; Added test fixture for SimilarShowsRepository; Added test fixture for crash reporting preferences; Added test infrastructure for Continue Watching data layer; Added test infrastructure for dependency injection; Added test infrastructure for integration testing; Added test infrastructure for shared JVM/iOS integration tests; Added test infrastructure for subscription management; Added test tags for UI automation across core screens; Added test tags for Watch Date Selection UI; Added test tags for collapsible sections, design components, and notification rationale; Added test tags for the progress screen UI components; Added test utilities for OAuth token refresh; Added test utilities for Recommended Shows repository; Added test utilities for deep link URL mapping; Added test utilities for the trailers module; Added tests for ObserveFeatureFlagRowsInteractor; Added tests for Simkl remote data sources; Added tests for Trakt HTTP client authentication and guard plugin; Added tests for backup JSON serialization and restore logic; Added tests for core coroutine and flow utilities; Added tests for datastore repository and backup filename sanitization; Added tests for deep link navigation to show details; Added tests for episode tracking, watch progress, and notification logic; Added tests for foreign key migration safety; Added tests for integration stub server and fixture loading; Added tests for navigation routes and dependency graph factories; Added tests for network error reporting and connectivity plugins; Added tests for paging extensions and API failure handling; Added tests for request manager cache validation and repository operations; Added tests for statistics domain logic; Added tests for the Android design system theme and typography; Added tests for the Featured Shows database access layer; Added tests for the Followed Shows data layer; Added tests for the ObserveRecentlyWatched interactor; Added tests for the fake HTTP engine binding container; Added tests for the popular shows data access object; Added tests for the rewatch data layer; Added unit tests for Android and iOS task scheduling workers; Added unit tests for DefaultCalendarRepository; Added unit tests for LibraryStore synchronization logic; Added unit tests for ShowCastStore; Added unit tests for SyncActivityInteractor; Added unit tests for Trakt sync data sources; Added unit tests for the Recommended Shows Store; New Android integration test infrastructure with system dialog handling; New JVM integration test infrastructure with fake dependencies; New shared stub infrastructure for integration tests; New shared test stubs for multi-provider authentication and UI scenarios.

Dependencies

Add Fastlane and Xcode tooling dependencies

The project now includes a Gemfile and Gemfile.lock that define the Ruby dependencies for its CI/CD pipeline. This introduces fastlane (v2.238.0) for automating iOS builds and releases, along with xcode-install and xcpretty for managing Xcode versions and formatting build output. The lockfile also pins specific versions for fastlane plugins (firebase\_app\_distribution, test\center) and their underlying libraries (e.g., aws-sdk-s3, google-apis-\), ensuring reproducible build environments.

(dependencies) · high confidence

Upgraded Gradle wrapper to v9.7.1 and configured JVM toolchain

The project's Gradle wrapper has been updated to version 9.7.1, ensuring builds use this specific distribution. Additionally, a new \gradle-daemon-jvm.properties\ file has been introduced to configure the Gradle daemon to use Azul JDK 21 across supported platforms (Linux, macOS, Windows, FreeBSD), and a \lint.xml\ file has been added to suppress specific Gradle and Android lint warnings.

gradle · high confidence

Housekeeping

App module documentation and build configuration added; Data module dependency graphs added to documentation; New release process documentation added.

Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.

How this codebase got here

Score

  • CAI 62 → 62 (-0.2)
  • Rubric changed (rubric-2026.08.19 → rubric-2026.09.15) — scores are not directly comparable.

Lenses

  • Code Health 95 → 94 (-1.0)
  • Architecture 99 → 89 (-10.9)
  • Maturity 77 → 81 (+3.3)
  • Readiness 59 → 49 (-10.6)
  • Security 48 → 59 (+10.5)
  • Domain Modelling 100 → 100 (+0.0)

Resolved (114)

  • Boundary-crossing change coupling: DebugMenuScreen.kt ↔ DebugMenuView.swift (features/debug/ui/src/main/kotlin/com/thomaskioko/tvmaniac/debug/ui/DebugMenuScreen.kt)
  • Change coupling clique: FakePopularShowsRepository.kt, FakeTopRatedShowsRepository.kt, FakeTrendingShowsRepository.kt, FakeUpcomingShowsRepository.kt (data/popularshows/testing/src/commonMain/kotlin/com/thomaskioko/tvmaniac/data/popularshows/testing/FakePopularShowsRepository.kt)
  • Change coupling: DefaultTrendingShowsRepository.kt ↔ UpcomingShowsRepository.kt (data/trendingshows/implementation/src/commonMain/kotlin/com/thomaskioko/tvmaniac/discover/implementation/DefaultTrendingShowsRepository.kt)
  • Change coupling: DiscoverShowsAction.kt ↔ DiscoverViewState.kt (features/discover/presenter/src/commonMain/kotlin/com/thomaskioko/tvmaniac/discover/presenter/DiscoverShowsAction.kt)
  • Coverage not included — suite not readable by the collector
  • Dependency hygiene not measured — dependency manifest found but not parsed for hygiene
  • Duplicated block (10 lines × 2) (android-designsystem/src/main/kotlin/com/thomaskioko/tvmaniac/compose/components/SwitchRow.kt)
  • Duplicated block (10 lines × 2) (data/episode/implementation/src/commonMain/kotlin/com/thomaskioko/tvmaniac/episodes/implementation/DefaultWatchedEpisodeSyncRepository.kt)
  • Duplicated block (10 lines × 2) (features/search/ui/src/main/kotlin/com/thomaskioko/tvmaniac/search/ui/components/SearchResultItem.kt)
  • Duplicated block (10 lines × 3) (core/base/src/commonMain/kotlin/com/thomaskioko/tvmaniac/core/base/extensions/Combine.kt)
  • Duplicated block (10 lines × 5) (data/featuredshows/implementation/src/commonMain/kotlin/com/thomaskioko/tvmaniac/data/featuredshows/implementation/FeaturedShowsStore.kt)
  • Duplicated block (11 lines × 2) (data/continue-watching/implementation/src/commonMain/kotlin/com/thomaskioko/tvmaniac/continuewatching/implementation/DefaultContinueWatchingDao.kt)
  • Duplicated block (11 lines × 2) (data/followedshows/implementation/src/commonMain/kotlin/com/thomaskioko/tvmaniac/followedshows/implementation/DefaultFollowedShowsDao.kt)
  • Duplicated block (11 lines × 2) (data/user/implementation/src/commonMain/kotlin/com/thomaskioko/tvmaniac/data/user/implementation/DefaultUserDao.kt)
  • Duplicated block (11 lines × 2) (domain/continue-watching/src/commonMain/kotlin/com/thomaskioko/tvmaniac/domain/continuewatching/ContinueWatchingSyncWorker.kt)
  • Duplicated block (11 lines × 2) (features/library/ui/src/main/kotlin/com/thomaskioko/tvmaniac/ui/library/LibraryScreen.kt)
  • Duplicated block (12 lines × 2) (android-designsystem/src/main/kotlin/com/thomaskioko/tvmaniac/compose/components/NavigationBar.kt)
  • Duplicated block (12 lines × 2) (android-designsystem/src/main/kotlin/com/thomaskioko/tvmaniac/compose/components/SwitchRow.kt)
  • Duplicated block (12 lines × 2) (data/continue-watching/implementation/src/commonMain/kotlin/com/thomaskioko/tvmaniac/continuewatching/implementation/NitroContinueWatchingStore.kt)
  • Duplicated block (12 lines × 2) (data/popularshows/implementation/src/commonMain/kotlin/com/thomaskioko/tvmaniac/data/popularshows/implementation/DefaultPopularShowsRepository.kt)
  • …and 94 more

New (273)

  • Change coupling: Colors.kt ↔ Theme.kt (android-designsystem/src/main/kotlin/com/thomaskioko/tvmaniac/compose/theme/Colors.kt)
  • Change coupling: ContinueWatchingPreviewParameterProvider.kt ↔ MyShowsScreen.kt (features/continue-watching/ui/src/main/kotlin/com/thomaskioko/tvmaniac/continuewatching/ui/ContinueWatchingPreviewParameterProvider.kt)
  • Change coupling: DefaultEpisodeRepository.kt ↔ FakeEpisodeRepository.kt (data/episode/implementation/src/commonMain/kotlin/com/thomaskioko/tvmaniac/episodes/implementation/DefaultEpisodeRepository.kt)
  • Change coupling: DefaultSeasonDetailsRepository.kt ↔ FakeSeasonDetailsRepository.kt (data/seasondetails/implementation/src/commonMain/kotlin/com/thomaskioko/tvmaniac/seasondetails/implementation/DefaultSeasonDetailsRepository.kt)
  • Change coupling: DefaultSeasonsRepository.kt ↔ FakeSeasonsRepository.kt (data/seasons/implementation/src/commonMain/kotlin/com/thomaskioko/tvmaniac/seasons/implementation/DefaultSeasonsRepository.kt)
  • Change coupling: DiscoverPreviewParameterProvider.kt ↔ DiscoverScreen.kt (features/discover/ui/src/main/java/com/thomaskioko/tvmaniac/discover/ui/DiscoverPreviewParameterProvider.kt)
  • Change coupling: SeasonPreviewParameterProvider.kt ↔ CollapsableContent.kt (features/season-details/ui/src/main/java/com/thomaskioko/tvmaniac/seasondetails/ui/SeasonPreviewParameterProvider.kt)
  • Change coupling: SeasonPreviewParameterProvider.kt ↔ EpisodeItem.kt (features/season-details/ui/src/main/java/com/thomaskioko/tvmaniac/seasondetails/ui/SeasonPreviewParameterProvider.kt)
  • Change coupling: SettingsActions.kt ↔ SettingsState.kt (features/settings/presenter/src/commonMain/kotlin/com/thomaskioko/tvmaniac/settings/presenter/SettingsActions.kt)
  • CircularIndicator.body (cognitive 19) (ios/Packages/Components/Sources/Components/CircularIndicator.swift)
  • ClassTooLong: DefaultWatchedEpisodeDao (data/episode/implementation/src/commonMain/kotlin/com/thomaskioko/tvmaniac/episodes/implementation/dao/DefaultWatchedEpisodeDao.kt)
  • ClassTooLong: SettingsPresenter (features/settings/presenter/src/commonMain/kotlin/com/thomaskioko/tvmaniac/settings/presenter/SettingsPresenter.kt)
  • Coverage not measured — Swift suite
  • Documentation: no installation or build instructions
  • Documentation: no installation or build instructions (:domain:seasondetails/README.md)
  • Documentation: no project overview (:domain:seasondetails/README.md)
  • Documentation: no usage examples (:domain:seasondetails/README.md)
  • Documentation: no usage examples (README.md)
  • Duplicate constructor signature for State
  • Duplicated block (10 lines × 2) (features/genre-shows/ui/src/main/kotlin/com/thomaskioko/tvmaniac/genreshows/ui/GenreShowsScreen.kt)
  • …and 253 more

Changes since last survey

  • 196 commits — 176 feature/other, 20 fixes

By area

  • ios/Packages — 32 commits
  • gradle/libs.versions.toml — 22 commits
  • app/dependencies — 20 commits
  • app/src — 14 commits
  • features/statistics — 10 commits
  • (root) — 8 commits
  • data/rewatch — 7 commits
  • features/settings — 7 commits
  • data/backup — 6 commits
  • .github/workflows — 5 commits
  • data/episode — 5 commits
  • .github/actions — 4 commits
  • features/show-details — 4 commits
  • data/lists — 3 commits
  • domain/widget — 3 commits
  • features/episode-sheet — 3 commits
  • features/lists — 3 commits
  • i18n/generator — 3 commits
  • api/trakt — 2 commits
  • core/integration — 2 commits

Notable commits

  • fix: chore: Fix Lint & Scoping bug (#1264)
  • fix: fix: Add missing genres for watched shows (#1197)
  • fix: fix: Clear a season's plays when it is removed from watched (#1228)
  • fix: fix: Clear removed episode (#1222)
  • fix: fix: Fix Heatmap legend and current day (#1209)
  • fix: fix: Fix Nightly emulator run (#1347)
  • fix: fix: Fix Watch status breakdown (#1190)
  • fix: fix: Fix flaky tests (#1231)
  • fix: fix: Flaky Test (#1214)
  • fix: fix: Improve flaky tests failure rate (#1279)
  • fix: fix: Keep tracked shows and watch history when logging out (#1249)
  • fix: fix: List changes cleanup (#1339)
  • fix: fix: Page the Trakt list items and watchlist requests (#1321)
  • fix: fix: Restore play counts (#1229)
  • fix: fix: Simkl offline status (#1370)
  • fix: fix: Standardize genre name (#1194)
  • fix: fix: Translate the missing German and French strings (#1253)
  • fix: fix: UI bug fixes (#1201)
  • fix: fix: Upload iOS debug symbols to Crashlytics on release builds (#1199)
  • fix: test: Fix iOS tests and the datastore repository test (#1320)
  • …and 176 more

Architecture

  • Containers 0 added · 0 removed · contexts 37 added · 0 removed · edges 118 added · 0 removed

Added bounded contexts (37)

  • account-switcher
  • android-designsystem
  • api
  • app
  • backup
  • base
  • calendar
  • continue-watching
  • episode
  • favorites
  • feature-flags
  • genre
  • implementation
  • infra
  • library
  • lists
  • nav
  • notifications
  • paging
  • presenter
  • …and 17 more

Added dependency edges (118)

  • account-switcher → api
  • account-switcher → base
  • account-switcher → continue-watching
  • account-switcher → library
  • account-switcher → user
  • api → base (coupling)
  • api → sqldelight (coupling)
  • app → api (coupling)
  • app → base
  • app → implementation
  • app → presenter
  • app → settings
  • app → ui
  • app → widget
  • backup → api (coupling)
  • backup → base (coupling)
  • backup → showdetails
  • base → api
  • base → view
  • calendar → api
  • …and 98 more

Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.

Survey your own repository

thomaskioko/tv-maniac was measured the same way every project in this corpus was: the same rubric, at a pinned commit, with the result published in full. Point a surveyor at a repository you know and see whether you agree with it.

About this page

  • The score is its most recent published measurement, taken on 22 September 2026 at a pinned commit. It is not a live figure and does not change until the project is measured again.
  • Measured at commit 8038c2e88e6f14e30f28d19bbe623e18496d0290 — the exact code this score is about.
  • Scored under rubric-2026.09.15 — the same rubric and the same method as every other entry in this index.
  • Measured by watchdog.canine.dev using codehealth-analyzer preprod-821afab8930d.