Add deployment reading windows and progress-aware quiz unlock
This commit is contained in:
1 parent
edbc9c6056
commit
d8eba9169f
15 files changed
+471
-5
No files matched your search
@@ -0,0 +1,76 @@
|
||||
# Deployment-controlled reading hours and quiz
|
||||
|
||||
The reader enforces reading hours on both `GET /api/chapter` and chapter page-image
|
||||
requests under `/lib/` (HTTP 423 outside hours). The dashboard, manga metadata,
|
||||
covers, progress, reading-time summaries, scraper and administrator pages remain
|
||||
available. A reader tab already open when a window ends checks access every 15
|
||||
seconds and returns to the gate. Chapter images use `Cache-Control: no-store` when
|
||||
the limiter is configured. Already downloaded images in a browser or files available
|
||||
directly on disk cannot be recalled; this is a self-imposed server access rule, not
|
||||
DRM. There is no schedule-changing API or UI.
|
||||
|
||||
## Docker configuration
|
||||
|
||||
Set these deployment variables on the reader service, then recreate **only the
|
||||
reader**. Leaving `READING_WINDOWS_JSON` empty disables the limiter. Day keys
|
||||
are `0` Sunday through `6` Saturday. Each day has any number of `[start,end]`
|
||||
intervals; an end earlier than its start carries into the next day. `24:00` is
|
||||
valid only as an end. Intervals are start-inclusive and end-exclusive, resolved
|
||||
using the IANA timezone, including daylight-saving changes.
|
||||
|
||||
```dotenv
|
||||
READING_WINDOWS_JSON='{"0":[["08:00","01:00"]],"1":[["07:00","12:00"],["13:00","24:00"]],"2":[["07:00","24:00"]],"3":[["07:00","24:00"]],"4":[["07:00","24:00"]],"5":[["07:00","24:00"]],"6":[["08:00","01:00"]]}'
|
||||
READING_TIMEZONE=Europe/Berlin
|
||||
READING_QUIZ_UNLOCK_MINUTES=60
|
||||
READING_QUIZ_CATALOG_PATH=/data/reading-quiz.json
|
||||
```
|
||||
|
||||
The Monday split above illustrates multiple on/off periods; replace it with
|
||||
`[["07:00","24:00"]]` for an uninterrupted weekday. The Saturday and Sunday
|
||||
windows extend to 01:00 on the following mornings. A malformed timezone,
|
||||
schedule, unlock length or catalog stops the reader at startup rather than
|
||||
silently removing the restriction. `READING_QUIZ_UNLOCK_MINUTES` accepts 1–1440.
|
||||
The scraper is independent and must not be restarted for this configuration.
|
||||
|
||||
## Question bank and progress watermark
|
||||
|
||||
The bank is a deployment-managed JSON file, separate from `manga.json` and from
|
||||
the scraper. See [`config/reading-quiz.example.json`](../config/reading-quiz.example.json).
|
||||
Its `manga` keys are **exact library folder IDs**. Each question has a stable ID,
|
||||
prompt, accepted answer variants, an evidence citation, and at least one
|
||||
`requires` chapter ID. The chapter IDs are the reader's IDs (for example `1/12`,
|
||||
not the on-disk `v01/c0012`). Every required chapter must be marked completed
|
||||
for that user before the question enters their pool. This supports a single
|
||||
watermark or a set of specific sections. Five eligible questions are needed to
|
||||
offer a quiz; an empty bank simply leaves outside-hours reading locked. A
|
||||
question's answers and evidence never go to the browser.
|
||||
|
||||
The challenge randomly samples five progress-eligible questions across *all*
|
||||
library manga, not only the one being opened. It asks them sequentially, accepts
|
||||
unlimited retries, and has no answer timer. Accepted variants are normalized
|
||||
for case, punctuation and accents; one typo is tolerated for answers of five
|
||||
or more characters, two for answers of eleven or more. Starting a new visit
|
||||
invalidates the previous challenge, and leaving the page abandons it. Passing
|
||||
all five grants that user reading access across manga for the configured number
|
||||
of minutes, persisted in `db.json` across reader restarts. Questions are not
|
||||
shown before their watermark; this depends on the reader's existing
|
||||
self-reported completion records.
|
||||
|
||||
Validate a proposed file with
|
||||
`node tools/validate-reading-quiz.js <catalog.json>` before pointing the reader
|
||||
at it. For an eventual research agent: write **drafts** with source citations,
|
||||
aliases and proposed chapter watermarks, then have a human verify identity,
|
||||
answer and spoiler boundary. Only a reviewed catalog should be copied to the
|
||||
configured path and loaded by restarting the reader. No wiki or transcript
|
||||
fetching is performed by the reader itself.
|
||||
|
||||
## Testing and rollback
|
||||
|
||||
`node tools/test-compose.js --reading-limit-ui` creates a disposable Compose
|
||||
fixture with two progress-qualified sample manga, tests chapter and image
|
||||
denial, quiz flow and the one-hour unlock, then tears it down. Add `--keep`
|
||||
to leave an isolated playable instance locked for manual review; its printed
|
||||
URL and fixture path identify it. Main data and the running main scraper are
|
||||
not mounted. To roll back a future main deployment, restore the previous
|
||||
reader image and configuration, recreate only the reader, and preserve current
|
||||
`db.json` and library. The additional `readingAccess` field is backward-safe.
|
||||
Reference in new issue
Block a user