Skip to content

Repository files navigation

CiJing · 词鲸背单词

CiJing app icon

Turn words found in real reading into a personal vocabulary library, graded AI stories, and a spaced-review routine.

简体中文 · Contributing · Supabase · Trusted server · App Store checklist

iOS 17+ SwiftUI Supabase license MIT

Product tour

CiJing has four focused top-level areas. Home brings the daily plan, accumulated progress, persistent reading history, and real learning entry points together in one glance.

CiJing home with a completed plan, learning totals, saved readings, and study entry points

Four top-level areas

Home
Daily plan, persistent reading history, and practice entry points
Library
Learning states, strength, due dates, and contextual vocabulary
CiJing home screen CiJing word library
Lookup
Definitions, pronunciation, examples, and one-tap saving
Settings
Learning preferences, privacy controls, cache, and account
CiJing word lookup CiJing settings

The complete learning loop

The top-level navigation stays simple, while each reading opens a focused sequence: choose target words, read with optional translations, practise retrieval, shadow sentence by sentence, review progress, and resume saved readings after relaunch.

1 · Choose
Theme, style, level, and target words
2 · Read
Graded bilingual story with highlighted words
3 · Practise
Meaning, context, spelling, and recall
Choose reading settings and target words Read a bilingual AI story Complete reading-based practice
4 · Shadow
Listen, speak, and compare sentence by sentence
5 · Improve
Activity, vocabulary states, and weak words
6 · Resume
Continue any saved reading after relaunch
Sentence shadowing practice Learning progress dashboard Resume a saved reading after relaunch

What it does

  • Captures words and source context from a Chrome Manifest V3 extension.
  • Keeps a private, user-scoped word library with notes and learning states.
  • Generates coherent bilingual readings from weak, due, and new words.
  • Persists every generated reading to reading_sessions, so history survives relaunches and sign-ins.
  • Schedules review with strength, ease factor, interval, lapse, and due-date signals.
  • Provides system pronunciation, shadowing, and short reading-based exercises.
  • Protects all user data with Supabase Row Level Security.
  • Follows the system appearance before sign-in and for unset accounts; signed-in appearance and local learning switches are isolated by user UUID, and the App Icon includes light/dark system variants.
  • Requires email verification for new accounts and rejects an unexpected session returned directly from sign-up.

Repository layout

.
├── client/      # SwiftUI iOS app
├── extension/   # Chrome extension for contextual lookup and saving
├── supabase/    # PostgreSQL migrations, RLS, RPCs, and Edge Functions
├── server/      # Trusted Flask boundary and health checks
├── scripts/     # Configuration, audit, and smoke-test utilities
├── docs/        # Policies, operations guides, model notes, and store assets
└── website/     # Privacy policy and support pages for public hosting

Architecture and security

iOS app ─────┐
             ├─ Supabase Auth / PostgREST ── PostgreSQL + RLS + RPC
Chrome ──────┘                    └────────── Edge Functions ── OpenRouter / Qwen

Physical iPhone ── local Flask integration gateway ── hosted Supabase
Flask server ── trusted health and operations boundary

The iOS app and extension share a Supabase account and user-scoped learning data. Every business table has Row Level Security, and database functions execute in the authenticated user's scope. During physical-device testing, iOS Auth, PostgREST, and Edge Functions requests pass through the local Flask gateway before reaching hosted Supabase; the Chrome extension continues to call hosted Supabase directly. The gateway preserves the user's access token and RLS boundary and never injects a server secret into client requests.

The root .env is the only local configuration source. Generated iOS and extension configuration is ignored by Git. Client bundles contain only the Supabase URL and publishable key; Supabase secret keys and the OpenRouter API key stay in trusted runtimes. See Supabase architecture and operations and the trusted server guide for component details.

Quick start

Requirements: macOS, Xcode 16 or newer, Node.js 20+, Docker Desktop, and Chrome. The repository wrapper downloads and caches its pinned Supabase CLI version on first use.

cp .env.example .env
# Fill the environment values in .env
make config

./scripts/supabase.sh start
./scripts/supabase.sh db reset
make functions

Open client/CiJing.xcodeproj, select the CiJing scheme and an iOS 17+ simulator, then run. Load extension/ as an unpacked extension from chrome://extensions.

Configuration, database, Edge Function, and production instructions live in supabase/README.md. Contribution workflow and physical-device troubleshooting live in CONTRIBUTING.md.

Physical-device and release quick reference

Once the iPhone has a device-integration build generated with make device-config and rebuilt in Xcode, routine local testing only requires this command from the repository root:

make server-start

Keep that terminal running and keep the iPhone and Mac on the same LAN. The device uses the Mac's Bonjour .local hostname, so a Wi-Fi IP change does not require regenerating configuration. For the first device setup, after switching back from release configuration, or after generated files were cleaned, run make device-config first and rebuild/reinstall the app in Xcode; starting Flask alone cannot change the URL embedded in an installed app.

Before creating an Archive, TestFlight build, or App Store build, verify that SUPABASE_URL in the root .env is the hosted production HTTPS URL, then run:

make config
make config-check

make device-config never changes the root .env, so make config restores the iOS client to the hosted URL from .env; make config-check verifies that generated files match it. Rebuild the Archive after both commands succeed—do not reuse a local device build that points to Flask. The release app does not require the local Flask server.

Verification

make config-check
make extension-test
make server-test
make ios-build

With Supabase running, make smoke verifies the cross-client API flow. Production environments can use make production-audit and make production-smoke after deployment.

Documentation

Contributing and security

Please read CONTRIBUTING.md and CODE_OF_CONDUCT.md before opening a contribution. Report vulnerabilities privately by following SECURITY.md, not through a public issue.

This project is available under the MIT License.

About

Turn words found in real reading into a personal vocabulary library, graded AI stories, and a spaced-review routine.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages