콘텐츠로 이동

WorkoutWrite — @gj-kit/expo-workouts

@gj-kit/expo-workouts/core에서 공개하는 interface입니다. package version 0.1.1의 release declaration을 그대로 표시합니다.

import { WorkoutWrite } from '@gj-kit/expo-workouts/core';
/**
* Full-state input for `saveWorkout`. There is NO partial-update path: on Android an upsert that
* omits the route DELETES the stored route, so the only safe contract is "send everything".
*/
interface WorkoutWrite {
/**
* A stable id this app owns — the idempotency key. Becomes HKMetadataKeySyncIdentifier /
* Health Connect `clientRecordId`.
* ⚠ Other apps CAN read this value on Android. Use an opaque UUID.
* Must match `/^[A-Za-z0-9._:-]{1,120}$/`.
*/
readonly id: string;
/**
* A safe integer >= 1, non-decreasing per `id`, that increases whenever the content changes.
* Derive it from your own record's `updatedAt` (epoch ms) or from an edit counter.
* ⚠ NEVER `Date.now()` at call time: a crash retry would write a fresh version and, on iOS, mint a
* second workout object and orphan the first one's samples and route.
* An EQUAL version replaces the stored workout; a LOWER one throws `staleVersion` and writes nothing.
*/
readonly version: number;
/**
* Nine members since owner decision ③. `'other'` is the documented lossy sink — it stores
* OTHER_WORKOUT(0) / `.other`(3000) and the original activity is not recoverable.
*/
readonly kind: WorkoutKind;
/**
* Drives the platform activity constant on write.
* ⚠ On Android it is only representable for `running`, `cycling`, `swimming` and `rowing`; for
* every other kind it is silently dropped and reads back `undefined`. On iOS it is written to
* `HKMetadataKeyIndoorWorkout` for every kind — but only when you actually set it: leaving it
* `undefined` OMITS the key rather than writing `@NO`.
*/
readonly indoor?: boolean | undefined;
readonly startMs: number;
/** Must be > `startMs` and <= now. */
readonly endMs: number;
readonly utcOffsetMin?: number | undefined;
/** IANA zone id (e.g. `'Asia/Seoul'`). iOS metadata only; Android stores only the offset. */
readonly timeZoneId?: string | undefined;
readonly pauses?: readonly Pause[] | undefined;
readonly laps?: readonly Lap[] | undefined;
readonly distanceM?: number | undefined;
readonly activeEnergyKcal?: number | undefined;
readonly elevationGainM?: number | undefined;
/** Omitted from the write when <= 0 — Health Connect throws on `StepsRecord(count = 0)`. */
readonly steps?: number | undefined;
/** Samples outside 1..300 bpm or outside `[startMs, endMs)` are dropped before writing. */
readonly heartRate?: readonly HeartRateSample[] | undefined;
/**
* REQUIRED, and `'none'` is not the same call shape as an empty array.
*
* ⚠ This is the one place where forgetting a field DESTROYS user data: an Android upsert that
* omits the route while holding the route write scope DELETES the stored route. Making the field
* required turns that silent, irreversible mistake into a compile error, and `'none'` forces the
* intent to be stated out loud.
* An empty array is `invalidArgument` — say `'none'`.
*/
readonly route: readonly RoutePoint[] | 'none';
}

이 선언은 매개변수, optionality, 제네릭, 반환값, 공개 union/type 계약의 정본입니다. 호출 전 필요한 환경·권한·오류 경계는 패키지 Golden path와 이 subpath의 import 조건을 함께 확인하세요.

  • 패키지: @gj-kit/expo-workouts
  • 버전: 0.1.1
  • 공개 entry: ./core
  • 소스: GitHub

Full-state input for saveWorkout. There is NO partial-update path: on Android an upsert that omits the route DELETES the stored route, so the only safe contract is “send everything”.