docs(workouts): document write-time picker source-priority divergence

The v1.4.42 senior-dev QA flagged that `dedupeWorkoutBatch` reads the
source ladder from the canonical `DEFAULT_WORKOUT_SOURCE_PRIORITY`
constant unconditionally, while the read-time picker resolves the
per-user `sourcePriorityJson` from the User row. A customised user
who promoted MANUAL above APPLE_HEALTH in Settings -> Sources can
still have their preferred Manual row dropped at write-time before
the read-time picker ever sees it.

Scope-narrow today (most paired users keep the Apple-first default)
but the moment a user customises, the divergence silently overrides
them. The architecturally correct fix (v1.4.43 candidate) is to
accept the small ingest-path cost of one indexed
`User.sourcePriorityJson` lookup and thread the user's ladder into
the picker. Until that lands, this docstring is the load-bearing
operator notice.
This commit is contained in:
Marc-André Bombeck committed 2026-05-21 19:28:34 +02:00
1 parent 7c9fb09098
commit fbdcf67eb8
1 file changed
+27 -6
+27 -6
View File
@@ -66,12 +66,33 @@
* ───────────────
*
* Zero Prisma imports, zero IO, zero user lookups. The helper takes
* an array, returns an array. Testable in isolation; safely
* invoked from a hot ingest path with no DB round-trip cost. The
* write-time path has the user's id on every row already and the
* source ladder is the canonical constant, so the helper doesn't
* need to consult `User.sourcePriorityJson` (that's a read-time
* concern: the user's display preference for the dashboard tile).
* an array, returns an array. Testable in isolation; safely invoked
* from a hot ingest path with no DB round-trip cost.
*
* Source-priority divergence vs the read-time picker
* ──────────────────────────────────────────────────
*
* The read-time picker resolves the per-user `sourcePriorityJson`
* (from `User.sourcePriorityJson`) for every read so a user who
* promoted MANUAL above APPLE_HEALTH in Settings → Sources sees
* their Manual rows surface above the Apple Watch ones. The
* write-time helper deliberately does NOT consult that preference:
* it uses the canonical `DEFAULT_WORKOUT_SOURCE_PRIORITY` constant
* unconditionally, so a customized user's preferred row can still
* be dropped at write-time before the read-time picker ever sees
* it. Scope-narrow today — `DEFAULT_SOURCE_PRIORITY.steps` is the
* Apple-first default and most paired users never override it —
* but the moment a user customises, this helper silently
* overrides them.
*
* The architecturally correct fix (v1.4.43 candidate) is option
* (b) from the v1.4.42 senior-dev QA M1: accept the small ingest-
* path cost of one indexed `User.sourcePriorityJson` lookup and
* thread the user's ladder into the picker. The batch route
* already has the userId per row; the lookup is one
* `prisma.user.findUnique({ where: { id }, select:
* { sourcePriorityJson: true }})`. Until that lands, this
* docstring is the load-bearing operator notice.
*/
import { DEFAULT_WORKOUT_SOURCE_PRIORITY } from "@/lib/sources/pick-canonical-workout";