Instruction file imported from SpesnetCaveman/SpesnetTogglSync (
.cursor/rules/services-conventions.mdc). Copyright stays with the author.
Services / API conventions
SyncService
- Fail-fast validation before Spesnet writes (including required Toggl description; whitespace-only is missing).
- User-facing validation / abort messages show entry times in South African (GMT+2 / SAST), not UTC.
- Only completed Toggl entries sync (
duration < 0or nullstop→ warn and stop; defer later entries so start-based watermark cannot orphan the runner). - Watermark is entry
StartUtconly (exclusive>; overlaps still sync); log a warning when ranges overlap. - Spesnet
txdatetimeis the entry start in South African (GMT+2) local time, not UTC. - Update watermark via
ConfigService.SaveSyncStateafter each successful entry. - Raise
Progressfor UI status / DateTimePicker updates.
API libraries
- Toggl lives in
SpesnetTogglSync.TogglApi; Spesnet (real + mock) inSpesnetTogglSync.SpesnetApi. - Implement
ITogglClient/ISpesnetTimekeepingClient; disposeHttpClientowners. - HTTP type is
TogglApiClient(notTogglClient— that name is the model). - Real Spesnet:
CookieContainerafterPOST api/Account/Login. - Mock: log JSON payloads; load
Data/mock-spesnet-reference.jsonfrom app base directory. - New Spesnet endpoints: add to interface + both real and mock.
- All live HTTP must go through
TogglApiHttp.SendAsync/SpesnetApiHttp.SendAsyncso failures hitCreateFailure(central debugger breakpoint + AI prompt exception message).
Config / logging
- Persist via
ConfigServiceJSON (camelCase, indented) under the resolved data directory. - Bootstrap: optional
config-location.jsonnext to the exe (dataDirectory); never put that path only inside appsettings. - Do not commit secrets; extend
appsettings.example.json/config-location.example.jsonfor new keys. - Use
FileLogger(IApiLogger) for auditable trail (logs under data directory). - Log each Ignore skip explicitly; end sync with synced/skipped summary counts.