refactor: merge internal/sync into internal/garmin, regroup api files and routes
Garmin auth/sync routes move under /api/garmin/*; sync.Service becomes garmin.Sync with garmin.SyncConfig/ClientConfig; applog becomes internal/log; the test mock moves into the garmin package as MockClient (breaking the test-only import cycle the merge created); stale test URLs and type names updated to match. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -80,20 +80,20 @@ export const api = {
|
||||
body: JSON.stringify({ display_name: displayName }),
|
||||
}),
|
||||
|
||||
// Auth
|
||||
login: () => request<AuthResponse>("/api/auth/login", { method: "POST" }),
|
||||
submitMFA: (code: string) =>
|
||||
request<AuthResponse>("/api/auth/mfa", { method: "POST", body: JSON.stringify({ code }) }),
|
||||
authStatus: () => request<AuthResponse>("/api/auth/status"),
|
||||
// Garmin Auth
|
||||
garminLogin: () => request<AuthResponse>("/api/garmin/auth/login", { method: "POST" }),
|
||||
garminMFA: (code: string) =>
|
||||
request<AuthResponse>("/api/garmin/auth/mfa", { method: "POST", body: JSON.stringify({ code }) }),
|
||||
garminStatus: () => request<AuthResponse>("/api/garmin/auth/status"),
|
||||
|
||||
// Sync
|
||||
syncRun: () => request<{ status: string }>("/api/sync/run", { method: "POST" }),
|
||||
// Garmin Sync
|
||||
garminSyncRun: () => request<{ status: string }>("/api/garmin/sync/run", { method: "POST" }),
|
||||
// Deletes every synced activity (and its laps/samples/kind assignments)
|
||||
// and rewinds the backfill watermark -- destructive, gated by a
|
||||
// confirmation in the UI.
|
||||
resetSync: () => request<{ status: string }>("/api/sync/reset", { method: "POST" }),
|
||||
syncRuns: () => request<SyncRun[]>("/api/sync/runs"),
|
||||
syncStatus: () => request<SyncStatus>("/api/sync/status"),
|
||||
garminSyncReset: () => request<{ status: string }>("/api/garmin/sync/reset", { method: "POST" }),
|
||||
garminSyncRuns: () => request<SyncRun[]>("/api/garmin/sync/runs"),
|
||||
garminSyncStatus: () => request<SyncStatus>("/api/garmin/sync/status"),
|
||||
|
||||
// Training types -- fixed taxonomy, no create/delete
|
||||
listWorkoutKinds: (includeInactive = false) =>
|
||||
|
||||
@@ -18,9 +18,9 @@ export function GarminConnection({ onBeforeConnect }: { onBeforeConnect?: () =>
|
||||
// it's open, so this no longer needs the "poll faster while syncing"
|
||||
// dynamic interval it used to have.
|
||||
useEffect(() => {
|
||||
api.authStatus().then(setAuth).catch((e) => showError(String(e)));
|
||||
api.garminStatus().then(setAuth).catch((e) => showError(String(e)));
|
||||
const interval = setInterval(() => {
|
||||
api.authStatus().then(setAuth).catch(() => {});
|
||||
api.garminStatus().then(setAuth).catch(() => {});
|
||||
}, 6000);
|
||||
return () => clearInterval(interval);
|
||||
}, []);
|
||||
@@ -29,7 +29,7 @@ export function GarminConnection({ onBeforeConnect }: { onBeforeConnect?: () =>
|
||||
setBusy(true);
|
||||
try {
|
||||
await onBeforeConnect?.();
|
||||
const result = await api.login();
|
||||
const result = await api.garminLogin();
|
||||
setAuth(result);
|
||||
setDisconnected(false);
|
||||
if (result.status === "authenticated") showSuccess("Connected to Garmin successfully.");
|
||||
@@ -48,7 +48,7 @@ export function GarminConnection({ onBeforeConnect }: { onBeforeConnect?: () =>
|
||||
if (!code.trim()) return;
|
||||
setBusy(true);
|
||||
try {
|
||||
const result = await api.submitMFA(code.trim());
|
||||
const result = await api.garminMFA(code.trim());
|
||||
setAuth(result);
|
||||
if (result.status === "authenticated") showSuccess("Connected to Garmin successfully.");
|
||||
} catch (e) {
|
||||
@@ -61,7 +61,7 @@ export function GarminConnection({ onBeforeConnect }: { onBeforeConnect?: () =>
|
||||
async function sync() {
|
||||
setBusy(true);
|
||||
try {
|
||||
await api.syncRun();
|
||||
await api.garminSyncRun();
|
||||
setShowSyncModal(true);
|
||||
} catch (e) {
|
||||
showError(String(e));
|
||||
@@ -76,14 +76,14 @@ export function GarminConnection({ onBeforeConnect }: { onBeforeConnect?: () =>
|
||||
}
|
||||
setBusy(true);
|
||||
try {
|
||||
await api.resetSync();
|
||||
await api.garminSyncReset();
|
||||
// Reset runs as a background sync job; wait for it to actually finish
|
||||
// before reloading, otherwise other pages (e.g. Activities) would
|
||||
// still show the just-deleted activities from their own stale state.
|
||||
let status = await api.syncStatus();
|
||||
let status = await api.garminSyncStatus();
|
||||
while (status.in_progress) {
|
||||
await new Promise((resolve) => setTimeout(resolve, 300));
|
||||
status = await api.syncStatus();
|
||||
status = await api.garminSyncStatus();
|
||||
}
|
||||
window.location.reload();
|
||||
} catch (e) {
|
||||
|
||||
@@ -61,7 +61,7 @@ export function SyncModal({ onClose }: { onClose: () => void }) {
|
||||
let timeout: ReturnType<typeof setTimeout>;
|
||||
const tick = () => {
|
||||
api
|
||||
.syncStatus()
|
||||
.garminSyncStatus()
|
||||
.then((s) => {
|
||||
setStatus(s);
|
||||
if (!s.in_progress) {
|
||||
|
||||
Reference in New Issue
Block a user