Documentation
Boba developer docs
A Docusaurus-style guide for the Next.js admin workspace, Neon data model, API routes, and the companion Chatur iOS app.
Boba contains two active product surfaces:
web/: a Next.js admin workspace backed by Neon.chatur/: a SwiftUI iOS app with location logging, camera capture, geospatial views, notepad, finance tracking, and pomodoro workflows.
The /docs page reads these Markdown files from web/docs/documents/ and renders them inside the Next app.
Repository map
| Path | Purpose |
|---|---|
web/app | Next.js App Router pages and route handlers. |
web/docs/documents | Docusaurus-style Markdown files rendered by /docs. |
web/db/schema.sql | Repeat-safe Neon schema and seed data. |
chatur/ | SwiftUI iOS app source. |
Local setup
Install dependencies, configure Neon, and run the web app locally.
Install dependencies from the web workspace:
cd web
npm installInstall the shared API workspace:
cd ../api
npm install
cp worker/.dev.vars.example worker/.dev.varsCopy the example environment file:
cp .env.example .envSet the Worker DATABASE_URL in api/worker/.dev.vars. Set the web NEXT_PUBLIC_API_BASE_URL to the local Worker URL:
NEXT_PUBLIC_API_BASE_URL="http://127.0.0.1:8787"Start the Worker:
cd api
npm run devStart the web dev server in another terminal:
cd web
npm run devRun a direct Neon smoke test:
cd api
npm run test:neonRun a production build check:
npm run buildArchitecture
How the static Next.js app, shared Worker API, and Neon database fit together.
The web workspace uses the Next.js App Router and exports static pages. Runtime data requests go to the shared Cloudflare Worker in api/.
| Area | Location | Notes |
|---|---|---|
| Pages | web/app | Dashboard, interviews, counters, login, and docs routes. |
| API Worker | api/worker | Shared JSON API for web and web-extension clients. |
| API client | web/lib/api-client.js | Builds URLs from NEXT_PUBLIC_API_BASE_URL. |
| Database | web/db/schema.sql | Neon schema and seed data. |
Runtime flow
- Client pages fetch JSON from
${NEXT_PUBLIC_API_BASE_URL}/api/*. - The Worker uses
@neondatabase/serverless. DATABASE_URLis configured as a Worker secret.- Static page privacy should be handled by hosting, such as Cloudflare Access.
Important files
web/app/page.jsweb/app/interviews/page.jsweb/app/counters/page.jsweb/app/docs/page.jsweb/lib/api-client.jsapi/worker/src/index.jsweb/scripts/run-next.mjs
Database
Neon schema, tables, and common SQL operations.
The canonical web database schema is web/db/schema.sql.
Apply the schema:
cd web
set -a
source .env
set +a
psql "$DATABASE_URL" -v ON_ERROR_STOP=1 -f db/schema.sqlTables
| Table | Purpose | Important columns |
|---|---|---|
questions | Interview question library | id, tags, title, question_text, answer_test, difficulty |
counters | Quick Apply counters | id, title, count, is_pinned, created_at |
copy_texts | Reusable snippets | id, title, text_content, created_at |
Common SQL
Select all questions:
select id, tags, title, question_text, answer_test, created_at, difficulty
from public.questions
order by created_at desc, id desc;Delete one question:
delete from public.questions
where id = '<question-id>';API routes
Shared Worker API reference for web and extension clients.
All API routes are served by the shared Cloudflare Worker in api/worker.
When AUTH_ENABLED=true, requests must include a valid dashboard_session cookie unless they are auth endpoints.
| Method | Path | Description |
|---|---|---|
GET | /api/health | Checks Neon connectivity. |
GET | /api/dashboard | Returns dashboard metrics and recent data. |
GET | /api/interview-questions | Lists interview questions. |
POST | /api/interview-questions | Creates an interview question. |
PATCH | /api/interview-questions/:id | Updates an interview question. |
DELETE | /api/interview-questions/:id | Deletes an interview question. |
GET | /api/counters | Lists Quick Apply counters. |
POST | /api/counters | Creates a counter. |
GET | /api/copy-texts | Lists saved snippets. |
POST | /api/copy-texts | Creates a saved snippet. |
GET | /api/map-pins | Lists map pins. |
POST | /api/map-pins | Creates a map pin. |
PATCH | /api/map-pins/:id | Updates a map pin. |
DELETE | /api/map-pins/:id | Deletes a map pin. |
POST | /api/auth/login | Creates a signed session cookie. |
POST | /api/auth/logout | Clears the session cookie. |
Create question body:
{
"tags": ["system-design", "technical"],
"title": "System Design",
"question_text": "How would you design a rate limiter?",
"answer_test": "Look for requirements, trade-offs, storage, and failure modes.",
"difficulty": "Hard"
}Authentication
Optional single-admin authentication behavior.
Authentication is disabled unless AUTH_ENABLED=true in the Worker environment.
AUTH_ENABLED=true
ADMIN_EMAIL="admin@example.com"
ADMIN_PASSWORD="use-a-long-unique-password"
AUTH_SECRET="at-least-32-random-characters"Generate a secret:
openssl rand -base64 32Request flow
- The Worker handles login, logout, and API authentication.
- Session tokens are signed with Web Crypto in
api/worker/src/index.js. - The session cookie is named
dashboard_session. - Static page access should be protected at the hosting layer when docs or screens must be private.
Troubleshooting
Debugging notes for local web development and Neon connectivity.
Direct Neon works but API calls fail
Run the direct smoke test:
cd api
npm run test:neonThen check the Worker route:
curl -i http://127.0.0.1:8787/api/healthIf the route fails but the direct script works, inspect:
api/worker/.dev.varsDATABASE_URLWorker secret in productionALLOWED_ORIGINCORS configuration- Worker logs from Wrangler or Cloudflare
For web client issues, confirm:
NEXT_PUBLIC_API_BASE_URL="http://127.0.0.1:8787"Chatur iOS
SwiftUI app structure, persistence, and build commands.
chatur/ is the SwiftUI iOS app in this repository.
Screens
- Home
- Location Tracker
- Camera
- GeospatialAR
- Notepad
- Finance
- Pomodoro
Persistence
SQLite tables in chatur/DatabaseStore.swift:
locationsphotoswateroutside_time
Notepad content uses @AppStorage("notepad.text").
Finance hard costs are JSON encoded in UserDefaults.
Build
xcodebuild -project boba.xcodeproj -scheme chatur -destination 'generic/platform=iOS Simulator' build