Files
gacha-event-tracker/docs/PRODUCT.md
T
Lucas WintherandClaude Opus 5.5 8a6110396a
CI / Typecheck, test, feed (push) Successful in 17s
CI / Build site (push) Successful in 8s
CI / Container image (push) Successful in 17s
docs: move PRODUCT and DESIGN into docs/ and list them in AGENTS
They are reasoning for whoever touches the interface next, which is
what docs/ holds, and the table in AGENTS.md is how an agent finds it.
The design tooling resolves both from docs/ without configuration.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-01 04:09:57 +02:00

184 lines
9.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Product
<!-- impeccable:product-schema 1 -->
## Platform
web
An installable single-page web app (PWA with a service worker and manifest) that works offline. Native
mobile apps are out of scope: installing to a home screen is enough (`docs/PRD.md` § Out of scope).
## Users
**The repository owner comes first.** Event Clock is the owner's own tool for keeping track of the
gacha games they play. When the owner's use and a public reader's request conflict, the owner's use
wins.
**Public readers come second, and they are welcome.** The app has been posted to r/gachagaming and is
served publicly. The typical public reader matches the PRD persona: someone playing 2–5 gacha games
who checks in a few times a week, usually on a phone. Their situation is a dozen overlapping,
time-limited events spread across as many in-game calendars, and the thing they fear is missing a
limited event by a day. A smaller group plays 6–10 games or more. For those readers, custom games and
events (F13) cover what no list of sources ever will.
The desktop layout is a real layout, not the phone layout stretched, but mobile is the main use case.
## Product Purpose
Event Clock answers three questions in one screen, across every game the reader plays:
1. What is running right now?
2. What ends soonest?
3. Which of these have I already finished, or am I partway through?
It collects live and upcoming events from community wikis, sorts them by end date, and plots them on
a timeline. Readers can mark an event done or in progress, estimate how much effort it takes, and tick
off daily progress on events that repeat.
Success is measured as follows (`docs/PRD.md` § Success criteria):
- A reader can find their next expiring event within 5 seconds of load, on mobile.
- At least 99% of published end dates are correct.
- A new game can be added without a schema migration or a client change.
## Positioning
**One screen for every game, ordered by what runs out next.** Each game publishes its own calendar,
and none of them talk to each other. paimon.moe, Game8 and in-game timers each answer the question
for one game. Event Clock answers it across all of them in a single deadline order. Cross-game
coverage is the core of the product, so the number and range of supported games matter directly.
The most common reason the public thread gave for not using the app was a missing game.
Date discipline is how the product is built rather than the headline claim, but it is never traded
away for more coverage (see Product Principles).
## Operating Context
- Readers check in a few times a week, usually on a phone, often between other things. The dailies
strip is meant to be answerable in about ten seconds.
- A reader has a game open, sees its in-game timer, and compares it with ours. Countdowns therefore
resolve on the game's own server reset for the reader's region (Asia, America or Europe), not on
UTC.
- Readers either work down a checklist of deadlines, or look at a game-by-game timeline in the style
of paimon.moe, which the public thread named as the reference.
- Some readers are catching up on games they set aside rather than busy with all of them. The app
serves them through the in-progress status and effort fields, and never nags them about a game they
stopped playing.
- Data is refreshed twice a day from community wikis. Some sources (the nine Game8 pages) cannot be
fetched by the scheduled runner and are refreshed by hand. The data's age is therefore a fact the
reader is shown, not one they have to assume.
## Capabilities and Constraints
**Capabilities.** The full feature set is specified as F1–F16 in `docs/PRD.md`:
- A timeline: one lane per game, or a single queue sorted by soonest end.
- A checklist of everything running, sorted by soonest end.
- Done and in-progress marks, effort estimates and notes.
- Daily checklists, with past days that can still be filled in.
- Ignoring an event, and filters by game or type.
- Focusing on one game at a time.
- Region selection.
- JSON export and import.
- The reader's own games and events, one-off or repeating.
- First-run setup.
- Offline use.
- A notice when a new version of the app is ready.
- Dark or light mode, plus a "follow the system" option.
- The reader's own game order.
The app currently covers twenty games from twenty-two sources.
**Hard constraints** (`AGENTS.md` § Three constraints):
- **No accounts, logins or user records.** All reader state lives in `localStorage`. Moving to
another device works through export and import, never a server-side user.
- **No LLM in the pipeline.** Event data comes only from deterministic parsers.
- **A Bun server owns fetching and parsing.** The client only ever calls this app's own `/api/*`.
- **Some stored keys must never move.** Event IDs, `dailies:<game>`, game-day keys and the
reader-authored `mygame:` / `myevent:` IDs are `localStorage` keys. Changing how any of them is
built silently wipes readers' progress, and there is no server copy to restore from.
- **Scraping conduct is binding:** honour `robots.txt`, refresh each source at most once every six
hours, space requests to the same host, and never get around an access control.
**Not the product** (`docs/PRD.md`):
- A wiki or event guide
- A notification or push service
- A pull tracker, damage calculator or build planner
- Localised beyond English
**Terminology:**
- The user is a **reader**.
- The two views are **Checklist** (stored id `"soon"`) and **Timeline**.
- An event's states are **untouched**, **doing it** and **done**.
- **Ignore** is not the same as done.
- A **lane** is one game's row or source.
- The daily **reset** is the boundary between game-days.
**Undecided:**
- Whether a month grid is needed in addition to the timeline.
- The formal accessibility standard (see below).
- The SQLite layer and the review queue for quarantined events are specified but not built.
## Brand Commitments
- **Name:** Event Clock.
- **Tagline:** "Live and upcoming gacha events, sorted by what expires next."
- **Unofficial and unaffiliated.** The app says so plainly. It credits the source wikis and the game
studios on the same screen as the data, and treats the source page as the authority when the two
disagree (F11).
- **Every event links to its source.** A date the reader typed in is visibly theirs and never
credited to a source (F13).
- **Game hues are identity.** A game keeps its colour across views and themes (F15).
- **Dark is the default theme.** Light mode and a "follow the system" option are available (F15).
- **Voice:** plain, specific and honest about uncertainty. The app says "end date unknown" rather
than implying a date, and states what it is holding back ("N live · N upcoming") instead of leaving
the reader to infer it. Do not use the "AI slop" self-description in promotion (`docs/FEEDBACK.md`
P3).
## Evidence on Hand
- `docs/FEEDBACK.md`: a reading of the r/gachagaming release thread (26 comments from 15 accounts),
with verbatim quotes. Readers called the app useful without being asked, one bookmarked it, and no
one disputed a date. The one design criticism was formed from the promo screenshot alone.
- The promo screenshot is outdated. FEEDBACK.md calls for a reshoot from a wide window, in timeline
view.
- There are no usage metrics, testimonials beyond that thread, press mentions or user counts. Do not
invent any.
- Pinned fixtures (`fixtures/<game>/`) and live snapshots (`snapshots/`) hold real event data for
every supported game.
## Product Principles
1. **Deadline order is the product.** Every sort and grouping falls back to soonest end first.
Truncating a list hides rows but never reorders them, and "next to expire" always means the
earliest end date.
2. **Breadth, never at the expense of a true date.** More games is the main growth lever, but a
wrong end date is worse than a missing event. Unknown ends stay unknown, a stale source is
disclosed, and a page that is out of date but still parses is treated as a failure.
3. **Showing is not telling.** What the reader can look at is their choice. The headline deadlines
and the dailies are instructions, so they never point at work that is already done or ignored.
4. **The reader's answers are theirs.** Their view, game order, region and choice of games are asked
for once and remembered. A game added later arrives switched off, and nothing the reader set is
overridden by a heuristic.
5. **Nothing is held back silently.** If something is hidden, stale or out of date, the reader is told
in words, including whose games the notice covers.
## Accessibility & Inclusion
**No formal standard has been chosen yet.** The following rules are already in force and must be
kept:
- Game hues and the urgency colours clear 4.5:1 contrast against the background in both themes.
- No interaction is drag-only. Reordering has arrow buttons, so it works on touch, by keyboard and
with a screen reader.
- Native `<details>` and `<button>` elements are used, so keyboard and screen-reader access needs no
second implementation.
- Focus outlines are visible on `summary` elements.
- A list row is a single tap target.
- The interface is in English only. Dates and countdowns are formatted with `Intl`.