Skip to content

Event Manager is a lightweight, privacy-conscious application that allows users to create and manage various events.

Notifications You must be signed in to change notification settings

BUMETCS673/cs673f25a2project-cs673a2f25team5

Repository files navigation

Event Manager and Planner Project Overview

Modern social event discovery and hosting tools span a wide range from casual invite pages to full ticketing stacks. Many existing tools are either too heavy (enterprise ticketing) or too casual (single-use invite pages), and they often trade off privacy, discoverability, and simplicity. Our project aims to fill a middle ground: a lightweight, privacy-conscious event hosting and discovery website that makes it quick to create attractive event pages, manage RSVPs, and integrate with calendars — while remaining easy to extend. The purpose is to let organizers create event pages and guest lists quickly, let guests RSVP and share the event, and provide organizers lightweight analytics and collaboration tools for running events.

Project Structure / Architecture

The event manager app aims to help individuals and organizations manage and track their events. In order to do so, the team's proposed solution is a full stack application. The team plans to provide this service through a website connected to a backend REST API that provides the needed endpoints for the user to manage and RSVP to events, among other functionalities. The frontend is built using Next.js with TypeScript to deliver a responsive and user-friendly interface for event management. The backend will be composed of 3 main components: the REST API, the SQL database, and monitoring services. The REST API will provide all the functionality needed by the frontend through various endpoints to enable users to control their events. The SQL database will provide a storage solution for information within the application. Additionally, the application integrates Clerk authentication services to handle user management and security, while Prometheus monitoring ensures system reliability and performance tracking. Please see the figure below for a diagram of the full stack application's design.

Architecture Diagram

Frontend

Please go to the frontend readme for a detailed explanation of the frontend structure and guidelines followed by the event manager application.

Backend

Please go to the backend readme for a detailed explanation of the backend structure and guidelines followed by the event manager application.

Stripe payments (backend + frontend)

  • Endpoints: POST /payments/checkout-session creates a Stripe Checkout Session and stores the checkout id on a payments row. POST /payments/webhook processes Stripe webhooks (e.g., checkout.session.completed) to mark payments as succeeded. Refunds are not supported in this build.
  • Env vars (backend): set STRIPE_SECRET_KEY and STRIPE_WEBHOOK_SECRET in .env (backend container uses these). FRONTEND_BASE_URL is used to build the success/cancel redirect URLs.
  • Env vars (frontend): set NEXT_PUBLIC_BACKEND_URL/BACKEND_URL to point to the backend (defaults to http://localhost:8000 for tests). Clerk is still required for auth tokens.
  • Database: payments table tracks event_id, user_id, amount_usd, status, and Stripe ids (stripe_checkout_session_id, stripe_payment_intent_id).
  • Behavior: If a user already has a successful payment for an event, checkout is skipped and the frontend shows an “already paid” message instead of charging again.
  • Local testing: Use Stripe CLI or test keys; webhook secret is required for /payments/webhook. No live key should be committed—set via environment only.

📁 Overall Folder Structure

cs673f25a2project-cs673a2f25team5/
├── code/                                             # event manager code
│   ├── backend/                                      # event manager backend code
│   │   ├── app/                                      # fastapi app code
│   │   │   ├── db/                                   # code for the db layer of the app
│   │   │   │   ├── categories.py                     # database operations for categories
│   │   │   │   ├── db.py                             # database engine and metadata configuration
│   │   │   │   ├── events.py                         # database operations for events
│   │   │   │   ├── filters.py                        # filter operation models for database queries
│   │   │   │   └── users.py                          # database operations for users
│   │   │   ├── models/                               # code for the models used in the app
│   │   │   │   ├── attendees.py                      # pydantic models for event attendees
│   │   │   │   ├── events.py                         # pydantic models for events (EventCreate, EventRead, PaginatedEvents)
│   │   │   │   ├── exceptions.py                     # custom exception classes
│   │   │   │   ├── patch.py                          # pydantic models for PATCH operations
│   │   │   │   └── users.py                          # pydantic models for users (UserCreate, UserRead, PaginatedUsers)
│   │   │   ├── routes/                               # code for the routers (endpoints) of the app
│   │   │   │   ├── __init__.py                       # router initialization
│   │   │   │   ├── attendees.py                      # attendees endpoints (stub)
│   │   │   │   ├── db.py                             # database health check endpoint
│   │   │   │   ├── events.py                         # events endpoints (GET, POST, DELETE, PATCH)
│   │   │   │   └── users.py                          # users endpoints (GET, POST, DELETE, PATCH)
│   │   │   ├── service/                              # code for the actual service logic of the app endpoints
│   │   │   │   ├── __init__.py                       # service initialization
│   │   │   │   ├── events.py                         # business logic for events (validation, error handling)
│   │   │   │   ├── filter_helper.py                  # filter parsing and validation logic
│   │   │   │   └── users.py                          # business logic for users (validation, error handling)
│   │   │   ├── __init__.py                           # init file
│   │   │   ├── config.py                             # database url config and settings management
│   │   │   └── main.py                               # entry point for the fastapi app
│   │   ├── test/                                     # backend unit and integration (end to end) tests
│   │   │   ├── test_events_failure_cases.py          # failure test cases for events endpoints
│   │   │   ├── test_events_success_cases.py          # success test cases for events endpoints
│   │   │   ├── test_filter_helper_failure_cases.py   # failure test cases for filter helper
│   │   │   ├── test_filter_helper_success_cases.py   # success test cases for filter helper
│   │   │   ├── test_users_failure_cases.py           # failure test cases for users endpoints
│   │   │   └── test_users_success_cases.py           # success test cases for users endpoints
│   │   ├── .python-version                           # python version used for the backend
│   │   ├── backend-README.md                         # detailed backend documentation
│   │   ├── pyproject.toml                            # tool configurations (uv, pytest, ruff)
│   │   ├── requirements.txt                          # event manager backend dependencies
│   │   ├── requirements-test.txt                     # event manager backend test dependencies
│   │   ├── tox.ini                                   # tox environment definitions
│   │   └── uv.lock                                   # uv overall definitions
│   └── frontend/                                     # event manager frontend code
        ├── __mocks__/                                # jest file mocks
│       │   └── fileMock.js                           # jest file for mocks
│       ├── cypress/                                  # cypress end-to-end tests
│       │   ├── e2e/                                  # folder accessed by cypress for e2e
│       │   │   ├── event-detail.cy.ts                # e2e test for event page flow
│       │   │   └── smoke.cy.ts                       # e2e test for initial load
│       │   ├── fixtures/                             # static data file for mock network responses
│       │   │   └── example.json                      # autogenerated examples
│       │   └── support/                              # support files for cypress tests
│       │       ├── commands.ts                       # for implementing custom commands
│       │       └── e2e.ts                            # global configuration
│       ├── public/                                   # static assets
│       │   ├── file.svg                              # file icon asset
│       │   ├── globe.svg                             # globe icon asset
│       │   ├── next.svg                              # next.js logo
│       │   ├── vercel.svg                            # vercel logo
│       │   └── window.svg                            # window icon asset
│       ├── src/                                      # source code
│       │   ├── app/                                  # app Router pages (layout.tsx, page.tsx)
│       │   │   ├── api/                              # route for all api calls
│       │   │   │   └── webhooks/                     # route for access webhooks
│       │   │   │       └── clerk/                    # route for clerks webhook
│       │   │   │           └── route.ts              # typescript code to intercept webhook from clerk
│       │   │   ├── create-events/                    # route for create events page
│       │   │   │   └── page.tsx                      # page component for creating new events
│       │   │   ├── events/                           # route for events display pages
│       │   │   │   ├── [id]/                         # dynamic route for individual event details
│       │   │   │   │   └── page.tsx                  # page component for single event display
│       │   │   │   └── page.tsx                      # page component for events list display
│       │   │   ├── favicon.ico                       # site favicon icon
│       │   │   ├── globals.css                       # where global css variables can be declared and imports for tailwind
│       │   │   ├── layout.tsx                        # root layout component defining global styles
│       │   │   └── page.tsx                          # home page/landing page component
│       │   ├── component/                            # reusable React components
│       │   │   ├── events/                           # event-related components
│       │   │   │   └── CreateEventForm.tsx           # form component for event creation
│       │   │   ├── landing/                          # landing page components
│       │   │   │   ├── BenefitsSection.tsx           # benefits section component for landing page
│       │   │   │   ├── CallToActionSection.tsx       # CTA section component for landing page
│       │   │   │   ├── DemoShowcaseSection.tsx       # demo showcase component for landing page
│       │   │   │   ├── FeatureHighlightsSection.tsx  # feature highlight component for landing page
│       │   │   │   ├── Heading.tsx                   # section heading component
│       │   │   │   ├── HeroSection.tsx               # hero section component for landing page
│       │   │   │   ├── WorkflowStepsSection.tsx      # workflow steps component for landing page
│       │   │   │   └── landingData.ts                # data/constants for landing page sections
│       │   │   ├── map/                              # map-related components
│       │   │   │   ├── GeoCoder.module.css           # styles for geocoder component
│       │   │   │   └── getPublicMapboxToken.ts       # utility to retrieve Mapbox public token
│       │   │   └── ui/                               # ui components
│       │   │       └── Header.tsx                    # header component for page navigation
│       │   ├── helpers/                              # reusable helper functions
│       │   │   └── fetchTimeout.ts                   # timeout to avoid hanging requests
│       │   ├── services/                             # api service layer for backend communication
│       │   │   ├── config.ts                         # service configuration and API base URL
│       │   │   ├── events.ts                         # events API service functions
│       │   │   └── users.ts                          # users API service functions
│       │   └── middleware.ts                         # ran before req's (used for protected/public routes)
│       ├── tests/                                    # folder for all tests
│       │   ├── config.test.ts                        # tests for config file
│       │   ├── createEventSchema.test.ts             # tests for creating event schema
│       │   ├── events.test.ts                        # tests for events
│       │   ├── EventSearchField.test.tsx             # tests for searching events
│       │   ├── Header.test.tsx                       # tests for viewing header
│       │   ├── useEventsBrowserState.test.ts         # tests for events browser
│       │   └── users.test.ts                         # tests for users
│       ├── cypress.config.ts                         # cypress config
│       ├── eslint.config.mjs                         # configuration file for ESLint and prettier
│       ├── frontend-README.md                        # detailed frontend documentation
│       ├── jest.config.ts                            # jest config (unit tests)
│       ├── jest.setup.ts                             # jest DOM/test setup
│       ├── next.config.ts                            # next.js configuration with output: "standalone"
│       ├── package.json                              # metadata for the project
│       ├── package-lock.json                         # records the exact version of every package installed in node_modules
│       ├── postcss.config.mjs                        # defines how PostCSS should process CSS files
│       └── tsconfig.json                             # defines how the compiler should compile the project's TS files into JS
├── db/                                               # database setup (docker compose, schema, ...)
│   ├── init/                                         # files used to initialize the database as part of the docker compose up
│   │   ├── 01_add_extensions.sql                     # sql extensions that need to be added to postgresql
│   │   └── 02_event_manager_db_schema.sql            # event manager db schema to create all tables
│   ├── database-README.md                            # detailed database documentation
│   └── db-docker-compose.yaml                        # docker compose file to start the postgres and pgadmin container and needed volumes
├── docs/                                             # event manager plan, proposal, and design docs
│   ├── Diagrams/                                     # architecture and design diagrams
│   │   ├── Backend Architecture Diagram.png          # detailed backend architecture
│   │   ├── Backend Flow Diagram.png                  # backend request flow diagram
│   │   ├── Database ERD Diagram.png                  # database entity relationship diagram
│   │   └── Event Manager Overall Architecture.png    # overall system architecture
│   ├── CS673_Database_Schema_team4.pdf               # database schema documentation
│   ├── CS673_MeetingMinutes_team4.docx               # team meeting minutes
│   ├── CS673_ProgressReport_team4.xlsx               # project progress tracking
│   ├── CS673_SPPP_RiskManagement_team4.xlsx          # risk management plan
│   ├── CS673_SPPP_team4.docx                         # software project plan and proposal document
│   ├── CS673_SDD_team4.docx                          # software project design document
│   ├── CS673_STD_team4.docx                          # software project testing document
│   ├── CS673_presentation1_team.pptx                 # project iteration 1 presentation slides
│   └── CS673_presentation0_team.pptx                 # project iteration 0 presentation slides
├── .github/                                          # gitHub configuration
│   └── workflows/                                    # gitHub Actions CI/CD workflows
│       ├── backend-ci.yml                            # backend continuous integration (test, lint, security, docker)
│       └── frontend-ci.yml                           # frontend continuous integration (lint, format, docker)
├── .vscode/                                          # vs code workspace configuration
│   └── settings.json                                 # editor settings and preferences
├── .gitignore                                        # files or folders to be ignored by git
├── .gitleaks.toml                                    # gitleaks configuration (allowlist)
├── Dockerfile.backend                                # dockerfile with definitions to build the backend image
├── Dockerfile.frontend                               # dockerfile with definitions to build the frontend image
├── team.md                                           # team members brief introduction
└── README.md                                         # project documentation

Project Setup

🧰 Prerequisites

  • Node.js 20.x (Frontend)
  • npm (Frontend)
  • Python 3.11 (Backend)
  • uv (pip install uv) (Backend)
  • Docker (optional, for containerized runs)

Overall Quick Setup and Run

Local Without Docker Containers

Let's start by clarifying that when we mention without docker containers we mean that the frontend and backend won't be running in docker containers but that the database will be running in a docker container.

  1. Create an env file with the following env vars:
# Database Configuration
POSTGRES_USER="<your_postgres_username>"
POSTGRES_PASSWORD="<your_postgres_password>"
POSTGRES_PORT="<your_postgres_port>"
POSTGRES_HOST=localhost
POSTGRES_DB="<your_database_name>"

# Clerk Configuration
CLERK_SECRET_KEY="<your_secret_key>"
CLERK_WEBHOOK_SIGNING_SECRET="<your_webhook_secret>"
CLERK_JWKS_URL="<your_jwks_url>"
NEXT_PUBLIC_MAP_BOX_TOKEN="<your_publishable_token>"
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY="<your_publishable_key>"

# Docker Configuration
DOCKER_USERNAME=javi99est
IMAGE_TAG=latest

# Clerk Configuration
CLERK_ISSUER=<clerk_issuer_url>
CLERK_JWT_AUDIENCE=<front_end_url>
# Enable/disable OAuth verification
CLERK_AUTH_ENABLED=true

# Miscellaneous
BACKEND_URL="http://127.0.0.1:8000"
  1. Export the env vars in the env file:
export $(grep -v '^#' .env | xargs)
  1. Start the postgres instance with the event_manager database (from the root dir)
docker compose -f db/db-docker-compose.yaml --env-file .env up -d --wait
  1. Start the backend fastapi application (from the code/backend dir)
uv run uvicorn app.main:event_manager_app --reload
  1. Start the frontend next.js application (from the code/frontend dir)
npm ci        # install dependencies
npm run dev

Local With Docker Containers

  1. Create an env file with the following env vars:
# Database Configuration
POSTGRES_USER="<your_postgres_username>"
POSTGRES_PASSWORD="<your_postgres_password>"
POSTGRES_PORT="<your_postgres_port>"
POSTGRES_HOST=localhost
POSTGRES_DB="<your_database_name>"

# Clerk Configuration
CLERK_SECRET_KEY="<your_secret_key>"
CLERK_WEBHOOK_SIGNING_SECRET="<your_webhook_secret>"
CLERK_JWKS_URL="<your_jwks_url>"
NEXT_PUBLIC_MAP_BOX_TOKEN="<your_publishable_token>"
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY="<your_publishable_key>"

# Docker Configuration
DOCKER_USERNAME=javi99est
IMAGE_TAG=latest

# Clerk Configuration
CLERK_ISSUER=<clerk_issuer_url>
CLERK_JWT_AUDIENCE=<front_end_url>
# Enable/disable OAuth verification
CLERK_AUTH_ENABLED=true

# Miscellaneous
BACKEND_URL="http://backend:8000"
  1. Export the env vars in the env file:
export $(grep -v '^#' .env | xargs)
  1. Start the docker container with the postgres instance and event_manager database (from the root dir)
docker compose -f db/db-docker-compose.yaml --env-file .env up -d --wait
  1. Build the latest version of your backend image (from the root dir)
docker build -f Dockerfile.backend -t $DOCKER_USERNAME/event-manager-backend:$IMAGE_TAG .
  1. Build the latest version of your frontend image (from the root dir)
docker build -f Dockerfile.frontend \
  --build-arg NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=$NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY \
  -t $DOCKER_USERNAME/event-manager-frontend:$IMAGE_TAG .
  1. Modify env file with the following env var and export the env vars again:
POSTGRES_HOST="host.docker.internal"  # use this host to allow the backend container to access the database running on the host machine

export $(grep -v '^#' .env | xargs)
  1. Start the docker frontend and backend containers
docker compose -f docker-compose.dev.yaml up -d

Frontend Setup

This is a Next.js project bootstrapped with create-next-app.

cd code/frontend
npm ci
npm run dev                       # Starts Next.js (Turbopack) on http://localhost:3000
Scripts (from package.json):
dev – next dev --turbopack
build – next build --turbopack
start – next start
lint – eslint

Run Next.js Application locally

  1. Access the frontend directory
cd code/frontend
  1. Copy the sample environment file and replace the Clerk secrets with values from your project. Update BACKEND_URL to point at the FastAPI instance.

  2. Install dependencies

npm ci
  1. Run Next.js application
npm run dev
  1. Access Next.js application at http://127.0.0.1:3000

Run Next.js Application in a Docker Container

  1. Build the Docker image and supply the Clerk publishable key so the compiled assets embed the correct client-side configuration.
docker build -f Dockerfile.frontend -t event-manager-frontend:latest .
  1. Run docker container using the image that was just built
docker run --rm -it -p 3000:3000 \
  -e CLERK_SECRET_KEY="<your_secret_key>" \
  -e CLERK_WEBHOOK_SIGNING_SECRET="<your_webhook_secret>" \
  -e CLERK_JWKS_URL="<your_jwks_url>" \
  -e BACKEND_URL="http://backend:8000" \
  event-manager-frontend:latest
  1. Access Application at http://0.0.0.0:3000

Frontend Container (Next.js Standalone)

The frontend Dockerfile uses Next.js output: "standalone" to copy only the minimal server + dependencies produced by the build.


Next.js packs your production server and only the required modules into .next/standalone. This:

  • Shrinks container size (no dev deps or full node_modules tree),
  • Speeds up cold starts and deploys,
  • Keeps the runtime image minimal (great for CI/CD).

Testing

  • npm run test to run jest unit tests
  • npm run test:watch to watch as tests run
  • npm run cypress:open to open cypress Electron or chromium application
// ***********************************************
// This example commands.ts shows you how to
// create various custom commands and overwrite
// existing commands.
//
// For more comprehensive examples of custom
// commands please read more here:
// https://on.cypress.io/custom-commands
// ***********************************************
//
//
// -- This is a parent command --
// Cypress.Commands.add('login', (email, password) => { ... })
//
//
// -- This is a child command --
// Cypress.Commands.add('drag', { prevSubject: 'element'}, (subject, options) => { ... })
//
//
// -- This is a dual command --
// Cypress.Commands.add('dismiss', { prevSubject: 'optional'}, (subject, options) => { ... })
//
//
// -- This will overwrite an existing command --
// Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... })
//
// declare global {
//   namespace Cypress {
//     interface Chainable {
//       login(email: string, password: string): Chainable<void>
//       drag(subject: string, options?: Partial<TypeOptions>): Chainable<Element>
//       dismiss(subject: string, options?: Partial<TypeOptions>): Chainable<Element>
//       visit(originalFn: CommandOriginalFn, url: string, options: Partial<VisitOptions>): Chainable<Element>
//     }
//   }
// }

Backend Setup

A modern Python project setup using:

  • tox – for test, lint, and format automation
  • uv – for fast dependency installation and environment management
  • ruff – for linting and formatting

Run FastApi Application / REST Api Locally

  1. Access the backend directory
cd code/backend
  1. Run fastapi application
uv run uvicorn app.main:event_manager_app --reload
  1. Access REST Api at http://127.0.0.1:8000

  2. Access REST Api swagger docs at http://127.0.0.1:8000/docs


Run FastApi Application / REST Api in a Docker Container

  1. Build docker image using the Dockerfile.backend file
docker build -f Dockerfile.backend -t event-manager-backend:latest .
  1. Run docker container using the image that was just built
docker run --rm -it -p 8000:8000 event-manager-backend:latest
  1. Access REST Api at http://0.0.0.0:8000

  2. Access REST Api swagger docs at http://0.0.0.0:8000/docs


Run CI Tasks with Tox

Run tests

uv run tox -e test

Test coverage

uv run tox -e coverage

Test report

uv run tox -e report

Run Ruff linter

uv run tox -e lint

Check formatting with Ruff

uv run tox -e format

Manual Ruff Usage

If you want to run Ruff directly:

Format the code

uv run ruff format .

Fix lint issues

uv run ruff check --fix

Database Setup

This project uses PostgresSQL as both the local development and production database. Please see below the steps to locally run your own version of the event manager database.

Database Initialization Files

Database initialization and migrations are managed through SQL scripts located in the db/init/ directory of the repository. These files are executed during the database setup process, typically as part of the Docker Compose workflow, ensuring all required extensions and tables are created with the proper schema.

  • 01_add_extensions.sql
    Purpose: This script adds necessary PostgreSQL extensions that are required for the application. Extensions might include support for UUID generation, advanced indexing, or other features to optimize database performance and functionality.

  • 02_event_manager_db_schema.sql
    Purpose: This script defines the core schema for the Event Manager application. It creates all tables (Users, Events, Categories, EventAttendees), sets up primary and foreign key constraints, and establishes the relationships as outlined in the ERD. It ensures the database structure matches the application's data model and enforces referential integrity.

These initialization files ensure that the database environment is consistent and reproducible across development, staging, and production deployments. Any future additions to the init process like database constraints or indexes will be added in sequential files to ensure the init process for the event_manager database is robust and complete.


Database Docker Setup

To clarify, this section uses the DB-docker-compose.yaml file to create the container for the postgres instance which holds the event_manager database as well as the pgadmin container which runs a simple and easy to use web ui to connect to the postgres instance.

  1. Run the following command to export all env variables.
export POSTGRES_USER=test \
  POSTGRES_PASSWORD=test1234 \
  POSTGRES_PORT=5432 \
  POSTGRES_HOST=localhost \
  POSTGRES_DB=event_manager \
  [email protected] \
  PGADMIN_DEFAULT_PASSWORD=adminpass
  1. Run the following command to get the postgres and pgadmin containers running.
docker compose -f db/db-docker-compose.yaml --env-file .env up -d --wait
  1. Access pgadmin web ui at http://localhost:8080

  2. Run the following command when you are done with the database to remove the volumes and containers.

docker compose -f db/db-docker-compose.yaml down -v
  1. If you want to keep the volumes (persistent storage) and just want to stop the container please run the following command.
docker compose -f db/db-docker-compose.yaml down

Authentication Setup

Required environment variables

Set the following values in code/frontend/.env.local (or export them in your shell) and mirror them into your CI secrets:

  • NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY – public key for rendering Clerk widgets.
  • CLERK_SECRET_KEY – backend API key used by Next.js server components and the webhook handler.
  • CLERK_JWKS_URL – JWKS endpoint for token validation (Clerk dashboard → API Keys).
  • CLERK_WEBHOOK_SIGNING_SECRET – secret provided when you create the webhook endpoint inside Clerk.
  • BACKEND_URL – base URL for the FastAPI service that receives user sync requests. code/frontend/.env contains local development defaults. Copy it to .env.local and replace the secret values with keys from your Clerk project before running the app. .env.local is git-ignored—keep real secrets out of the repository.

Webhook flow

  • Clerk sends user.created events to POST /api/webhooks/clerk.
  • The handler verifies the signature with verifyWebhook using CLERK_WEBHOOK_SIGNING_SECRET and logs errors for invalid payloads.
  • Valid events trigger a POST to ${BACKEND_URL}/create-user/ with the user's name and primary email to keep the backend in sync.
  • Ensure your FastAPI service exposes this endpoint; the webhook responds with a 500 status if the sync call fails.

Route protection

code/frontend/src/middleware.ts uses clerkMiddleware to guard /discover and /onboarding while leaving /api/webhooks/clerk and static assets unauthenticated. The global layout (code/frontend/src/app/layout.tsx) renders sign-in/up buttons for unauthenticated visitors and a UserButton once signed in.


Stripe Payment Setup

Overview

Stripe is integrated into the backend to handle secure payment processing for event registrations.
The backend communicates with the Stripe API using the official Stripe SDK and supports the following flow:

  1. Create a Stripe Account:
    • Go to https://dashboard.stripe.com/register and sign up for a free Stripe account.
    • After login, go to Developers → API keys to get your Publishable key and Secret key.
    • Use your test keys (they start with pk_test_ and sk_test_) for development.
  2. User selects an event → initiates checkout.
  3. Backend creates a Stripe Checkout Session.
  4. Stripe redirects user to hosted payment page.
  5. Stripe sends webhook events (e.g. checkout.session.completed) to the backend for payment confirmation.
  6. Payment details are stored in the payments table.

Required environment variables

Add the following to your root .env (and mirror into your CI secrets if needed). These are used by the backend FastAPI service.

STRIPE_SECRET_KEY=sk_test_********************************
STRIPE_WEBHOOK_SECRET=whsec_********************************
APP_BASE_URL=http://127.0.0.1:8010
FRONTEND_BASE_URL=http://localhost:3000
  1. Run the following command to export all env variables.
export POSTGRES_USER=test
POSTGRES_PASSWORD=test1234
POSTGRES_PORT=5432
POSTGRES_HOST=localhost
POSTGRES_DB=event_manager
[email protected]
PGADMIN_DEFAULT_PASSWORD=adminpass
STRIPE_SECRET_KEY=sk_test_********************************
STRIPE_WEBHOOK_SECRET=whsec_********************************
APP_BASE_URL=http://127.0.0.1:8010
FRONTEND_BASE_URL=http://localhost:3000

Stripe SDK & CLI Installation

Install Stripe Python SDK

The Stripe SDK enables your FastAPI backend to create checkout sessions and verify webhooks.

uv pip install stripe

Alternatively:

pip install stripe

Install Stripe CLI

The Stripe CLI securely forwards webhooks from Stripe’s cloud to your local backend.

Windows (system-wide):-

winget install Stripe.StripeCLI

Stripe CLI Setup

Login to Stripe

Authenticate your CLI with your Stripe account:

stripe login

This opens a browser window to confirm access and link your local CLI.

Start the Webhook Listener

Forward live events from Stripe → your local FastAPI backend:

stripe listen --forward-to http://127.0.0.1:8010/payments/webhook

You’ll see an output like:

Ready! Your webhook signing secret is whsec_XXXXXXXX

Copy this whsec_XXXXXXXX value into your .env file as:

STRIPE_WEBHOOK_SECRET=whsec_XXXXXXXX

Then restart your backend so it loads the new secret.

Ready to test payments and webhooks locally!

GitHub Actions secrets

.github/workflows/frontend-ci.yml now pulls Clerk secrets during the check and docker jobs. Populate the following repository secrets so CI can build and publish the frontend image:

  • CLERK_JWKS_URL
  • CLERK_SECRET_KEY
  • CLERK_WEBHOOK_SIGNING_SECRET
  • NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY

Backend Authentication Guide

The Event Manager API uses Clerk for authentication. All API endpoints (except health checks and metrics) require a valid Clerk OAuth token in the Authorization header.


Authentication Flow

  1. Frontend: User logs in with Clerk OAuth (handled by your frontend)
  2. Frontend: Receives a JWT token from Clerk
  3. Frontend: Includes token in API requests: Authorization: Bearer <token>
  4. Backend: Verifies token with Clerk's public keys
  5. Backend: Extracts user information and processes request

Configuration

Environment Variables

Add these to your .env file:

# Clerk Configuration
CLERK_ISSUER=<clerk_issuer_url>
CLERK_JWT_AUDIENCE=<front_end_url>

Development Mode

For local development without Google OAuth:

CLERK_AUTH_ENABLED=false

When disabled, the API accepts all requests with a mock development user.


Error Responses

401 Unauthorized
{
  "detail": "Not authenticated"
}

Occurs when:

  • No Authorization header provided
  • Invalid token format
  • Token has expired
  • Token signature verification fails

503 Service Unavailable
{
  "detail": "Authentication service unavailable"
}

Occurs when:

  • Cannot reach Google's authentication servers
  • Network issues

Security Considerations

  1. Token Validation: Every request validates the token signature with Clerk's public keys
  2. Email Verification: Only tokens with verified emails are accepted
  3. Audience Check: Tokens must be issued for your specific Clerk
  4. Issuer Check: Tokens must come from Clerk's issuer
  5. HTTPS: Always use HTTPS in production to prevent token interception

Testing

Authentication is disabled in tests by default


Troubleshooting

"Not authenticated" error
  • Check that Authorization header is present
  • Verify token format: Bearer <token>
  • Ensure token hasn't expired (Google tokens typically last 1 hour)

"Authentication service unavailable" error
  • Check internet connectivity
  • Verify Google's authentication services are operational
  • Check firewall/proxy settings

Frontend Integration (Clerk Example)

If using Clerk for Google OAuth:

import { useAuth } from "@clerk/nextjs";

export function useApiRequest() {
  const { getToken } = useAuth();

  async function apiRequest(endpoint: string, options: RequestInit = {}) {
    const token = await getToken();

    return fetch(`http://localhost:8000${endpoint}`, {
      ...options,
      headers: {
        ...options.headers,
        Authorization: `Bearer ${token}`,
      },
    });
  }

  return { apiRequest };
}

Security Setup

Python Dependency Audit (pip-audit)

pip install pip-audit
cd code/backend
pip-audit -r requirements.txt
pip-audit -r requirements-test.txt

Semgrep Scan

pip install semgrep
semgrep --version
# Scan backend
semgrep --config p/python code/backend
# Scan Frontend
semgrep --config p/react code/frontend
# Full Project Scan
semgrep ci --config auto

Secret Scanning (Gitleaks)

This repo uses Gitleaks to stop secrets (API keys, tokens, etc.) from landing in the codebase.

  • Where it runs: part of the GitHub Actions workflow in '.github/workflows/backend-ci.yml'
  • Config: '.gitleaks.toml' (reduces false positives by ignoring docs/caches and obvious dummy tokens)
  • Output: results are uploaded to Security → Code scanning alerts and PRs get inline annotations
  • Permissions: the workflow grants 'security-events: write' to upload SARIF; it uses the auto-provided 'secrets.GITHUB_TOKEN'

Setup

  1. Add repo secret 'GITLEAKS_LICENSE_KEY' (Repo → Settings → Secrets and variables → Actions).
  2. Keep '.gitleaks.toml' at repo root so the scanner picks it up.

Useful Links

About

Event Manager is a lightweight, privacy-conscious application that allows users to create and manage various events.

Resources

Stars

Watchers

Forks

Packages

No packages published

Contributors 8