From 2477b0a8a78214a4e80b3172b5191b971b69f029 Mon Sep 17 00:00:00 2001 From: Lucas Winther Date: Fri, 16 Oct 2026 05:36:09 +0200 Subject: [PATCH] docs: record every-N-days periods, their switch and built-in clocks Co-Authored-By: Claude Opus 5.5 --- docs/DATA-MODEL.md | 23 ++++++++++++++++------- docs/PRD.md | 18 ++++++++++-------- 2 files changed, 26 insertions(+), 15 deletions(-) diff --git a/docs/DATA-MODEL.md b/docs/DATA-MODEL.md index 90a3560..6160317 100644 --- a/docs/DATA-MODEL.md +++ b/docs/DATA-MODEL.md @@ -257,7 +257,7 @@ Namespaced, versioned, and small. Nothing here ever goes to the server. // timelineDayWidth, timelineGroup, showUpcoming, // timelineSplitUpcoming, detectDaily, showChores, // choresOn?, choresOff?, - // showWeeklyTasks, showMonthlyTasks, showCompleted, showIgnored, theme, regionConfirmed, + // showWeeklyTasks, showMonthlyTasks, showCycleTasks, showCompleted, showIgnored, theme, regionConfirmed, // onboarded, showRoutines?, routineGames?, routinesOff?, // routinesAsked?, routinesHidden?, standardPulls? } // Chores and built-in weekly tasks are each one global @@ -277,10 +277,11 @@ Namespaced, versioned, and small. Nothing here ever goes to the server. // false, premium only. // Every list absent means none — built-ins are opt-in for // every install. PRD F17. - // showWeeklyTasks / showMonthlyTasks say whether tasks of - // that period sit in the strip's row under the dailies. - // Both default true, so an install from before them keeps - // its tasks on screen; off hides and never deletes. + // showWeeklyTasks / showMonthlyTasks / showCycleTasks say + // whether tasks of that period sit in the strip's row under + // the dailies. All default true, so an install from before + // them keeps its tasks on screen (an absent showCycleTasks + // reads as true); off hides and never deletes. // changelogSeen is the newest changelog entry id the // reader dismissed. Absent means unrecorded: first-run // setup sets it, so absent is an install from before the @@ -405,6 +406,11 @@ recomputes from `daily` on every read, so a backfill, a removed tick or a week r bookkeeping and clears nothing. Weeks are cut in day-key space by `periodOf` (`src/shared/period.ts`): the seven keys from the chosen weekday, so a week rolls exactly where the game's day does, per region and per reset override. A day key later than today never counts. +A task's other periods are cut the same way: a month from its chosen day, and a **cycle** of N days +as `from + k·N` for the whole number `k` that puts today inside it — before `from` as well as after, +so `from` may be any day a cycle began. A built-in may name a server `clock` (code only, never +stored): its day keys are then cut on that server's reset for every reader, for a cycle that ends at +one instant everywhere (NTE's Beyond the Rails, on Asia's). **Not every game has a server per region.** `GameMeta.resetOffsets` records the regions where a game's server clock differs from `REGION_RESET_UTC_OFFSET`. Endfield is the case this exists for: it @@ -567,7 +573,8 @@ true is the day two key spaces merge silently. // startsAt, startPrecision, // endsAt, endPrecision, at, updatedAt } } "gacha-tracker:v1:tasks" // { [mytask id]: { id, game, title, - // period: { unit: "week", startsOn: 1–7 } | { unit: "month", startsOn: 1–31 }, + // period: { unit: "week", startsOn: 1–7 } | { unit: "month", startsOn: 1–31 } + // | { unit: "cycle", days: 2–366, from: "YYYY-MM-DD" }, // measure: { kind: "days", required } | { kind: "amount", target, unit? }, // from?, at, updatedAt } } "gacha-tracker:v1:amounts" // { [itemKey]: { [periodStartKey]: { value, at } } } @@ -581,7 +588,9 @@ one a newer version wrote, and opening an older tab must not erase it. `amounts` `daily` under its id; its numbers live in `amounts` under its id and the start key of the period (`periodOf`, `src/shared/period.ts`), so a new week starts with no value and old weeks are never pruned. An event's points goal stores its numbers the same way, under the event id. Deleting a task -removes the task record only. +removes the task record only. **A cycle task is the newest shape** (2026-10-16): a build from before +it fails `TaskSchema` on one, skips it on display and keeps it on disk, so it reappears when the +bundle updates; its numbers sit under the cycle's start key like any period's. **Built-in tasks** (`src/shared/routines.ts`) are not stored: they ship in the bundle, each with a `source` URL and the `asOf` date that page gives, and their ticks and numbers are stored under their diff --git a/docs/PRD.md b/docs/PRD.md index 71d5882..ddde742 100644 --- a/docs/PRD.md +++ b/docs/PRD.md @@ -574,19 +574,21 @@ with the standing chore of the game it came from, because the reader thinks in g **F17 — Weekly and monthly tasks.** Some chores roll weekly or monthly rather than daily — earning ZZZ's weekly activity points, finishing Endfield's weekly routine — and no source publishes them, so they were nowhere in the app. -A reader can now set them up per game in *Your own*: a title, every week (from a weekday they pick) -or every month (from a day of the month), and either **tick it off** (N days in the period, one by +A reader can now set them up per game in *Your own*: a title, every week (from a weekday they pick), +every month (from a day of the month) or **every N days** (from a day a cycle began — a two-week +endgame mode, say), and either **tick it off** (N days in the period, one by default) or **reach a number** (a target such as 2,100, with an optional unit). The form opens with examples to start from, held to the same bar as the event form's (F13, *Examples to start from*). - **They roll on the game's clock.** A week starts at the game's daily reset on the chosen day, on the reader's server — the same clock every daily tick is cut on, so nothing new to get wrong. -- **They sit under the dailies, and are counted apart.** Tasks have a row of their own, *This week & - month*, under today's chips — in game order — and the header counts them under *Weekly* or - *Monthly*, not "today": a chore due by Sunday is not waiting on anyone every morning, and only - today's dailies celebrate. **Each period can be switched off** (`showWeeklyTasks`, - `showMonthlyTasks`), in *What you see* and in the strip's Edit panel, offered only once a task of - that period exists. Off hides tasks only — an event with a goal stays — and discards nothing. +- **They sit under the dailies, and are counted apart.** Tasks have a row of their own under today's + chips — in game order — headed by the periods it holds (*This week & month*, *This week, month & + cycle*), and the header counts them under *Weekly*, *Monthly* or *Cycles*, not "today": a chore + due by Sunday is not waiting on anyone every morning, and only today's dailies celebrate. A + cycle's chip shows the days left in it. **Each period can be switched off** (`showWeeklyTasks`, + `showMonthlyTasks`, `showCycleTasks`), in *What you see* and in the strip's Edit panel, offered + only once a task of that period exists. Off hides tasks only — an event with a goal stays — and discards nothing. - **A number is entered, not ticked.** Its chip opens an editor under the strip — the value as the game shows it, not an increment — because a chip is one target. Catch up offers last period's number the way it offers yesterday's tick.