Reading the repo
Opening the box…
Reading the repo
Opening the box…
Assembly instructions
QuizTime- Flashcard Quiz Maker
Saved setup from 12 h ago
Will it work on macOS?
Heads-upIt also needs PostgreSQL and 10 settings in .env (6 secret).
Then run bash setup.sh. It stops at the first error and is safe to run again. Servers and tests aren't started; it lists them at the end. Read it first.
Needs Git: xcode-select --install
git clone https://github.com/bisacoo1/quiz-time.git cd quiz-time
Node.js LTS (no version pinned)
# needs nvm: brew install nvm (or https://github.com/nvm-sh/nvm) nvm install --lts
Fill in secrets: GEMINI_API_KEY, AUTH_SECRET, AUTH_GOOGLE_SECRET, VAPID_PUBLIC_KEY, VAPID_PRIVATE_KEY, CRON_SECRET
cp .env.example .env.local
Needs: PostgreSQL (no compose file — install locally or run via Docker)
npm ci
npm run dev
Requirements
Setup
npm install
cp .env.example .env.local # then fill in the values below
npm run db:migrate # create the tables (idempotent)
npm run dev
| Variable | Required | Notes |
| --- | --- | --- |
| DATABASE_URL | yes | Postgres connection string. Required at build time – src/db/index.ts throws if it's missing. |
| GEMINI_API_KEY | for generating cards¹ | Key for the primary provider (Google Gemini). |
| OPENROUTER_API_KEY | for generating cards¹ | Optional but recommended: used when every Gemini model is at its limit. See AI model failover. |
| GEMINI_MODEL | no | Overrides the main model. Default: gemini-3.6-flash. |
| GEMINI_FALLBACK_MODELS | no | Overrides the Gemini fallback order (comma-separated). Default: gemini-3.1-flash-lite, antigravity, gemini-3.5-flash-lite. antigravity is a Gemini agent with higher token use – drop it to save tokens. |
| OPENROUTER_MODELS | no | Overrides the OpenRouter fallback list (comma-separated). Default: openrouter/free, nvidia/nemotron-3-super-120b-a12b:free, inclusionai/ling-3.0-flash-vl:free. The free lineup rotates monthly – see openrouter.ai/models (filter "Free"). |
| GEMINI_RATE_LIMIT_COOLDOWN_SECONDS | no | How long a rate-limited model is skipped (default 300). Google's own retryDelay hint wins when sent; the value is clamped to 15 s–30 min and doubles on repeated hits. |
| AUTH_SECRET | for sign-in | Auth.js secret. Generate with openssl rand -base64 32. |
| AUTH_GOOGLE_ID | for sign-in | Google OAuth client ID. |
| AUTH_GOOGLE_SECRET | for sign-in | Google OAuth client secret. |
| BLOB_READ_WRITE_TOKEN | for Side by Side | Read/write token for a private Vercel Blob store. Keep it server-only. |
| OWNER_EMAIL | no | The account that becomes the owner and sees the who's online roster. Case-insensitive; comma-separated addresses allowed. Empty or unset = feature off. |
| MAINTENANCE_MODE | no | 1/true/yes/on enables maintenance mode. |
| VAPID_PUBLIC_KEY | for push | Web push public key. Generate with npx web-push generate-vapid-keys. |
| VAPID_PRIVATE_KEY | for push | Web push private key (same command). |
| VAPID_SUBJECT | for push | Contact for push services, e.g. mailto:you@example.com. |
| CRON_SECRET | for push | Bearer token for /api/cron/reminders. Generate with openssl rand -hex 32. |
¹ Cards can be generated with either AI key. With both, the app has a
longer safety net. Without the VAPID_* variables, the notification inbox
still works and the panel explains that push isn't configured.
⚠️ Never commit
.env. It is listed in.gitignore; if it was ever pushed, rotate the keys.
No reports for macOS yet.
GitManual AI Agent reads the 4 key files and writes a step-by-step guide for macOS. Once written, it's saved for everyone.