Skip to content

Latest commit

 

History

46 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

BarberOS

Full-stack barbershop management system — online booking, barber schedules, commission tracking, and inventory in one platform.

Python FastAPI React TypeScript PostgreSQL Docker Tests License Live Demo


Screenshots

Homepage

Public landing page

Step 1
Step 1 — Service & barber
Step 2
Step 2 — Date & time
Step 3
Step 3 — Your details

Booking Confirmation

Booking confirmation with reschedule option

Admin Dashboard

Admin dashboard — real-time metrics

Appointments
Appointment management
Payments
Payments & commissions

Inventory

Inventory management with low-stock alerts

Barber Schedule

Barber panel — daily schedule

API Docs 1
OpenAPI documentation — auth, admin & scheduling endpoints
API Docs 2
OpenAPI documentation — payments, inventory & public endpoints

Live Demo

Role Login URL Email Password
Admin https://barberos-os.vercel.app/admin/login admin@barberos.com demo1234
Barber https://barberos-os.vercel.app/barbero/login carlos@barberos.com demo1234
Client https://barberos-os.vercel.app/reservar No account required —

Seed data includes 3 barbers, 5 services, 8 appointments across all statuses, and 6 inventory items.


Features

  • 🗓️ 3-step public booking — no account required, clients book in under 2 minutes
  • 👥 Three-role system — Admin, Barber, and Client with fully isolated dashboards and auth flows
  • 💰 Automated commission split — 40% barber / 60% shop, with bi-weekly earnings reports per barber
  • 📧 Automated email reminders — APScheduler sends reminders at 24h and 2h before each appointment via Resend
  • 📅 Client rescheduling — clients reschedule directly from their confirmation email link, no account needed
  • 📦 Inventory management — stock tracking with configurable minimum thresholds and low-stock alerts
  • 🔐 JWT auth with refresh tokens — separate OAuth2 flows for Admin and Barber roles, bcrypt password hashing
  • 📊 Real-time admin dashboard — daily appointments, monthly revenue, pending count, and per-barber commission breakdown
  • 🐳 Docker ready — full local environment with docker-compose in one command, includes PostgreSQL and nginx
  • ✅ 37 passing tests — pytest suite covering auth flows, booking validation, role-based access, Pydantic schemas and commission calculations
  • 📖 OpenAPI documentation — 25+ documented endpoints at /docs with request/response schemas

Tech Stack

Backend

Technology Version Role
Python 3.12 Language
FastAPI 0.135 HTTP framework / REST API
SQLAlchemy 2.0 Async ORM
PostgreSQL 15 Relational database
Alembic — Schema migrations
Pydantic v2 Schema validation
python-jose — JWT authentication (HS256)
passlib / bcrypt — Password hashing
APScheduler — Email reminder jobs
Resend — Transactional email delivery
Docker — Containerization
pytest — Testing (37 passing tests)

Frontend

Technology Version Role
React 19 UI library
TypeScript 5.9 Strict typing
Vite 8 Bundler / dev server
Tailwind CSS v4 Styling (Vite plugin)
react-router-dom v7 SPA routing
TanStack Query v5 Server state / API cache
Zustand v5 Auth session state
axios — HTTP client with JWT interceptor
react-hook-form v7 Form management

Architecture Decisions

  • Async SQLAlchemy 2.0 + asyncpg — non-blocking DB operations handle concurrent booking requests without thread overhead
  • Pydantic v2 schemas — 2x faster validation vs v1; strict typing enforced across all API boundaries with zero Any types
  • TanStack Query v5 — server state per role with automatic cache invalidation; no redundant API calls across dashboards
  • APScheduler in-process — reminder jobs run inside uvicorn without Redis or Celery; ±15 min tolerance windows prevent duplicate sends
  • UUID type safety — JWT sub field explicitly cast to uuid.UUID before DB queries, preventing silent driver-level type coercion failures

Project Structure

barberos/ ├── backend/ │ ├── app/ │ │ ├── api/ │ │ │ └── routes/ # One router per domain (auth, admin, citas, horarios, pagos, inventario, public) │ │ ├── core/ │ │ │ ├── config.py # Environment variables via pydantic-settings │ │ │ └── security.py # JWT creation/verification + bcrypt hashing │ │ ├── db/ │ │ │ ├── database.py # Async engine + get_db dependency │ │ │ └── models/ # 12 SQLAlchemy models (one file per entity) │ │ ├── schemas/ # Pydantic v2 request/response schemas per domain │ │ ├── services/ # Business logic decoupled from HTTP layer │ │ └── main.py # FastAPI app, CORS middleware, router registration │ ├── alembic/ # Schema migration history │ ├── scripts/ │ │ └── seed.py # Demo data seeder (barbers, services, appointments) │ ├── tests/ │ │ ├── conftest.py # AsyncClient fixture with in-memory SQLite DB │ │ ├── test_auth.py # 6 HTTP tests — login flows and protected routes │ │ ├── test_citas.py # 5 HTTP tests — booking creation and validation │ │ ├── test_schemas.py # 11 unit tests — Pydantic schema validation │ │ ├── test_cita_service.py # Business rules — booking constraints and cancellation │ │ ├── test_pago_service.py # Commission calculations and payment rules │ │ └── test_security.py # JWT generation, hashing and token validation │ ├── .env.example │ └── requirements.txt │ └── frontend/ └── src/ ├── api/ # Axios instance + per-domain request functions ├── components/ # Shared components (layouts, route guards, UI) ├── pages/ │ ├── admin/ # AdminDashboard, AdminBarberos, AdminServicios, │ │ # AdminCitas, AdminHorarios, AdminPagos, AdminInventario │ ├── barbero/ # BarberoAgenda, BarberoGanancias, BarberoInventario │ └── public/ # HomePage, ReservarPage, CitaPage (3-step booking flow) ├── store/ # Zustand stores (authStore per role) ├── types/ # TypeScript interfaces mirroring backend schemas └── utils/ # Date/time helpers (Bogotá timezone)


Quick Start

Option A — Docker (recommended)

git clone https://github.com/dacq7/barberos-os.git
cd barberos-os
cp .env.example .env        # configure SECRET_KEY and RESEND_API_KEY
docker compose up --build -d
docker compose exec backend alembic upgrade head
docker compose exec backend python3 scripts/seed.py
# Frontend: http://localhost:3000
# Backend API: http://localhost:8000
# API Docs: http://localhost:8000/docs

Option B — Manual setup

Backend:

cd backend
python3 -m venv venv && source venv/bin/activate
pip install -r requirements.txt
cp .env.example .env        # configure your variables
alembic upgrade head
python3 scripts/seed.py
uvicorn app.main:app --reload
# API available at http://localhost:8000

Frontend:

cd frontend
npm install
npm run dev
# App available at http://localhost:5173

Environment Variables

Variable Description Example
DATABASE_URL PostgreSQL async connection string postgresql+asyncpg://user:pass@localhost:5432/barberos_db
SECRET_KEY JWT signing secret (use a strong random string) your-secret-key-here
ALGORITHM JWT algorithm HS256
ACCESS_TOKEN_EXPIRE_MINUTES Access token TTL in minutes 30
REFRESH_TOKEN_EXPIRE_DAYS Refresh token TTL in days 7
RESEND_API_KEY Resend API key for transactional emails re_your_key_here
ALLOWED_ORIGINS_STR Comma-separated list of allowed CORS origins https://your-frontend.vercel.app
BASE_URL Frontend base URL (used in email links) https://your-frontend.vercel.app

Data Model

12 entities: admins · barberos · servicios · barbero_servicios · horarios · barbero_bloqueos · bloqueos_generales · clientes · citas · pagos · inventario · inventario_alertas

Key business rules:

  • Minimum booking: 30 minutes in advance — maximum: 1 month ahead
  • Client cancellation deadline: 1 hour before appointment
  • Client rescheduling deadline: 30 minutes before appointment
  • Commission split: 40% barber / 60% barbershop per completed service
  • Email reminders: dispatched at 24h and 2h windows with ±15 min polling tolerance to prevent duplicates
  • Appointment statuses: pending → confirmed → completed / cancelled / no_show

Running Tests

cd backend
source venv/bin/activate
pytest tests/ -v

Expected output: tests/test_auth.py::test_login_barbero_valido PASSED tests/test_auth.py::test_login_password_incorrecta PASSED tests/test_auth.py::test_login_usuario_inexistente PASSED tests/test_auth.py::test_login_admin_valido PASSED tests/test_auth.py::test_ruta_protegida_con_token PASSED tests/test_auth.py::test_ruta_protegida_sin_token PASSED tests/test_citas.py::test_crear_cita_datos_completos PASSED tests/test_citas.py::test_crear_cita_datos_incompletos PASSED tests/test_citas.py::test_listar_citas_admin PASSED tests/test_citas.py::test_crear_cita_fecha_invalida PASSED tests/test_citas.py::test_crear_cita_sin_horario PASSED tests/test_schemas.py::test_login_schema_email_valido PASSED tests/test_schemas.py::test_login_schema_email_invalido PASSED tests/test_schemas.py::test_cita_schema_completo PASSED tests/test_schemas.py::test_cita_schema_sin_campos_requeridos PASSED tests/test_schemas.py::test_barbero_schema_valido PASSED tests/test_schemas.py::test_barbero_schema_email_invalido PASSED tests/test_schemas.py::test_horario_schema_valido PASSED tests/test_schemas.py::test_inventario_schema_stock_negativo PASSED tests/test_schemas.py::test_pago_schema_valido PASSED tests/test_schemas.py::test_servicio_schema_precio_negativo PASSED tests/test_cita_service.py::test_crear_cita_falla_fecha_menos_30_min PASSED tests/test_cita_service.py::test_crear_cita_falla_slot_no_disponible PASSED tests/test_cita_service.py::test_cancelar_cita_cambia_estado PASSED tests/test_cita_service.py::test_cancelar_cita_falla_si_ya_cancelada PASSED tests/test_cita_service.py::test_cancelar_cita_falla_menos_de_1_hora PASSED tests/test_cita_service.py::test_cambiar_estado_cita_actualiza_correctamente PASSED tests/test_pago_service.py::test_registrar_pago_calcula_comisiones_correctamente PASSED tests/test_pago_service.py::test_registrar_pago_falla_si_cita_no_completada PASSED tests/test_pago_service.py::test_registrar_pago_falla_si_ya_existe_pago PASSED tests/test_pago_service.py::test_get_resumen_barbero_calcula_total_correcto PASSED tests/test_security.py::test_hash_password_difiere_del_texto_plano PASSED tests/test_security.py::test_verify_password_correcto PASSED tests/test_security.py::test_verify_password_incorrecto PASSED tests/test_security.py::test_create_access_token_genera_jwt_valido PASSED tests/test_security.py::test_create_refresh_token_incluye_type_refresh PASSED 37 passed in 3.75s


Author

Diego Alejandro Correa — Full-Stack Developer · Founder of Veridis Dev
Medellín, Colombia 🇨🇴


Built with FastAPI + React · Deployed on Railway & Vercel · © 2025 Veridis Dev

About

Barbershop management SaaS — online booking, schedules, commissions · React + FastAPI + PostgreSQL

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages