Repository navigation
Add sync worker, HTTP API and sync server tests - #2
Merged
Merged
Conversation
Commands are applied to the local collection right away and answered through the message's reply, then pushed to the sync server once the debounce window closes. Sync failures are classified and logged by AnkiSyncService along with the final sync status. Request bodies are bound with FSharp.SystemTextJson and validated with DataAnnotations; missing, null and invalid fields come back as 422 with per-field errors. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Defaults for the Ankit and SyncServer sections, listening on port 5000 to match compose.yaml. Sync credentials are left empty and are meant to come from environment variables or user-secrets. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
POST /sync/full with "upload" or "download" resolves FullSyncRequired, which the first sync of a non-empty collection always runs into. The full sync goes through the worker like the other commands, media is synced right after it, and failures come back as 502. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The server is built with Testcontainers from Anki's example Dockerfile at the Anki tag the rslib bindings use, with cargo limited to 4 jobs so the build doesn't run out of memory. The tests skip without Docker running Linux containers. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Verify-Format runs Fantomas, a local tool, but the verify job never ran "dotnet tool restore", so the check failed before Fantomas started. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
SyncStatus. rslib errors are classified intoSyncFailed(invalid credentials, aborted, network, server rejected, full sync required, backend/native failures). Follows server redirects.Ankit:SyncDebounceTime) closes. Handlers only see the result of their command.POST /decks{ "name" }POST /notes{ "deckId", "noteTypeId", "fields", "tags"? }POST /sync/full{ "direction": "upload" | "download" }: resolvesFullSyncRequired, which the first sync of a non-empty collection always hitsappsettings.jsonwith theAnkitandSyncServersections. Credentials are left empty, so set them withSyncServer__Username/SyncServer__Password.Tests
Ankit.Server.Testsruns the sync service against a real Anki sync server started with Testcontainers.paket.dependencies. Cargo is limited to 4 jobs because a build with the default parallelism ran out of memory.Results:
FullSyncRequired FullSync, then/sync/fullupload and download.Notes
FullSyncRequireduntil someone calls/sync/fullonce.🤖 Generated with Claude Code