Skip to content

Eric-Philippe/YBoard-Intervenants

Repository files navigation

YBoard — Teacher Management Platform

YBoard is a web application developed for Ynov Toulouse to manage teacher candidates, module assignments, and workload tracking across all programs and specialties of the school.

YBoard


Features

Teacher management — Create and maintain instructor profiles with contact details, diploma, hourly rate, and CV (PDF upload, preview, replacement, deletion).

Module and program management — Organize educational modules by promo (level + specialty) with associated workload targets.

Assignment workflow — Assign teachers to modules through three statuses: Ongoing (currently assigned), Potential (under evaluation with interview tracking), Selected (validated for assignment).

Workload tracking — Monitor the hourly volume per instructor per module, with visibility across all programs.

Drag-and-drop interface — Move teachers between assignment statuses with an intuitive kanban-style board.

Secure authentication — JWT-based login with bcrypt password hashing.


Tech Stack

Layer Technology
Frontend Next.js 15, React 19, TypeScript
Backend tRPC, Next.js API Routes
Database PostgreSQL 15, Prisma ORM
UI Mantine UI, Tailwind CSS, Tabler Icons
Auth JWT, bcrypt
Drag & Drop @dnd-kit
Validation Zod
Containerization Docker, Docker Compose

Getting Started

Prerequisites

  • Node.js 22+
  • npm 10+
  • PostgreSQL 15+

Installation

git clone <repository-url>
cd YBoard-Intervenants
npm install

Environment

Create a .env file at the project root:

DATABASE_URL="postgresql://postgres:password@localhost:5432/yboard"
JWT_SECRET="change-this-in-production"
NODE_ENV="development"

Database setup

npm run db:generate    # Generate Prisma client
npm run db:migrate     # Apply migrations
npm run db:seed        # (Optional) Seed initial data

Development

npm run dev

The application will be available at http://localhost:3000.


Available Scripts

# Development
npm run dev              # Start dev server (Turbo)
npm run build            # Production build
npm run start            # Production start
npm run preview          # Build then start

# Database
npm run db:generate      # Generate Prisma client
npm run db:migrate       # Apply migrations
npm run db:push          # Push schema without migration (dev only)
npm run db:studio        # Open Prisma Studio

# Code quality
npm run check            # Lint + TypeScript check
npm run lint             # ESLint
npm run lint:fix         # ESLint with auto-fix
npm run typecheck        # TypeScript check only
npm run format:check     # Prettier check
npm run format:write     # Prettier format

Docker

Docker Compose (recommended)

docker-compose up -d       # Start application and database
docker-compose logs -f     # Follow logs
docker-compose down        # Stop
docker-compose down -v     # Stop and remove all volumes (deletes data)

Two persistent volumes are created automatically:

  • postgres_data — PostgreSQL data
  • cv_storage — Uploaded CV files (/app/uploads/cv)

CV backup

# Backup
docker cp $(docker-compose ps -q app):/app/uploads/cv ./cv_backup

# Restore
docker cp ./cv_backup/. $(docker-compose ps -q app):/app/uploads/cv/

Manual Docker

docker build -t yboard-app .

docker run -p 3000:3000 \
  -v yboard_cv_storage:/app/uploads/cv \
  -e DATABASE_URL="postgresql://postgres:password@host.docker.internal:5432/yboard" \
  -e JWT_SECRET="your-secret-key" \
  yboard-app

Database Schema

erDiagram
    Users {
        uuid id PK
        varchar firstname
        varchar lastname
        varchar email
        varchar password
        timestamp last_connected
        uuid active_perimeter_id FK
    }

    Perimeter {
        uuid id PK
        varchar title
        varchar slug
        varchar origin
        varchar color
        timestamp created_at
    }

    PerimeterMember {
        uuid id PK
        uuid perimeter_id FK
        uuid user_id FK
        timestamp joined_at
    }

    Promos {
        uuid id PK
        varchar level
        varchar specialty
        varchar icon
        uuid perimeter_id FK
        varchar survey_title
        text survey_introduction
    }

    Modules {
        uuid id PK
        varchar name
        text description
        varchar periode
        boolean avec_mentor
        int nombre_heure_tdp
        int nombre_heure_ffp
        uuid perimeter_id FK
    }

    Teacher {
        uuid id PK
        varchar lastname
        varchar firstname
        varchar status
        varchar diploma
        decimal rate
        varchar email_perso
        varchar email_ynov
        varchar phone_number
        varchar cv_filename
        timestamp cv_uploaded_at
    }

    TeacherComment {
        uuid id PK
        uuid teacher_id FK
        uuid perimeter_id FK
        text comment
        timestamp updated_at
    }

    PromoModules {
        uuid id PK
        uuid module_id FK
        uuid promo_id FK
        int workload
    }

    ongoing {
        uuid teacher_id FK
        uuid promo_modules_id FK
        int workload
        decimal rate
        decimal rateTDP
        decimal rateFFP
    }

    potential {
        uuid teacher_id FK
        uuid promo_modules_id FK
        int workload
        decimal rate
        decimal rateTDP
        decimal rateFFP
        date interview_date
        text interview_comments
        boolean decision
    }

    selected {
        uuid teacher_id FK
        uuid promo_modules_id FK
        int workload
        decimal rate
        decimal rateTDP
        decimal rateFFP
    }

    SurveySubmission {
        uuid id PK
        uuid perimeter_id FK
        varchar nom
        varchar prenom
        varchar email
        varchar telephone
        varchar niveau_academique
        text intitule_diplome
        varchar annees_experience
        text domaines_exercice
        varchar final_choice
        timestamp created_at
    }

    SurveyResponse {
        uuid id PK
        uuid submission_id FK
        uuid promo_modules_id FK
        varchar module_label_snapshot
        varchar response
        text condition_text
    }

    SurveySubmissionTeacher {
        uuid id PK
        uuid submission_id FK
        uuid teacher_id FK
        timestamp linked_at
    }

    Perimeter ||--o{ PerimeterMember : "has members"
    Perimeter ||--o{ Promos : "contains"
    Perimeter ||--o{ Modules : "contains"
    Perimeter ||--o{ TeacherComment : "scopes"
    Perimeter ||--o{ SurveySubmission : "receives"
    Perimeter ||--o{ Users : "active for"
    Users ||--o{ PerimeterMember : "belongs to"
    Promos ||--o{ PromoModules : "has"
    Modules ||--o{ PromoModules : "linked via"
    Teacher ||--o{ ongoing : "assigned"
    Teacher ||--o{ potential : "candidate"
    Teacher ||--o{ selected : "selected"
    Teacher ||--o{ TeacherComment : "has"
    PromoModules ||--o{ ongoing : "contains"
    PromoModules ||--o{ potential : "contains"
    PromoModules ||--o{ selected : "contains"
    PromoModules ||--o{ SurveyResponse : "referenced in"
    SurveySubmission ||--o{ SurveyResponse : "has"
    SurveySubmission ||--o{ SurveySubmissionTeacher : "linked to"
Loading

Project Structure

src/
├── app/
│   ├── api/
│   │   ├── cv/             # CV upload, view, delete
│   │   └── trpc/           # tRPC handler
│   ├── login/
│   ├── modules/
│   ├── teachers/
│   ├── promos/
│   └── users/
├── components/
│   ├── AppLayout.tsx
│   ├── Sidebar.tsx
│   └── modals/
├── contexts/
│   ├── AuthContext.tsx
│   └── ModalContext.tsx
├── server/
│   ├── api/
│   └── db.ts
├── trpc/
└── types/
uploads/
└── cv/                     # CV files (not tracked in git)

CV Storage

Uploaded CVs are stored under uploads/cv/ with the naming convention [uuid]_[timestamp].pdf.

  • Accepted format: PDF only
  • Maximum size: 5 MB
  • API endpoints: POST /api/cv/upload, GET /api/cv/[filename], DELETE /api/cv/[filename]

In production (Docker), the directory is mapped to a persistent volume to survive container restarts.


First Login

Create an admin user directly in the database, then log in at /login.


License

Proprietary — Eric PHILIPPE © 2026

About

YBoard is a comprehensive management platform specifically developed for Ynov Toulouse to handle in-depth candidate management and teacher assignment across all modules and programs of the school.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Packages

 
 
 

Contributors

Languages