Classify ships with 15 ordered SQL migrations that build the complete database schema incrementally. You must apply all of them in sequence before starting the server. After the migrations run you also need to seed theDocumentation 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.
roles table with the three built-in roles.
All migration files live in
supabase/migrations/ and are numbered 001 through 015. Each file is idempotent in the sense that re-running an already-applied migration will not corrupt data, but the safest approach is to apply them once in order on a fresh Supabase project.Applying the migrations
You have two options: the Supabase SQL editor (no extra tooling required) or the Supabase CLI (recommended for automated deployments).Option A — Supabase SQL Editor
- Open your project in the Supabase Dashboard.
- Navigate to SQL Editor.
- For each file in
supabase/migrations/, open the file locally, copy its contents, paste into the SQL editor, and click Run. Work through them in numerical order (001→015).
Option B — Supabase CLI
The Supabase CLI can apply migrations directly against your remote project.This approach is preferred for CI/CD pipelines because it tracks which migrations have already been applied.
Seed the roles table
After all migrations have been applied, insert the three built-in roles. Without this seed the application cannot assign roles to users and sign-up will fail.Run this in the Supabase SQL editor or via
supabase db execute.The
roles table is readable by both anonymous and authenticated users (the RLS policy grants public SELECT access). This allows the sign-up form to list available roles without requiring a prior login.Migration overview
The table below summarises what each migration does so you understand what is being applied to your database.| # | Key changes |
|---|---|
| 001 | Add estado_proyecto and es_favorito UI columns to grupos_proyectos |
| 002 | Grant API roles on the public schema |
| 003 | Add favorito columns and CRUD Row-Level Security policies to grupos_proyectos |
| 004 | Drop legacy escuela and members tables (schema cleanup) |
| 005 | Create create_grupo_proyecto RPC function |
| 006 | Add RLS member-access policies |
| 007 | Add project config columns: alcance_detalle, notas_alcance, anteproyecto_validado, link_respaldo, link_calificaciones, documentos |
| 008 | Create the avatars profile storage bucket |
| 009 | Create search_usuarios_dni search function |
| 010 | Create create_tarea_grupo RPC function |
| 011 | Create eventos_calendario table |
| 012 | Create admin academic schema: cursos, materias, cursos_usuarios_asignados, materia_profesor |
| 013 | Add division, materia, and horario columns to cursos |
| 014 | Create asistencias attendance table |
| 015 | Add project lock columns (lock_alcance, lock_documentacion, lock_equipo) and proyecto_asignado_profesor |
Key tables
usuarios
Stores the user profile for every registered account, linked to Supabase Auth via the user UUID. Includes nombre, apellido, dni, foto_perfil (URL to the Storage avatar), and a foreign key to roles.
grupos_proyectos
The central project entity. Each row represents a student group’s project and tracks status, scope details, supporting links, document references, lock flags, and the assigned professor.
tareas_grupo
Tasks scoped to a specific project group. Created via the create_tarea_grupo RPC to ensure atomic assignment and permission checks.
eventos_calendario
Calendar events associated with courses or project groups, used to schedule milestones, presentations, and deadlines.
cursos
Academic course instances, including division, subject (materia), and schedule (horario). Used by the admin panel and linked to attendance records.
materias
The catalogue of subjects that can be assigned to courses and to professor accounts via the materia_profesor join table.
asistencias
Attendance records keyed to a user, a course, and a timestamp. Records can be created manually by a professor or automatically by an ESP32 device via the device token endpoint.
RPC functions
Classify uses PostgreSQL functions (called viasupabase.rpc()) for operations that require atomicity or that need to bypass client-side permission boundaries safely.
| Function | Migration | Purpose |
|---|---|---|
create_grupo_proyecto | 005 | Creates a new project group and assigns the calling user as the initial member in one atomic transaction |
create_tarea_grupo | 010 | Creates a task and associates it with a project group, enforcing membership checks |
search_usuarios_dni | 009 | Full-text search over user DNIs, used by the invite flow to find users without exposing the full usuarios table |
Row-Level Security policies
All sensitive tables have RLS enabled. The policies follow a consistent pattern:usuarios— authenticated users can read only their own row (auth.uid() = id_usuario). Admin operations use the service role client which bypasses RLS entirely.grupos_proyectos— a user can access a project row if they appear inproyecto_profesor(the assigned professor column) or are a member of the associatedgrupo_estudiantegroup.roles— SELECT is open to both anonymous and authenticated callers so the sign-up form can list roles; INSERT/UPDATE/DELETE are restricted to the service role.
Profile avatars storage bucket
Migration 008 creates a Supabase Storage bucket namedavatars. When a user uploads a profile photo the server stores the file in this bucket and writes the resulting public URL to usuarios.foto_perfil.
The bucket is configured with the following access rules:
- Authenticated users can upload and replace their own avatar (path scoped to their user UUID).
- Public read is enabled so avatar URLs can be embedded in
<img>tags without requiring a signed URL.
If the
avatars bucket does not exist when the server starts (for example, if migration 008 was skipped), avatar uploads will fail with a storage error. Verify the bucket is present under Storage in the Supabase Dashboard after running the migrations.