From 80bb54beee8f0f49200089cfc81dd7a8986d4e05 Mon Sep 17 00:00:00 2001 From: Cliff Hill Date: Thu, 4 Sep 2025 10:47:45 -0400 Subject: [PATCH] Cleaning up the readme some more. Signed-off-by: Cliff Hill --- README.md | 289 ++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 235 insertions(+), 54 deletions(-) diff --git a/README.md b/README.md index 4ffb1f70..2a32d08d 100644 --- a/README.md +++ b/README.md @@ -6,15 +6,6 @@ This is a full-stack application simulating an online booking system for confere --- -## Project Overview - -This project is a full-stack conference room booking system, designed for clarity, modularity, and ease of local development. It consists of: - -- **Backend:** Python 3.13, FastAPI, SQLAlchemy, asyncpg, modular structure, dataclass-based models, and robust testing with Nox and Pytest. -- **Frontend:** React, TypeScript, Material-UI, centralized logging, and a clean separation of components and pages. -- **Database:** PostgreSQL, with a normalized schema for users, rooms, bookings, and invitees. -- **Containerization:** Docker Compose for both production and development, with hot-reload and volume mounts for rapid iteration. - ## Design Decisions - **Backend:** @@ -34,16 +25,6 @@ This project is a full-stack conference room booking system, designed for clarit --- -### Backend decisions - -I decided to push to Python 3.13, because there are always language improvements as they are advanced, some of them help make the code more readable (like the use of pipe syntax for type hinting) others are the improved error messages and better interactive interpreter in 3.13, both of which help with debugging. - -The structure I picked for the backend is what I have found from research to be the preferred way to structure the code. When a file gets too large, I split it into multiple files under a subdirectory - like with services, where it simply was unweildly to manage. - -### Frontend Decisions - -I wanted clear, concise separations of concerns whenever possible. I believe that components should be separated out and then pages should combine whatever components they have. I believe that tests should be made, but not directly in the paths of the code, cluttering up the directories. The more minimal I can make things, the better because there is less maintenence required then. - ### Security concerns There is no login or security in place with this project. However if set up with zero trust, an example scenario could use OpenID or similar login security, encrypted JWTs, secure connections could be established to the database as well as all traffic being moved to https rather than http, locking everything down to ensure that those who communicate with any part of this system are authenticated and have only the access that they are authorized. Each endpoint would need to be able to check that the user is authenticated and has a valid token that has not expired in order to be used. @@ -65,6 +46,158 @@ I used AI to stub out a couple of files: - 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. - 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. + +## 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 +# or run only unit tests: +nox --session=tests +``` + +**Frontend tests:** + +```bash +cd frontend +yarn test +``` + +--- + +**Tip:** + +- You can run backend and frontend tests locally (see below for details). +- You can connect to the database using `psql` with the credentials in your `.env` file. + +--- + +This project is a full-stack conference room booking system, designed for clarity, modularity, and ease of local development. It consists of: +This will start the backend (port 8000), frontend (port 3000), and Postgres (port 5432) with hot-reload enabled for rapid development. + +**Development mode exposes:** + +- Frontend: http://localhost:3000 +- Backend (API & docs): http://localhost:8000 (OpenAPI docs at http://localhost:8000/docs) +- PostgreSQL: localhost:5432 (see below to connect) + +**Connect to the database with psql:** + +```bash +psql -h localhost -U -d +# Example (using defaults): +psql -h localhost -U user -d mydb +``` + +Password is in your `.env` file. + +--- + +## Production Environment Setup + +To run the application in production mode (optimized containers, only frontend exposed): + +From the project root: + +```bash +docker compose up +``` + +**Production mode exposes:** + +- Frontend: http://localhost:3000 +- Backend and database are NOT exposed outside the Docker network. + +--- + +### API Documentation (Backend) + +To build the backend API documentation (OpenAPI/Swagger UI): + +```bash +cd backend +nox +``` + +This will run all tests and also build the API docs. + +**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/build/api-docs/` relative to the project root. + +--- + +- **Backend:** Python 3.13, FastAPI, SQLAlchemy, asyncpg, modular structure, dataclass-based models, and robust testing with Nox and Pytest. +- **Frontend:** React, TypeScript, Material-UI, centralized logging, and a clean separation of components and pages. +- **Database:** PostgreSQL, with a normalized schema for users, rooms, bookings, and invitees. +- **Containerization:** Docker Compose for both production and development, with hot-reload and volume mounts for rapid iteration. ### Running for production @@ -81,12 +214,13 @@ In this mode, only one port is exposed in docker - the port 3000, which is the f ## Local Development & Setup 1. **Clone the repository** + 2. **Copy environment variables file** - Copy the provided example file: - ```bash - cp .env.example .env + ```bash + cp .env.example .env - ``` + ``` 3. **Start in development mode:** @@ -94,23 +228,52 @@ In this mode, only one port is exposed in docker - the port 3000, which is the f docker compose -f compose.dev.yml up ``` + The port configuration is in the `.env` file. The defaults would have: + - Frontend: [http://localhost:3000](http://localhost:3000) - Backend: [http://localhost:8000/docs](http://localhost:8000/docs) - Postgres: localhost:5432 - Hot-reload enabled for both frontend and backend. - 5. **Install backend dependencies (for local development outside Docker):** + 1. **Install backend dependencies (for local development outside Docker):** + ```bash cd backend poetry install ``` + - This will set up a virtual environment and install all required packages for the backend. + 2. **Get `pre-commit` configured:** + + ```bash + pre-commit install + ``` + + 3. **Connecting to the Database During Development:** + + When running with `compose.dev.yml`, the database is exposed on port 5432. You can connect + using `psql`: + + ```bash + psql -h -U -d + ``` + + Using the defaults, that would be: + + ```bash + psql -h localhost -U user -d mydb + ``` + + Enter the password when prompted (see your `.env` file). + 4. **Production mode:** + ```bash docker compose up ``` - - Only frontend port 3000 is exposed. + + - Only frontend port (default 3000) is exposed. --- @@ -139,19 +302,26 @@ The project was implemented with testing in the forefront. Tests can be run from the `nox` command in the root backend directory. This will validate the backend with a wide range of tools, to ensure that everything is correct. - Run all tests and checks: + ```bash cd backend nox ``` + - List available sessions: + ```bash nox --list-sessions ``` + - Run a specific session (e.g., unit tests): + ```bash nox --session=tests ``` + - Install pre-commit hooks: + ```bash pre-commit install ``` @@ -196,18 +366,6 @@ graph TD --- -#### Connecting to the Database During Development - -When running with `compose.dev.yml`, the database is exposed on port 5432. You can connect using `psql`: - -```bash -psql -h localhost -U user -d mydb -``` - -Enter the password when prompted (see your `.env` file, default is `password`). - ---- - #### Database Schema Diagram ```mermaid @@ -266,23 +424,46 @@ graph TD ```mermaid 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 Model - participant Database + 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 - FastAPI_Router->>API_Endpoint: Matches Route - API_Endpoint->>Pydantic_Schema: Validate Input - Pydantic_Schema-->>API_Endpoint: Validated Data - API_Endpoint->>Service_Layer: Pass Validated Data - Service_Layer->>Model: Apply Business Logic - Model->>Database: Perform DB Operations - Database-->>Model: Return Query Result - Model-->>Service_Layer: Return Processed Data - Service_Layer-->>API_Endpoint: Return Response Data - API_Endpoint-->>Frontend: HTTP Response + Frontend->>FastAPI_Router: HTTP Request (REST) + FastAPI_Router->>API_Endpoint: Route Match + API_Endpoint->>Pydantic_Schema: Validate & Parse Input + 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) +``` + +--- + +#### SSE Update Flow (Real-Time Room Availability) + +```mermaid +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: ...) + end + Frontend-->>SSE_Endpoint: Disconnect (close EventSource) + SSE_Endpoint-->>Event_Generator: Cleanup Subscriber ```