curo1305 8ac1d8223b Use venv inside pre-commit container instead of pip --user
Creates /tmp/venv inside the ephemeral container, installs bandit there,
and runs the security check via the venv's Python. No --user installs,
no script-location warnings, no writes outside the container's /tmp.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-13 23:08:02 +02:00

destroying_sap

A fullstack SaaS web application built with FastAPI, React, and PostgreSQL.

Stack

Layer Tech
Backend FastAPI (async), SQLAlchemy 2, Alembic, PostgreSQL 16
Auth JWT bearer tokens, bcrypt password hashing
Frontend React 18, TypeScript, Vite, React Router v6, TanStack Query

Current State

  • User registration and login (JWT auth)
  • Protected dashboard with nav bar (Dashboard | Profile | Logout)
  • /api/users/me — authenticated user info
  • /api/profile/me — GET/PUT personal profile (position, phone, date of birth, address)
  • Profile data stored in a dedicated profiles table; auto-created on first access
  • Admin role flag (is_superuser) stored in users table; exposed as is_admin in API (false for regular users, true for admins)
  • Admin-only user management at /admin: list all users, add users, delete users, toggle active status
  • All input sanitized before reaching the DB (null-byte rejection, length caps, format validation)
  • 3 separate Docker containers: db (PostgreSQL), backend (FastAPI), frontend (nginx)
  • All containers run as non-root users (UID 1001 for backend and frontend, UID 70 for db)
  • Dev environment seeds a test user automatically on startup (test@example.com / Test123!)
  • Password policy: min 8 chars, upper + lowercase, digit, special character, no common words
  • Pre-commit security hook (scripts/security_check.py) runs inside Docker on every commit

Containers

Container Image Port User (UID:GID) Description
db postgres:16-alpine 5432 70:70 (postgres) PostgreSQL database
backend custom (python:3.12-slim) 8000 1001:1001 (appuser) FastAPI management API
frontend custom (nginxinc/nginx-unprivileged:alpine) 80 1001:1001 (appuser) React UI served by nginx (internal port 8080)

The frontend nginx container proxies /api/* to the backend container internally — no CORS headers needed in production.

Installation

Prerequisites

  • Docker + Docker Compose

Production

git clone <repo>
cd destroying_sap
cp .env.example backend/.env   # edit SECRET_KEY at minimum
docker compose up --build -d

Development (hot reload)

docker compose -f docker-compose.yml -f docker-compose.dev.yml up --build

Local (no Docker)

1. Start PostgreSQL

docker compose up db -d

2. Backend

cd backend
python -m venv .venv && source .venv/bin/activate   # Windows: .venv\Scripts\activate
pip install -e ".[dev]"
cp ../.env.example .env
alembic upgrade head
uvicorn app.main:app --reload

3. Frontend

cd frontend && npm install && npm run dev

Environment Variables

Copy .env.example to backend/.env and adjust:

Variable Default Description
DATABASE_URL postgresql+asyncpg://postgres:password@localhost:5432/destroying_sap Async PostgreSQL URL
SECRET_KEY change-me-in-production JWT signing key
CORS_ORIGINS ["http://localhost:5173"] Allowed frontend origins

Development

# Backend lint + format
cd backend && ruff check . && ruff format .

# Backend tests
cd backend && pytest

# Frontend type check + lint
cd frontend && npm run typecheck && npm run lint

# New DB migration (after changing models)
cd backend && alembic revision --autogenerate -m "describe change"
cd backend && alembic upgrade head
S
Description
No description provided
Readme 1.4 MiB
Languages
Python 53.2%
TypeScript 44.1%
Dockerfile 1%
CSS 0.9%
Shell 0.5%
Other 0.2%