mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-11 13:52:20 +00:00
Six provider syncs returned a bare count, which narrowed their failures away: a Nightscout window in which every SGV row was refused by a constraint returned the same 0 as a quiet night, and an Oura or Polar run whose collections all failed returned 0 too. The routes then answered 200 with a count and the settings card drew a green tick over it. Every sync now reports what it imported AND whether any part of it did not land, and the route resolves the outcome server-side so the web card and the native client cannot disagree. Google Health keeps its 502 for a run that failed and wrote nothing, but a run that failed after writing some resources is now a partial rather than a discarded result. The labs OCR commit carries the same resolved outcome.
36 lines
1.3 KiB
TypeScript
36 lines
1.3 KiB
TypeScript
import { apiHandler, requireAuth } from "@/lib/api-handler";
|
|
import { apiSuccess, apiError } from "@/lib/api-response";
|
|
import { annotate } from "@/lib/logging/context";
|
|
import { resolveSyncOutcome } from "@/lib/outcome/written-outcome";
|
|
import { syncUserWhoop } from "@/lib/whoop/sync";
|
|
import { NextRequest } from "next/server";
|
|
|
|
/**
|
|
* Manually trigger a WHOOP sync for the current user (v1.11.0).
|
|
*
|
|
* Mirrors the Withings manual-sync route: incremental by default, full
|
|
* history when `{ fullSync: true }` is posted.
|
|
*/
|
|
export const POST = apiHandler(async (request: NextRequest) => {
|
|
const { user } = await requireAuth();
|
|
annotate({ action: { name: "whoop.sync" } });
|
|
|
|
let fullSync = false;
|
|
try {
|
|
const raw = await request.text();
|
|
// Flag-only payload — cap the parse cost (mirrors safeJson maxBytes).
|
|
if (raw.length > 64 * 1024) {
|
|
return apiError(`Request body exceeds ${64 * 1024} bytes`, 413);
|
|
}
|
|
const body = JSON.parse(raw);
|
|
fullSync = body?.fullSync === true;
|
|
} catch {
|
|
// no body provided -> default incremental sync
|
|
}
|
|
|
|
// Resolved server-side so the card and the native client cannot disagree on
|
|
// how the same run reads.
|
|
const result = await syncUserWhoop(user.id, { fullSync });
|
|
return apiSuccess({ ...resolveSyncOutcome(result), fullSync });
|
|
});
|