Skip to content

RahRha-v3-2/Tutorial-Credit-Course

Repository files navigation

Guap Finance — Credit Education Platform

A production-grade credit-education platform: TypeScript API gateway, PostgreSQL persistence, static HTML frontend, deployed to a single VPS behind nginx + Let's Encrypt.

Quick start (local, demo mode)

cd api-gateway
npm install
npm test         # 28 tests, ~5s
npm run dev      # http://localhost:3000

In demo mode (no LINODE_DB_* env vars), the gateway runs entirely in memory: register / login / enroll / progress all work without a database.

Deploy to a fresh Ubuntu VPS

sudo DOMAIN=krai.example.com EMAIL=you@example.com \
     LINODE_DB_HOST=... LINODE_DB_USER=... LINODE_DB_PASSWORD=... \
     ./deploy-vps.sh

The script is idempotent: installs Node 20, nginx, certbot, ufw, fail2ban; creates the krai system user; clones into /opt/krai; generates fresh JWT secrets into /etc/krai/gateway.env (mode 0640); runs migrations; installs the systemd unit and nginx vhost; obtains an SSL cert; locks down the firewall.

Layout

api-gateway/         Express + zod gateway — primary entry point
  src/
    config/          zod-validated env loader
    db/              pg pool + sequential SQL migrator
    middleware/      requestId, helmet+cors, auth, rate-limit, validate,
                     metrics, errorHandler
    routes/          health, auth, courses, progress, quiz,
                     leaderboard, analytics
    services/        passwords (bcrypt), tokens (JWT), course/user/progress
                     repos (PG with in-memory fallback)
  tests/             jest unit + supertest integration (28 tests)
infrastructure/
  migrations/        canonical SQL schema
  nginx/             krai.conf vhost + krai-proxy.conf snippet
  systemd/           hardened krai-gateway.service unit
  backup/            daily PG backup script (cron-friendly)
  monitoring/        prometheus.yml
docker/
  docker-compose.prod.yml   gateway + Postgres + optional Grafana stack
frontend/            static HTML (served by the gateway)
data/courses-full.json    canonical course catalog
docs/                architecture + API reference
deploy-vps.sh        one-shot Ubuntu VPS provisioner

Security baseline

  • bcrypt password hashing (rounds=12 in prod, 4 in tests); legacy SHA256 hashes are rejected outright.
  • Separate JWT_SECRET and JWT_REFRESH_SECRET, each ≥32 chars, validated at boot — the process exits in production if either is missing.
  • helmet with strict CSP in production, HSTS preload, x-powered-by off.
  • CORS allowlist via CORS_ORIGINS (comma-separated), never * by default.
  • express-rate-limit globally plus tighter limits on /api/v1/auth/*.
  • zod validation on every body/query (no unchecked JSON).
  • Account lockout after 5 failed logins within 15 minutes.
  • Request IDs (UUID v4) on every response; structured JSON logs via winston in production.
  • Prometheus /metrics (default + per-route latency histogram); nginx restricts the endpoint to private IPs.
  • Graceful shutdown on SIGTERM/SIGINT; uncaught-exception handlers.
  • systemd unit hardened (NoNewPrivileges, ProtectSystem=strict, CapabilityBoundingSet=, MemoryDenyWriteExecute, syscall filter).

Development workflow

cd api-gateway
npm run lint        # eslint, must pass
npm run typecheck   # tsc --noEmit, must pass
npm test            # jest, must pass
npm run build       # tsc → dist/

CI (.github/workflows/ci.yml) runs lint + typecheck + test + build + npm audit + Trivy filesystem scan + Docker image smoke-test on every push.

Environment variables

Variable Default Notes
NODE_ENV development one of development, test, staging, production
PORT 3000
JWT_SECRET required, ≥32 chars
JWT_REFRESH_SECRET required, ≥32 chars
BCRYPT_ROUNDS 12
CORS_ORIGINS http://localhost:3000,http://localhost:8000 comma-separated
TRUST_PROXY false set to true behind nginx
RATE_LIMIT_WINDOW_MS 900000 15 minutes
RATE_LIMIT_MAX 300 per IP per window
AUTH_RATE_LIMIT_MAX 20 per IP per window for /auth/*
DEMO_MODE false in-memory persistence when true
LINODE_DB_HOST DB connection (Postgres)
LINODE_DB_PORT 5432
LINODE_DB_USER
LINODE_DB_PASSWORD
LINODE_DB_NAME guap_finance
LINODE_DB_SSL true
LOG_LEVEL info
LOG_FORMAT json pretty in dev

See api-gateway/src/config/env.ts for the canonical zod schema.

Documentation

  • docs/architecture.md — system design
  • docs/api-reference.md — REST endpoints
  • CONTRIBUTING.md — development guidelines
  • CLAUDE.md — internal repository guide

License

MIT.

About

Resources

Contributing

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors