Reviewed-on: #17
Spanglish — Language Exchange Event Platform
A full-stack web app for organizing and managing language exchange events (Asunción, Paraguay).
Features
- Public site: events, booking, contact, community, legal pages, bilingual (EN/ES)
- User dashboard: profile, tickets, payments, sessions/security
- Admin (
/admin): events, tickets/check-in, users/roles, payments, email templates, media uploads - API: Swagger UI at
/api-docs, OpenAPI JSON at/openapi.json, health check at/health
Tech stack
- Backend: Node.js + TypeScript, Hono, Drizzle ORM, SQLite (default) or PostgreSQL
- Auth: JWT (via
jose), Argon2id password hashing (with legacy bcrypt verification for older hashes) - Email:
nodemailer(SMTP) with optional provider config - Frontend: Next.js 14 (App Router), Tailwind CSS, SWR, Heroicons
Local development
Prerequisites
- Node.js 18+
- npm
Setup
npm install
cp backend/.env.example backend/.env
cp frontend/.env.example frontend/.env
Initialize database (SQLite by default)
npm run db:migrate
Run
npm run dev
Default URLs:
- Frontend:
http://localhost:3002 - Backend API:
http://localhost:3001 - API docs:
http://localhost:3001/api-docs
First user becomes admin
The first user to register becomes the admin. Register at /register.
Useful scripts (workspace)
Run these from the repo root:
npm run dev
npm run build
npm run start
npm run db:generate
npm run db:migrate
npm run db:studio
npm run db:export # Backup database
npm run db:import # Restore from backup
You can also run per workspace:
npm run dev --workspace=backend
npm run dev --workspace=frontend
Environment variables
Backend (backend/.env)
Key settings (see backend/.env.example for the full list):
- DB:
DB_TYPE=sqlite|postgres,DATABASE_URL=./data/spanglish.db(or Postgres URL) - Auth:
JWT_SECRET(change in production) - URLs/ports:
PORT,API_URL,FRONTEND_URL - Email:
EMAIL_PROVIDER(console|smtp|resend) and corresponding credentials - Payments (optional): Stripe/MercadoPago/LNbits configuration
Frontend (frontend/.env)
Key settings (see frontend/.env.example):
- Server port:
PORT=3002 - API base URL:
NEXT_PUBLIC_API_URL(optional)- Leave empty to use same-origin
/api(recommended when running behind nginx) - In local dev, Next.js rewrites
/api/*and/uploads/*to the backend
- Leave empty to use same-origin
- Social links (optional):
NEXT_PUBLIC_WHATSAPP,NEXT_PUBLIC_INSTAGRAM, etc.
Database
SQLite (default)
- DB file defaults to
backend/data/spanglish.db(viaDATABASE_URL=./data/spanglish.db) - Run migrations with
npm run db:migrate
PostgreSQL
Set in backend/.env:
DB_TYPE=postgres
DATABASE_URL=postgresql://user:password@localhost:5432/spanglish
Then run:
npm run db:migrate
Backups (export / import)
Create backups and restore if needed:
# Export (creates timestamped file in backend/data/backups/)
npm run db:export
# Export to custom path
npm run db:export -- -o ./my-backup.db # SQLite
npm run db:export -- -o ./my-backup.sql # PostgreSQL
# Import (stop the backend server first)
npm run db:import -- ./data/backups/spanglish-2025-03-07-143022.db
npm run db:import -- --yes ./data/backups/spanglish-2025-03-07.sql # Skip confirmation
Note: Stop the backend before importing so the database file is not locked.
Production deployment (nginx + systemd)
This repo includes example configs in deploy/:
- systemd:
deploy/spanglish-backend.service,deploy/spanglish-frontend.service- Backend runs on 3018, frontend on 3019 by default (see the unit files)
- Backend needs write access to
backend/dataandbackend/uploads
- nginx:
deploy/spanglish_upstreams.confdefines upstreams for ports 3018/3019deploy/front-end_nginx.confproxies/apiand/uploadsto the backend and everything else to the frontenddeploy/back-end_nginx.confis a dedicated API vhost example with CORS handling
Typical production flow:
npm ci
npm run build
npm run db:migrate
Then install/enable the systemd services and nginx configs for your server.
Documentation
- Specs / notes:
about/ - Legal docs:
frontend/legal/
License
MIT
Description
Spanglish V1.1
Latest
Languages
TypeScript
99.7%
CSS
0.2%
JavaScript
0.1%