Skip to content

Tech Stack

Package Manager

  • pnpm dengan workspace protocol (workspace:* untuk internal packages).
  • pnpm workspace catalogs untuk shared dependency versions across packages.

Frontend (apps/web)

  • SvelteKit 2.59.1 (latest) + Svelte 5.55.5 (latest) + Vite 6
  • @sveltejs/adapter-cloudflare 7.2.8 (latest) — deploys to Cloudflare Workers/Pages hybrid
  • Tailwind CSS 4 + shadcn-svelte
  • TanStack Query 5 untuk Svelte (@tanstack/svelte-query) untuk server state
  • SvelteKit routing untuk SPA routing
  • oRPC Client (@orpc/client + @orpc/openapi-client/fetch) untuk API calls

Backend (apps/api)

  • oRPC 1.14.2 (latest stable) — type-safe RPC framework dengan OpenAPI generation
    • @orpc/server — server-side procedures dan middleware
    • @orpc/contract — contract-first route definitions (zero server deps)
    • @orpc/openapi — OpenAPI spec generation
    • @orpc/openapi/fetch — fetch adapter untuk Cloudflare Workers
    • @orpc/client + @orpc/openapi-client — typed client untuk frontend
  • better-auth 1.6.9 (latest stable) — auth dengan Drizzle adapter
  • Zod 4 — schema validation (v4, latest stable). Request/response schemas di-export dari route handler dan di-consume via @apps/api/schemas. Date fields selalu pakai z.coerce.date() untuk handle serialization wire.
  • Drizzle ORM — database access via @packages/db
  • Pure Cloudflare Workers fetch handler (tidak pakai Hono atau HTTP framework tambahan)

Database

  • Cloudflare D1 — SQLite-compatible edge database
  • Drizzle ORM 0.45.2 (latest stable) + drizzle-kit 0.31.10 (latest stable) untuk schema dan migrations

Auth

  • better-auth 1.6.9 plugins:
    • Google OAuth
    • Email / Password (dengan worker-friendly hasher)
    • Magic Link / Email OTP
    • BearerAuthorization: Bearer <token> header auth untuk non-browser clients
    • JWT/api/auth/token dan /api/auth/jwks endpoints untuk JWT generation dan verification
  • Password hashing: scrypt via node:crypto.scrypt (dengan nodejs_compat flag). Verified working di Workers — tidak perlu fallback.
  • Jangan pakai native bcrypt atau @node-rs/argon2 — requires native bindings yang gagal di Workers.
  • Role system: student, teacher, admin, owner (stored di better-auth user table via additionalFields).

Email

  • Resend untuk transactional emails (magic codes, notifications)

Storage

  • Cloudflare R2 untuk photo evidence dan payment proof uploads
  • @packages/storage menyediakan upload helpers dengan file type dan size validation

Telemetry

  • @tigorhutasuhut/telemetry-js — OpenTelemetry SDK abstraction untuk tracing, metrics, dan structured logging.
  • API (apps/api): pakai subpath /cloudflare dengan instrument() wrapper di entrypoint + @traced() decorator di service mixins + withQueryName() untuk DB query spans.
  • Web server (apps/web): pakai traceHandler() di hooks.server.ts untuk trace tiap request SvelteKit.
  • Web browser: eager instrumentFetch() di hooks.client.ts (patch globalThis.fetch sebelum module lain capture reference) + lazy initSDK() via dynamic import.
  • Logger: getLogger() dari telemetry-js — structured logging dengan auto-attachment trace_id dan span_id. Jangan pakai console.log / console.error di production code.
  • Semua runtime error pakai AppError dari @tigorhutasuhut/telemetry-js/error — menggantikan ServiceError custom.

Deployment

  • Cloudflare Workers (apps/api, apps/web)
  • Cloudflare Pages (apps/docs)
  • wrangler CLI untuk local dev dan deploy
  • worker-configuration.d.ts generated by wrangler types (gitignored)

Code Quality

  • Biome — single formatter dan linter untuk semua code
  • lefthook — pre-commit hooks running biome check --write on staged files
  • turbo — monorepo task orchestration

Constraints

  • NO native dependencies (no Rust, no node-gyp).
  • Semua packages harus bisa run di Cloudflare Workers runtime (V8 isolates).
  • Prefer Web APIs over Node.js APIs.
  • Semua env vars diakses melalui Env binding atau env di Worker fetch context.
  • Workers (apps/api, apps/web) support full env keys di wrangler.jsonc; Pages (apps/docs) TIDAK support env keys — env vars dashboard-managed.

Released under the MIT License.