Last updated: 2026-07-01
WordBank is a personal mobile app for learning and reviewing English vocabulary, workplace expressions, and technical (SRE / FinOps / DevOps) jargon. Each entry pairs a term with a short gloss, a full plain-English explanation, a Chinese translation, and example sentences. The app lets the owner browse, search, and review entries with spaced repetition.
The content is authored separately (by Claude, via the wordbank skill) and lands in a JSONL file in
this repo. The app reads that file. This PRD covers the app, not the authoring tool.
A single user: a non-native English speaker, native Chinese, who wants to (1) sound fluent in daily standups with European colleagues and (2) ramp up on SRE jargon. Not a multi-user product β no accounts, no sync server, no sharing in v1.
Goals (v1)
- Read the vocabulary source and present entries clearly, with Markdown-rendered explanations.
- Review mode with spaced repetition, so terms come back at increasing intervals.
- Filter into decks by tag (e.g.
standup,sre,finops). - Toggle between the English explanation and its Chinese translation.
- Work fully offline.
Non-goals (v1)
- No editing of entries inside the app (the JSONL is authored externally; the app is read-only over the content). A later version may add quick edits.
- No cloud sync, login, or multi-device.
- No audio / text-to-speech (candidate for v2).
- Source of truth:
data/wordbank.jsonlβ one JSON object per line (JSONL). Human-readable, diffable in git, append-only. This file is the contract between the authoring skill and the app. - At app load, parse the JSONL and build a local SQLite database for fast queries, filtering, and review scheduling. SQLite is a derived cache, not the source β it can be rebuilt from the JSONL any time. Rebuild when the JSONL's modified-time or a content hash changes.
- Review state (last reviewed, next-due date, ease/interval) lives only in SQLite / app storage β never written back into the JSONL, so the source stays clean and mergeable.
| Field | Type | Notes |
|---|---|---|
term |
string | The word or expression. Unique key. |
pos |
string | Part of speech / kind (noun, idiom, acronym, jargon, β¦). |
definition |
string | Short one- or two-sentence gloss. The flashcard front / quick recall. |
zh |
string | Short Chinese gloss for at-a-glance recognition. |
explanation |
string (Markdown) | Full English teaching text. GitHub-flavored Markdown, \n line breaks. |
explanation_zh |
string (Markdown) | Chinese translation of explanation, same structure. |
context |
string | The real sentence where the term came up (optional). |
examples |
string[] | 1β2 model sentences, at least one standup-usable. |
synonyms |
string[] | Simpler near-synonyms. |
register |
string | Formality note (formal, neutral, informal). |
tags |
string[] | Multi-valued. At least one broad area (standup, sre, finops, devops, general) plus finer topics (cost, slo, idiom, β¦). Decks are built from tags, so a term can appear in several decks. |
added |
string | ISO date (YYYY-MM-DD) the entry was created. |
term, definition, zh are always present. Treat every other field as optional and render
conditionally.
CREATE TABLE entry (
term TEXT PRIMARY KEY,
pos TEXT,
definition TEXT NOT NULL,
zh TEXT,
explanation TEXT,
explanation_zh TEXT,
context TEXT,
examples TEXT, -- JSON array as text
synonyms TEXT, -- JSON array as text
register TEXT,
added TEXT
);
CREATE TABLE tag ( term TEXT, tag TEXT ); -- one row per (term, tag)
CREATE TABLE review ( term TEXT PRIMARY KEY, -- spaced-repetition state
last_reviewed TEXT,
next_due TEXT,
interval_days INTEGER,
ease REAL,
reps INTEGER );Decks = SELECT DISTINCT tag FROM tag. A deck's cards = entries joined on tag.
- Home / decks β list of tags with a count and how many are due today. Tap a tag to enter it.
- List β entries in the current deck (or all). Each row: term + short
definition(+zh). Search box filters by term / definition / tag. - Detail β term,
pos,definition,zh, then the Markdownexplanation. A toggle switchesexplanationβexplanation_zh. Showexamples,synonyms,register,context,tags. - Review (flashcards) β show the term (front); reveal
definition+zh+explanation(back); the user rates recall (e.g. Again / Hard / Good / Easy); update spaced-repetition state. Pull the day's queue fromreview.next_due <= today, plus new (never-reviewed) cards.
Use a simple, proven scheme (SM-2 style) in v1: each rating adjusts interval_days and ease, and
sets next_due. Keep the algorithm in one module so it is easy to swap later. New cards start with a
short interval (e.g. 1 day) and grow on success.
- React Native + Expo β fastest path to a working app on the owner's phone.
- expo-sqlite for the local database.
- react-native-markdown-display (or similar) to render
explanation/explanation_zh. - TypeScript, with a typed
Entrymatching the schema above.
- Project scaffold (Expo + TypeScript), load
data/wordbank.jsonl, log parsed entries. - JSONL β SQLite import with rebuild-on-change; typed
Entry. - List + Detail screens (Markdown rendering, EN/ZH toggle).
- Deck filtering by tag.
- Review mode + SM-2 scheduling, persisting review state.
- Polish: search, due-today counts, empty states.
- Pronunciation / audio (TTS or recorded) β v2?
- In-app quick edit or "flag for review" that writes a side file the skill can pick up?
- Import more than one source file, or keep a single
wordbank.jsonl?