Build a complete, production-ready school management web app
Build a complete, production-ready school management web application (Pronote-like). The system must be fully functional end-to-end with frontend, backend, and relational database. This is NOT a prototype. Do NOT generate mock data, fake UI, or placeholder features. Every function must work with real persistent data. GLOBAL REQUIREMENTS - Database is the only source of truth. - No static arrays, no local-only state. - All CRUD operations must persist in the database. - After every create/update/delete → immediately refetch or invalidate queries.
Read the full description
- UI must always reflect real database state without manual refresh. - All dropdowns and selectors must load real data dynamically. - All relationships must use real foreign keys. - All data must persist after page reload. INITIAL USER Create only one initial user: username: admin password: Pollo9.0ll role: admin status: active Login must work immediately. ROLES AND ACCESS CONTROL Implement role-based access control with strict permissions: - admin: full system access - management: read and analytics access - vie_scolaire: attendance and discipline - teacher: classes, grades, assignments - parent: child data only - student: own data only Every API and UI must enforce permissions. DATABASE SCHEMA Table: users - id (UUID, primary key) - username (unique) - password (hashed) - role (enum) - first_name - last_name - email - status (active/disabled) - created_at If using external authentication: - also create corresponding record in users table - link auth_id to users.id - if a user is not in users table, it must be treated as non-existent Other required tables: classes - id - name - level - section - school_year subjects - id - name - coefficient groups - id - name - description student_class - student_id - class_id parent_student - parent_id - student_id teacher_subject_class - teacher_id - subject_id - class_id timetable - id - class_id - subject_id - teacher_id - day_of_week - start_time - end_time - room grades - id - student_id - subject_id - teacher_id - value - coefficient - date assignments - id - class_id - subject_id - teacher_id - title - description - due_date lessons - id - class_id - subject_id - teacher_id - content - date attendance - id - student_id - date - status (present/absent/late) - justification_status discipline - id - student_id - type - description - date messages - id - sender_id - receiver_id - content - created_at CRITICAL FUNCTIONAL FIXES USER CREATION When admin creates a user: 1. Insert into users table 2. Ensure role is correctly assigned 3. Ensure username is unique 4. Return created object 5. Immediately refetch users list 6. Update UI instantly User must: - appear in lists immediately - be selectable in dropdowns - persist after refresh DROPDOWNS All dropdowns must: - query users table - filter by role dynamically - update immediately after new user creation STUDENT CLASS ASSIGNMENT - Each student must belong to one class - Assignment must be stored in student_class table or class_id field - After assignment: - student appears in class immediately - class shows updated student list - persists after refresh LOGIN - Must validate username/password - Must compare hashed password correctly - Must return user role - Must allow access based on role - Must persist session/token SCHOOL STRUCTURE MANAGEMENT Admin must be able to: - create classes - create subjects - create groups - assign students to classes - assign teachers to subjects - assign teachers to classes per subject Relationships must be consistent and stored in DB. TIMETABLE SYSTEM Timetable must be created per class. Each timetable entry must include: - class_id - subject_id - teacher_id - day_of_week - start_time - end_time - room Rules: - each class has independent timetable - student sees only their class timetable - parent sees child timetable - teacher sees only assigned lessons - admin sees all CORE FEATURES Teacher: - insert grades - create assignments - create lessons Student: - view grades - view assignments - view timetable Parent: - view child data - view grades - view attendance Vie scolaire: - manage attendance - manage absences and justification Admin: - full management REAL-TIME DATA CONSISTENCY After any mutation: - refetch data OR invalidate cache - update UI immediately - update dropdowns immediately No stale data allowed. SEARCH AND FILTER All lists must support: - search - filtering - sorting - pagination SECURITY - passwords must be hashed - enforce role permissions on backend - validate all inputs - prevent unauthorized access FINAL VALIDATION TESTS 1. login with admin works 2. create user → appears immediately 3. create class → appears immediately 4. assign student → visible and persistent 5. assign teacher → visible and correct 6. create timetable → correct per class 7. refresh page → all data still exists FINAL REQUIREMENT The system must be complete, consistent, and fully functional. If any feature is incomplete or broken, fix it before finishing.
import express, { Request, Response } from 'express';
import cors from 'cors';
import dotenv from 'dotenv';
import { Pool } from 'pg';
dotenv.config();
const app = express();
app.use(cors());
app.use(express.json());
const pool = new Pool({
user: process.env.DB_USER,
host: process.env.DB_HOST,
database: process.env.DB_DATABASE,
password: process.env.DB_PASSWORD,
port: Number(process.env.DB_PORT),
});
import bcrypt from 'bcryptjs';
import jwt from 'jsonwebtoken';
// ...
app.post('/api/login', async (req: Request, res: Response) => {
const { username, password } = req.body;
try {
const userResult = await pool.query('SELECT * FROM users WHERE username = $1', [username]);
if (userResult.rowCount === 0) return res.status(401).send('User not found');
const user = userResult.rows[0];
const isPasswordValid = await bcrypt.compare(password, user.password);
if (!isPasswordValid) return res.status(401).send('Invalid credentials');
const token = jwt.sign({ userId: user.id, role: user.role }, process.env.JWT_SECRET as string, {
expiresIn: '1h',
});
res.json({ token, role: user.role });
} catch (err) {
console.error(err);
res.status(500).send('Internal server error');
}
});
app.listen(5000, () => {
console.log('Server is running on port 5000');
});