Full-stack application — academic project (PFA), EMSI · 2025
AppointmentPro
Appointment booking system with client / professional roles

Context and problem
Built as my final-year academic project (PFA) at EMSI. Independent professionals often manage appointments by phone or on paper: missed slots, double bookings, no overview. The goal was a complete web application covering the entire appointment lifecycle, from publishing availability to completion.
Objectives
- Offer two distinct journeys: professionals publish slots, clients book them.
- Guarantee that a booked slot can no longer be offered to other clients.
- Cover the full cycle: booking, completion, cancellation.
- Secure the data: each user only sees their own appointments.
My role
- Development of the React / TypeScript interface: client and professional dashboards, forms, slot lists.
- PostgreSQL database modelling: profiles, time slots, appointments.
- Supabase authentication setup with role selection at sign-up.
- Writing the Row Level Security policies controlling access to every table.
Key features
- Email sign-up and sign-in via Supabase Auth, with client or professional role.
- Professionals create and delete availability slots (date, start and end time).
- Clients browse available slots and book in one click.
- Appointment lifecycle: booked, completed, cancelled.
- A booked slot automatically becomes unavailable to other clients.
- Role-specific dashboards: slot management for pros, bookings for clients.
Technical architecture
- React 18 + TypeScript + Vite frontend, components organised by role (client, professional, auth, shared).
- Supabase backend-as-a-service: PostgreSQL database, authentication and generated API.
- Database-level security: Row Level Security policies on the profiles, time_slots and appointments tables — a client can only read or modify their own appointments.
- Shared TypeScript types (Profile, TimeSlot, Appointment) mirroring the relational schema.
- Versioned SQL migration defining enums, tables and access policies.
Technologies
- React 18
- TypeScript
- Vite
- Tailwind CSS
- Supabase
- PostgreSQL
- Row Level Security
Technical decisions and challenges
- Booking integrity: preventing double-booking of a slot — availability status is enforced by the database, not only by the interface.
- Data isolation between users: RLS policies guarantee no user can reach another user's appointments by crafting a request.
- Two distinct experiences in one application: routing and components adapt to the role returned by authentication.
Outcome and limitations
- Working application tested locally end to end: sign-up, slot creation, booking and cancellation all verified (screenshots below).
- Known limitation: the app depends on an external Supabase project; environment keys are not included in the project folder.
- Known limitation: not publicly deployed at this stage; demo accounts only.
Screenshots




