Skip to content

About

Resources

Stars

0 stars

Watchers

1 watching

Forks

Repository files navigation

Ling Script

Minimal, mobile‑first language practice. Built for speed, clarity, and a delightful UX.


Live Next.js React TypeScript Prisma SQLite Bun Node.js Docker ESLint


App Router • API routes • Prisma ORM • SQLite • Standalone build • One‑container deploy

Highlights

  • Bold, mobile‑first UI with accessible focus states and toasts
  • Next.js App Router with server components and app/api/* endpoints
  • Prisma + SQLite for a zero‑ops, file‑based database that “just works”
  • One‑command local setup; instant seed/reset scripts for fast iteration
  • Production‑ready Dockerfile using Next standalone output

Built With

  • Next.js 15, React 19, TypeScript 5
  • Prisma 6 (SQLite), Node.js 20
  • Bun (dev ergonomics, bunx for Prisma)
  • Vanilla CSS (no framework) tuned for touch + desktop

Quick Start

Prereqs: Node 20+ (or Bun), Docker optional.

  1. Install deps
# Recommended
bun install

# or npm
npm install
  1. Configure the database URL (SQLite file path). Create .env in the repo root:
DATABASE_URL="file:../data/ling.db"
  1. Create the database and generate the Prisma client
# Push schema (skips generate in script); dev regenerates client automatically
bun run db:push
  1. Start the dev server
bun run dev
# http://localhost:3000
  1. Seed sample data (languages, units, prompts)
bun run db:seed

# Or recreate from scratch (delete DB file, push, seed)
bun run db:reset

Health check: GET /api/health

Metrics

  • Endpoint: GET /metrics (no auth). Returns Prometheus text format with default Node/process metrics and custom HTTP metrics.
  • Enable/disable: set METRICS_ENABLED=true|false (default true). When disabled, GET /metrics returns 404 and request instrumentation is a no-op.
  • Labels: service is set from APP_NAME or package.json name. HTTP metrics are labeled by method, route, status, and service.
  • Counters/Histograms:
    • http_requests_total{method,route,status,service}
    • http_request_duration_seconds{method,route,status,service} with sensible buckets
  • Note: Place a reverse proxy rule to block public access to /metrics. It is intended for internal scraping by Prometheus.

API Cheatsheet

  • GET /api/langs — list languages
  • GET /api/units/:langId — units for a language
  • GET /api/prompts/:unitId — prompts for a unit
  • POST /api/create/lang — { name }
  • POST /api/create/unit — { langId, name }
  • POST /api/create/prompt — { unitId, content, answer }

Docker (One‑Container Deploy)

Build the image:

docker build -t ling-script-next .

Run with a bind mount to persist the SQLite file on the host:

# Linux/Mac
docker run --name ling-next -p 3000:3000 \
  -v "$(pwd)/data:/app/data" \
  -e DATABASE_URL="file:/app/data/ling.db" \
  ling-script-next
# Windows PowerShell
docker run --name ling-next -p 3000:3000 `
  -v ${PWD}\data:/app/data `
  -e DATABASE_URL="file:/app/data/ling.db" `
  ling-script-next

Notes:

  • SQLite lives at /app/data/ling.db inside the container; no external DB needed
  • You can change the filename/location by adjusting DATABASE_URL
  • If you mount a host folder to /app/data, ensure it is writable by the container user. On Linux: sudo chown -R 1000:1000 ./data

Project Structure

app/                    # App Router (pages + API routes)
  api/                  # REST-ish endpoints
  lang/[id]/            # Language units listing
  unit/[id]/            # Practice screen (client)
components/             # UI primitives (TopNav, Toasts, etc.)
lib/prisma.ts           # Prisma client (single instance)
prisma/schema.prisma    # Data model (Lang, Unit, Prompt)
prisma/seed.js          # Seed script (idempotent)
scripts/reset-db.js     # Quick nuke & seed for dev
Dockerfile              # Multi-stage, standalone Next build

NPM Scripts

  • dev — bunx prisma generate && next dev
  • build — prisma generate && next build
  • start — next start
  • db:push — prisma db push --skip-generate
  • db:seed — bun prisma/seed.js
  • db:reset — remove DB, push schema, seed

Roadmap

  • Richer progress tracking and spaced repetition
  • Export/import user progress
  • More languages and curated units

Made with care. If this helped you evaluate my skills, I’m happy to walk through the code, decisions, and tradeoffs in an interview.

About

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages