Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/Taykl12/Classify/llms.txt

Use this file to discover all available pages before exploring further.

The Classify backend reads all of its runtime configuration from a single .env file located at server/.env. This file is intentionally excluded from version control — you must create it by copying the example file and filling in the values specific to your Supabase project.

Create the env file

cp server/.env.example server/.env
Then open server/.env in your editor and replace the placeholder values described below.

Reference: all variables

SUPABASE_URL

The base URL of your Supabase project. Every API call the server makes — whether it is reading data, authenticating users, or accessing storage — goes to this URL. Where to find it: Supabase Dashboard → Settings → API → Project URL
SUPABASE_URL=https://<your-project-ref>.supabase.co

SUPABASE_ANON_KEY

The public anonymous key for your project. This key is subject to Row-Level Security (RLS) policies, so it is safe to expose in browser contexts. On the server it is used for user-scoped operations and for creating clients that act on behalf of authenticated users. Where to find it: Supabase Dashboard → Settings → API → Project API keys → anon / public
SUPABASE_ANON_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

SUPABASE_SERVICE_ROLE_KEY

The service role key grants full database access and bypasses all RLS policies. It is used exclusively by admin routes and professor-level operations that require elevated privileges.
Never expose SUPABASE_SERVICE_ROLE_KEY to the browser, include it in client-side bundles, or commit it to a public repository. Anyone who obtains this key can read, modify, or delete all data in your database without restriction. Store it only in your server-side environment and in a secrets manager in production.
Where to find it: Supabase Dashboard → Settings → API → Project API keys → service_role / secret
SUPABASE_SERVICE_ROLE_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

PORT

The TCP port the Express server listens on. Defaults to 3001. Change this if another process already occupies that port, or if your hosting platform requires a specific port (e.g. many platforms use 8080).
PORT=3001

APP_ORIGIN

The full origin (scheme + host + optional port) of the frontend application. The server uses this value in two places:
  • CORS headers — only requests from this origin are allowed to call the API.
  • Password-reset redirect URL — Supabase Auth redirects users back to this origin after they click the reset link in their email.
APP_ORIGIN=http://localhost:5173
Set this to your production frontend domain when deploying, for example https://classify.yourdomain.com.

ESP32_DEVICE_TOKEN

A shared secret string that ESP32 devices must include in requests to the attendance ingestion endpoint. The server validates this token to ensure only authorised hardware can push attendance records.
The default value dev-esp32-token is public knowledge. Always replace it with a long, randomly generated string in production. A 32-character random hex string is a reasonable minimum:
openssl rand -hex 32
ESP32_DEVICE_TOKEN=dev-esp32-token

Complete .env.example

# server/.env.example

# ── Supabase ──────────────────────────────────────────────
# Project URL from Dashboard → Settings → API
SUPABASE_URL=https://jgrtmokyqdvdxsldmkou.supabase.co

# Public anon key — safe to use in user-scoped queries (RLS enforced)
SUPABASE_ANON_KEY=

# Service role key — bypasses RLS; NEVER expose publicly
SUPABASE_SERVICE_ROLE_KEY=

# ── Server ────────────────────────────────────────────────
# TCP port the Express server listens on
PORT=3001

# Frontend origin used for CORS and password-reset redirects
APP_ORIGIN=http://localhost:5173

# ── Hardware ──────────────────────────────────────────────
# Shared secret for ESP32 device authentication
# Change this from the default in any non-development environment
ESP32_DEVICE_TOKEN=dev-esp32-token

How Supabase clients are constructed

The server creates three distinct Supabase client instances depending on the privilege level required for a given operation:
ClientKeys usedRLS enforcedTypical usage
createAnonClient()SUPABASE_URL + SUPABASE_ANON_KEY✅ YesPublic reads, role lookups
createUserClient(accessToken)SUPABASE_URL + SUPABASE_ANON_KEY + user JWT✅ Yes (as the authenticated user)All student and professor data operations
createAdminClient()SUPABASE_URL + SUPABASE_SERVICE_ROLE_KEY❌ BypassedAdmin routes, professor assignment, bulk operations
The createUserClient function injects the user’s JWT from the request so that RLS policies on tables like grupos_proyectos and usuarios are evaluated against the real authenticated user rather than an anonymous caller.
In development you can run the frontend and backend simultaneously with hot-reload by running pnpm dev in the repo root (starts Vite on port 5173) and pnpm dev:server in the server/ directory (starts nodemon on port 3001). Both values match the .env.example defaults, so no changes are required for local development.

Next step

With your .env file in place, continue to Database Setup to apply the Supabase migrations and seed the roles table.

Build docs developers (and LLMs) love