# Online Booking Application ## Cliff Hill's Coding Project This is a full-stack application simulating an online booking system for conference rooms. --- ## Design Decisions ### React Contexts for State Management - Global state for rooms, bookings, and users via context providers. - Real-time updates using SSE in context. ### Modular Component Architecture - Reusable, focused components (e.g., BookingForm, RoomList, RoomSelect, CalendarView). - Shared UI logic abstracted into dedicated components. ### TypeScript for Safety and Documentation - Strong typing for all props, state, and data models. - Centralized type/interface definitions. ### Unified Color and Style Logic - Room/event colors assigned by room id modulo, using CSS custom properties. - Consistent visual theming across lists, dropdowns, and calendar. ### Separation of Concerns - Business logic and API calls abstracted into helpers and service modules. - Thin UI components focused on rendering and interaction. ### Robust Error Handling and Validation - Field-level validation and user-friendly error messages in forms. - Backend errors formatted for clarity. ### Centralized Logging - Logging utility used throughout frontend and backend for analytics and debugging. - Key actions and lifecycle events are logged. ### JSDoc and Docstrings for Documentation - File-level and component-level documentation in both frontend and backend. - TypeScript interfaces and Python models are documented. ### React Router for Navigation - Page routing and programmatic navigation after booking actions. ### Accessibility and User Experience - Disabled states, error messages, and skeleton loaders for better UX. - Visual distinction for selected/unavailable rooms. ### FastAPI Backend with SQLAlchemy ORM - Async API endpoints grouped by resource (rooms, bookings, users). - Database models with relationships and constraints. ### Pydantic Schemas for Validation - Separate schemas for create, update, and response objects. ### Service Layer Abstraction in Backend - Business logic separated from HTTP routing. ### Testing and Code Quality - Pytest, coverage, pre-commit hooks, and code style enforcement for backend; run `pytest` from the backend folder. - Jest and React Testing Library, code style enforcement and additional pre-commit hooks for frontend; run `yarn run jest` from the frontend folder. - All tests can be run from the`nox` command in the root directory, or for tests specific to each part of the project, run `nox` in either `frontend` or `backend` respectively. - `nox` frontend tests include: `pre-commit`, `coverage`, `audit`, `storybook`, and `jest`. - `nox` backend tests include: `pre-commit`, `safety`, `mypy`, `tests`, `typeguard`, `xdoctest`, and `docs-build`. `nox` could very easily be integrated into a CICD pipeline for full validation of the code to be done before anything could be merged into `main`. ### Docker Compose for Orchestration - Multi-service setup: backend (FastAPI), frontend (React), and Postgres database. - Custom network, healthchecks, and persistent volumes. - Environment variables managed via .env files. ### Extensibility and Maintainability - Modular design for easy feature addition and refactoring. - Generated from Hypermodern Python Cookiecutter for best practices. ### AI Use I used AI to stub out a couple of files: - I use primarily copilot inside my VSCode. This was done through conversations I had with the AI about the state of the code, and ways to improve things, or for setting up documentation, etc as I explain below. - Any use is extremely caveated by me needing to adjust and correct what was conceieved by the AI, as it is a helpful tool, but often gets little details incorrect. - The Dockerfile.backend and Dockerfile.frontend - to speed up the process of getting docker loaded efficiently for the project. - The compose.yml file - getting the different images gathered together quickly. - The compose.dev.yml file - used to get a further understanding of how to hook up an extension to the previous file. - The mermaid diagrams used in this file. - I have the CodeGPT plugin in VSCode, and it has helped with docstrings, logging messages, and sometimes reducing the time it takes me to write out the code. - I used AI to rapidly set up tests for each users component (router, service), then adapted it to the others independently. I believe AI is great for getting reasonable tests written quickly, and then I simply refined it, and replicated the kinds of tests across the different components. - I was experimenting with some AI edits for debugging the tests. - My frontend skills are less polished than my backend skills. I've been using AI along the lines of how I would use StackOverflow, answering questions to help me get the code written. - AI was very helpful in getting the frontend to do what I wanted quickly. - I used AI to help clean up and better structure the CSS for the frontend project, as well as get some code documentation in place. - AI was used to refactor code a few times to make it cleaner and better organized. - AI was used for debugging the tests to quickly correct them, for frontend and backend. --- ## Documentation & Storybook ### Backend API Documentation To build and view the backend API documentation: 1. Navigate to the backend directory: ```bash cd backend ``` 2. Run the Nox docs session (live-reloading server): ```bash nox -s docs ``` This will build and serve the docs with live reloading. Your browser should open automatically to the docs at: [http://localhost:8000/docs](http://localhost:8000/docs) **Alternative (static build):** If you want to build the static HTML docs only: ```bash cd backend nox -s docs-build xdg-open docs/_build/index.html # Linux open docs/_build/index.html # macOS start docs/_build/index.html # Windows ``` Or manually open `docs/_build/index.html` in your browser. ### Frontend Storybook To run Storybook for the frontend using Nox: 1. Navigate to the frontend directory: ```bash cd frontend ``` 2. Run the Nox storybook session: ```bash nox -s storybook ``` This will start Storybook and open your browser to: [http://localhost:6006](http://localhost:6006) **Alternative (static build):** If you want to build the static Storybook docs only: ```bash cd frontend nox -s storybook-build xdg-open storybook-static/index.html # Linux open storybook-static/index.html # macOS start storybook-static/index.html # Windows ``` Or manually open `storybook-static/index.html` in your browser. --- ## Development Environment Setup Follow these steps to get your local development environment running: ### 1. Clone the repository You can use either HTTPS or SSH: **HTTPS:** ```bash git clone https://github.com/xlorepdarkhelm/numinar-coding-project.git cd numinar-coding-project ``` **SSH:** ```bash git clone git@github.com:xlorepdarkhelm/numinar-coding-project.git cd numinar-coding-project ``` ### 2. Copy environment variables ```bash cp .env.example .env # Or, if present: cp .env.sample .env ``` ### 3. Install backend dependencies ```bash cd backend poetry install ``` ### 4. Set up pre-commit hooks (recommended) ```bash pre-commit install ``` ### 5. Install frontend dependencies ```bash cd ../frontend yarn install ``` ### 6. Start Docker Compose in development mode (in a separate terminal) From the project root: ```bash docker compose -f compose.dev.yml up ``` This will start the backend (port 8000), frontend (port 3000), and Postgres (port 5432) with hot-reload enabled for rapid development. ### 7. Run tests (backend & frontend) #### Backend tests ```bash cd backend nox # Run all tests and checks (also builds API docs) # or run only unit tests: nox --session=tests ``` ##### API Documentation - The `nox` command above will also build the backend API documentation. - **View the API docs in development mode:** Open [http://localhost:8000/docs](http://localhost:8000/docs) in your browser (when running dev Docker Compose). - **Generated static docs (after running nox):** See `backend/docs/build/index.html` relative to the project root. #### Frontend tests ```bash cd frontend nox # or run only nox tests: nox --session=jest ``` #### All tests from the project root ```bash nox ``` Note - you can use any of the sessions from frontend or backend here to isolate just that test. ## Nox and Pre-commit Integration This project uses [Nox](https://nox.thea.codes/) for orchestrating development, testing, and code quality sessions across both frontend and backend. Pre-commit hooks are managed via [pre-commit](https://pre-commit.com/) and are integrated into the Nox workflow for consistent linting and formatting. - **Nox sessions** are defined in both the project root and in the `frontend` and `backend` directories. You can run all sessions from the root, or target frontend/backend specifically. - **Pre-commit** is run as a Nox session (`nox -s pre-commit`) and also as a git hook. Both use pinned tool versions and shared config files for consistency. - **Typical usage:** - Run all checks: `nox` (from root) - Run only frontend checks: `cd frontend && nox` - Run only backend checks: `cd backend && nox` - Run pre-commit manually: `nox -s pre-commit` or `pre-commit run --all-files` ## Troubleshooting & FAQ **Q: Why does isort or black change files differently in Nox vs pre-commit?** A: Make sure both Nox and pre-commit are using the same pinned tool versions and config files. See `.isort.cfg` and `.pre-commit-config.yaml` for details. **Q: Why does Storybook open the browser or not exit when run in CI/Nox?** A: Use `yarn build-storybook` for static builds (exits automatically). For dev server, use `yarn storybook dev --ci` to prevent browser opening. **Q: Why do pre-commit hooks modify files after a commit or behave differently in CI?** A: Pre-commit runs in its own environment. Always run `pre-commit run --all-files` locally to reproduce CI behavior. Ensure your config files are up to date and tool versions are pinned. **Q: How do I run only frontend or backend tests?** A: Use Nox in the respective directory (`cd frontend && nox`, `cd backend && nox`). **Q: How do I fix environment or dependency issues?** A: Delete `.venv` or `node_modules` and reinstall dependencies (`poetry install` for backend, `yarn install` for frontend). Check for version mismatches in config files. **Q: Where are config files for formatting and type checking?** A: See `.isort.cfg`, `.coveragerc`, and `mypy.ini` in the project root. These are derived from backend settings for consistency. --- ## Diagrams ### Docker Compose Components ```mermaid %% Docker Compose Architecture graph TD subgraph docker_network B[Frontend
Port: 3000] C[Backend
Port: 8000] D[PostgreSQL
Port: 5432] C -- "SQL: 5432" --> D end Client[Client] -- "HTTP: 3000" --> B Client -- "HTTP/REST: 8000" --> C ``` --- ### Database Schema Diagram ```mermaid %% Database Schema with Types and Keys classDiagram class User { string email [PK] string name } class Room { int id [PK] string name string location string equipment int capacity } class Booking { int id [PK] int room_id [FK] datetime start_time datetime end_time string title } class Invitee { int id [PK] int booking_id [FK] string user_email [FK] } User "1" <|-- "*" Invitee : user_email [FK] Room "1" <|-- "*" Booking : room_id [FK] Booking "1" <|-- "*" Invitee : booking_id [FK] ``` --- ### Component Diagram ```mermaid %% Component Relationships and Data Flow graph TD subgraph Frontend F1[Pages] --> F2[Components] F2 --> F3[API Calls] end subgraph Backend B1[FastAPI Routers] --> B2[Pydantic Schemas] B1 --> B3[Service Layer] B3 --> B4[SQLAlchemy Models] B4 --> B5[PostgreSQL] end F3 -- REST --> B1 B5 -.->|External| PG[PostgreSQL Service] ``` --- ### Backend Request Data Path ```mermaid %% Backend Request Data Path with Error Handling sequenceDiagram participant Frontend participant FastAPI_Router as FastAPI Router participant API_Endpoint as API Endpoint participant Pydantic_Schema as Pydantic Schema participant Service_Layer as Service Layer participant DB_Model as DB Model participant Database Frontend->>FastAPI_Router: HTTP Request (REST) FastAPI_Router->>API_Endpoint: Route Match API_Endpoint->>Pydantic_Schema: Validate & Parse Input alt Validation Error Pydantic_Schema-->>Frontend: HTTP 422 Unprocessable Entity else Validated Pydantic_Schema-->>API_Endpoint: Validated Data API_Endpoint->>Service_Layer: Pass Data Service_Layer->>DB_Model: Business Logic DB_Model->>Database: DB Query/Update Database-->>DB_Model: Query Result DB_Model-->>Service_Layer: Data Service_Layer-->>API_Endpoint: Response Data API_Endpoint-->>Frontend: HTTP Response (JSON) end ``` --- ### SSE Update Flow ```mermaid %% SSE Update Flow with Event Types sequenceDiagram participant Frontend participant FastAPI_Router as FastAPI Router participant SSE_Endpoint as SSE Endpoint participant Event_Generator as Event Generator participant Publisher as Publisher Frontend->>SSE_Endpoint: Open EventSource /availability/stream SSE_Endpoint->>Event_Generator: Start Async Event Loop loop While Connected Event_Generator->>Publisher: Wait for Event or Timeout Publisher-->>Event_Generator: Room Availability Event | Keep-Alive Event_Generator-->>Frontend: Send SSE Event (data: {type: "availability" | "keep-alive"}) note over Publisher,Frontend: Trigger: Booking created/updated/deleted end Frontend-->>SSE_Endpoint: Disconnect (close EventSource) SSE_Endpoint-->>Event_Generator: Cleanup Subscriber ``` ---