Watch History Sync is a .NET 10 worker that syncs watched history from one configured source to one or more configured destinations. Supported providers are Simkl, Trakt, and Pmdb.
Find a file
2026-04-22 21:40:06 -07:00
src Add xUnit v3 sync coverage and test inventory 2026-04-22 13:25:58 -07:00
tests Restructure and standardize test projects 2026-04-22 21:28:16 -07:00
.gitignore Update .gitignore 2026-04-22 08:17:29 -07:00
AGENTS.md Clarify AGENTS test change rules 2026-04-22 13:30:42 -07:00
README.md Add xUnit v3 sync coverage and test inventory 2026-04-22 13:25:58 -07:00
TESTS.md Simplify TESTS inventory layout 2026-04-22 21:38:47 -07:00
WatchHistorySync.slnx Restructure and standardize test projects 2026-04-22 21:28:16 -07:00

Watch History Sync

Watch History Sync is a .NET 10 worker that syncs watched history from one configured source to one or more configured destinations. Supported providers are Simkl, Trakt, and Pmdb.

Dependencies

  • .NET 10 SDK
  • Network access to the APIs used by your configured providers
  • Valid provider credentials in configuration
  • NuGet restore access for Coravel 6.0.0

Commands

dotnet build WatchHistorySync.slnx
dotnet test WatchHistorySync.slnx
dotnet run --project src/WatchHistorySync.Worker -- --validate-config
dotnet run --project src/WatchHistorySync.Worker -- --run-once <job-name>
dotnet run --project src/WatchHistorySync.Worker -- --run-window <job-name> --from 2026-04-01T00:00:00Z --to 2026-04-02T00:00:00Z
dotnet run --project src/WatchHistorySync.Worker
  • dotnet build WatchHistorySync.slnx restores packages and builds the solution.
  • dotnet test WatchHistorySync.slnx runs the xUnit v3 test suite.
  • --validate-config validates startup configuration and checks enabled-job providers, then exits.
  • --run-once <job-name> runs one enabled job using that job's configured LookbackWindow.
  • --run-window <job-name> --from <iso-8601> --to <iso-8601> runs one enabled job for an explicit UTC window. --to must be later than --from.
  • Running without command arguments starts the scheduled worker.

Tests

The committed automated test inventory lives in the root TESTS.md.

Configuration

Configuration is bound from the WatchHistorySync section in src/WatchHistorySync.Worker/appsettings.json. Standard .NET configuration overrides such as appsettings.Development.json and environment variables can be used on top of the base file.

WatchHistorySync:Providers entries support:

  • Name: unique provider name referenced by jobs
  • Kind: Simkl, Trakt, or Pmdb
  • BaseUrl: optional override for the provider API root
  • Simkl.ClientId and Simkl.AccessToken: required when Kind is Simkl
  • Trakt.ClientId and Trakt.AccessToken: required when Kind is Trakt
  • Pmdb.ApiKey: required when Kind is Pmdb

Default provider base URLs:

  • Simkl: https://api.simkl.com/
  • Trakt: https://api.trakt.tv/
  • Pmdb: https://publicmetadb.com/

WatchHistorySync:Jobs entries support:

  • Name: unique job name
  • Enabled: whether the job participates in validation and execution
  • Source: provider name for the single source
  • Destinations: one or more provider names for destinations
  • LookbackWindow: positive TimeSpan used by --run-once and scheduled runs
  • Schedule: UTC cron expression used by the scheduler
  • PreventOverlapKey: optional overlap lock key
  • RunOnStartup: whether the job runs once when the worker starts

Each job must have exactly one source, at least one destination, known provider names, and a source that is not also listed as a destination.

Example:

{
  "WatchHistorySync": {
    "Providers": [
      {
        "Name": "simkl-main",
        "Kind": "Simkl",
        "Simkl": {
          "ClientId": "replace-me",
          "AccessToken": "replace-me"
        }
      },
      {
        "Name": "trakt-main",
        "Kind": "Trakt",
        "Trakt": {
          "ClientId": "replace-me",
          "AccessToken": "replace-me"
        }
      },
      {
        "Name": "pmdb-main",
        "Kind": "Pmdb",
        "Pmdb": {
          "ApiKey": "replace-me"
        }
      }
    ],
    "Jobs": [
      {
        "Name": "simkl-to-trakt-and-pmdb",
        "Enabled": false,
        "Source": "simkl-main",
        "Destinations": ["trakt-main", "pmdb-main"],
        "LookbackWindow": "1.00:00:00",
        "Schedule": "0 */6 * * *",
        "PreventOverlapKey": "simkl-to-trakt-and-pmdb",
        "RunOnStartup": false
      }
    ]
  }
}