A modern social web application built with React, FastAPI, and DevSecOps practices. This project focuses on continuous integration, automated testing, and secure deployment.
This project is built using Visual Studio Code Dev Containers. This ensures that everyone working on the project uses the exact same OS, tools, and dependencies (Python, Node.js, Playwright browsers, etc.) without needing to install them manually on their local machine.
Before you begin, ensure you have the following installed:
- Container Runtime If you are devleoping on a Linux machine, you probably already have Docker installed. Otherwise, choose one of the following options:
- Docker Desktop
- Rancher Desktop (Ensure
dockerd(moby) is selected in Kubernetes Settings if using this) - Other alternatives
- Visual Studio Code
- Dev Containers Extension for VS Code (id:
ms-vscode-remote.remote-containers)
This project is designed to run in a VS Code Dev Container. This ensures you have Python, Node.js, Postgres, and all tools (including VS Code extensions) pre-installed.
- Open Docker Desktop (or Rancher Desktop)
- Open the project root in VS Code.
- When prompted, click "Reopen in Container".
- Wait for the build to finish. The environment will automatically run make install to set up dependencies.
/
backend/
|
├── app/
│ ├── api/
│ │ └── v1/
│ │ └── endpoints/
│ │ ├── auth.py # Autentisering
│ │ ├── circles.py # Circle CRUD
│ │ ├── circle_members.py
│ │ ├── posts.py # Inlägg CRUD
│ │ └── users.py # Användarsökning
│ │
│ ├── core/
│ │ ├── config.py # Konfiguration
│ │ ├── security.py # JWT, hashing
│ │ └── db.py # DB connection
│ │
│ ├── db/
│ │ ├── models.py # SQLAlchemy models
│ │ └── database.py # Session management
│ ├── schemas/
│ │ ├── auth.py # Pydantic schemas
│ │ └── social.py
│ └── main.py # FastAPI app
│
├── tests/
│ ├── unit/ # Enhetstester
│ ├── integration/ # Integrationstester
│ ├── e2e/ # End-to-end tester
│ │ └── step_defs/
│ │ ├── test_user_dashboard.py
│ │ ├── test_login.py
│ │ ├── test_registration.py
│ │ └── test_ui.py
│ └── conftest.py # Shared fixtures (Database, etc.)
│
├── alembic/ # Databasmigrationer
|
├── pyproject.toml # Dependencies
├── uv.lock
│
docs # General project documentation and guides
├── features/ # BDD Gherkin files
│ ├── login.feature
| └── etc...
├── BDD_CONFIGURATION.md
├── etc...
|
frontend/
|
├── src/
│ ├── components/ # Återanvändbara komponenter
│ ├── pages/ # Sidor (LoginPage, RegisterPage, etc.)
│ ├── services/ # API-kommunikation
│ │ └── auth.service.js
│ ├── hooks/ # Custom React hooks
│ ├── context/ # React Context för state
│ ├── utils/ # Hjälpfunktioner
│ └── App.jsx # Huvudkomponent
├── public/ # Statiska filer
├── index.html
├── package.json # Dependencies
├── vite.config.js # Build-konfiguration
│
├── Makefile
└── README.md # This file
- Single Source of Truth: We use a Makefile to define all our complex build, test, and run commands.
- Local Parity: The exact same commands we type on our laptops (like make test-backend) are the ones GitHub Actions uses.
- Abstracted Complexity: Developers don't need to memorize long Pytest arguments or Playwright flags; the Makefile handles it.
Note that these commands should all be run from the root folder of the project.
# Show all Make commands
make help
# Install backend and fronted dependencies
make install
# Start development server backend (FastAPI)
# API docs available here: API Docs: http://localhost:8000/docs
make run-backend
# Start development server frontend (requires backend to be running also)
# access at http://localhost:3000
make run-backend
make run-frontend
# Run end-2-end tests
make run-test-backend
make run-frontend
make test-e2e
- React 19 with Vite
- React Router DOM v6
- Axios for HTTP requests
- Vitest + Testing Library (unit/integration)
- Dependency Manager: uv (replaces pip/poetry)
- Framework: FastAPI
- Server: Uvicorn
- Authentication: PyJWT (Modern replacement for python-jose)
- Password Hashing: pwdlib + argon2 (Modern replacement for passlib)
- Validation: Pydantic
- Database: SQLAlchemy, PostgreSQL, Alembic for migrations
- Testing: pytest
- Code Quality: Ruff (replaces black/flake8/isort) + mypy
- Security: bandit
- Create feature branch from main
- Implement feature with tests, run tests
- Check code quality: e.g. make lint-backend
- Security scan: e.g. make security-backend
- Commit and push to feature branch
- Create Pull Request (CI will run automatically)
- Code review by team
- Merge to main
Our project utilizes a comprehensive, multi-layered testing strategy to ensure reliability across the entire stack. We divide our tests into specific domains to maximize execution speed and maintain clean database states.
Our backend testing suite focuses on the FastAPI server and database logic, emphasizing speed and transaction safety.
- Unit Testing: Tests individual functions, utilities, and isolated business logic. We mock external dependencies and avoid database interactions to provide immediate developer feedback.
- Integration Testing: Tests API endpoints, database queries, and SQLAlchemy models natively using
@pytest.mark.asyncio.- Data Strategy: We use a highly optimized
db_sessionfixture. Instead of wiping the database, this fixture wraps every test in a safe transaction and strictly rolls it back when the test completes.
- Data Strategy: We use a highly optimized
- Execution: Run via
make test-backend.
Our frontend unit and component tests are powered by Vitest, chosen for its blazing-fast execution and native integration with our Vite build pipeline.
- Component Testing: We use
@testing-library/reactto render components in isolation. We focus on testing how a user interacts with the UI (e.g., finding elements by accessible roles) rather than testing internal React state. - DOM Assertions: Extended with
@testing-library/jest-domfor highly readable matchers liketoBeInTheDocument(). - Browser Simulation: We use
jsdomto simulate a browser environment inside Node.js, allowing us to test clicks and renders in milliseconds without launching a real browser. - Structure: Tests are located in
frontend/src/tests/or colocated directly next to the components they test (e.g.,Button.test.jsx). - Execution: Run via
make test-frontend-unit(ornpm run test:watchfor active development).
Our E2E layer tests the complete user journey from the React UI down to the database. It is driven by readable Gherkin .feature files and executed via Playwright.
- Full-Stack Execution: These are synchronous browser tests that require the FastAPI server, frontend dev server, and test database to be running simultaneously.
- Database "Nuke" Strategy: Because the live background server cannot read uncommitted Pytest transactions, we use an
autouse=Truefixture calledclean_database_before_test. This runs aTRUNCATE TABLE ... CASCADEcommand to completely wipe all data before every single E2E test to prevent state leakage. - Synchronous Factories: We use dedicated synchronous fixtures (like
create_test_user_synchronous) to physically commit test data to the database before Playwright navigates to the page. - Automated XFAILs (BDD): Gherkin scenarios tagged with
@todoare automatically mapped to Pytest's@xfailmarker via a custom hook. This keeps the CI pipeline green while documenting UI features that are waiting on backend implementation. - Execution: Run via
make test-e2e.
GitHub Actions workflow located in .github/workflows/ci-cd.yml:
Runs on push to main/develop branches and pull requests
-
Checkout code: Fetches the repository code so the runner can access it.
-
Initialize CodeQL: Prepares the GitHub Advanced Security scanner for either Python or JavaScript depending on the matrix target.
-
Install uv: Sets up the Python package manager and caches dependencies based on the backend/uv.lock file.
-
Setup Backend Environment: Creates a .env file with database credentials populated from GitHub Secrets and installs backend dependencies.
-
Setup Test Database & Start Server: Seeds the shared PostgreSQL database and boots up the backend server in the background.
-
Lint, Format, Security: Runs static analysis and basic security checks on the Python code.
-
Run Tests: Executes the backend unit and integration tests.
-
Setup Node.js: Initializes Node version 20 and caches npm packages.
-
Install & Audit: Installs frontend dependencies, runs a security audit, and performs linting checks.
-
Unit Tests: Executes the frontend unit tests via Vitest.
-
Playwright Setup: Caches browser binaries using the uv.lock key, and intelligently downloads either the full browsers or just the system dependencies based on whether the cache was hit.
-
Run E2E Tests: Starts the frontend React server, waits for port 3000 to become available, and executes the Playwright end-to-end suite.
-
Cleanup: An "always-run" step that safely kills any lingering background npm, node, and uvicorn processes to free up the runner.
-
CodeQL Analysis: Finalizes the security scan and guarantees the results are uploaded to the GitHub Security tab, regardless of whether tests passed or failed.
git clone https://github.com/DiscSecOps/DiscSecOps
-
Playwright browsers are pre-installed in the Dev Container
-
The project follows DevSecOps principles with security integrated from the start
-
Feature development uses slicing methodology for incremental delivery
- Camelia Ciuca
- Haidar Alany
- Mattias Hammarhorn
- Richard Orme
- Shahzad Babar
MIT