Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 32 additions & 18 deletions .env.example
Original file line number Diff line number Diff line change
@@ -1,23 +1,37 @@
HOST=0.0.0.0
PORT=8000
# -----------------------------------------------------------------------------
# Host User & System Settings (for Rootless Docker)
# Run `id -u` and `id -g` on Linux/macOS to get these values
# -----------------------------------------------------------------------------
UID=1000
GID=1000

# PostgreSQL Configuration (PostgreSQL 16)
POSTGRES_USER=fashio_admin
POSTGRES_PASSWORD=SuperSecureAndComplexPassword2026!
# -----------------------------------------------------------------------------
# Port Configurations
# -----------------------------------------------------------------------------
POSTGRES_PORT=5432
BACKEND_PORT=8000
FRONTEND_PORT=5173

# -----------------------------------------------------------------------------
# Database Configuration
# -----------------------------------------------------------------------------
POSTGRES_DB=fashio_db
POSTGRES_PORT=42359
POSTGRES_HOST=127.0.0.1
POSTGRES_USER=fashio_user
POSTGRES_PASSWORD=fashio_secure_password
POSTGRES_HOST=db

# JWT
JWT_SECRET=my_super_long_and_secure_secret_key
# -----------------------------------------------------------------------------
# Django / Security Settings
# -----------------------------------------------------------------------------
JWT_SECRET=super-secret-jwt-key-change-in-production

# OAuth2 Authentication Providers
# Google Developer Console Credentials
GOOGLE_CLIENT_ID=your_google_client_id.apps.googleusercontent.com
GOOGLE_CLIENT_SECRET=GOCSPX-your_google_client_secret
GOOGLE_REDIRECT_URL=http://localhost:8000/api/auth/google/callback
# -----------------------------------------------------------------------------
# OAuth Credentials (Google & GitHub)
# -----------------------------------------------------------------------------
GOOGLE_CLIENT_ID=your-google-client-id.apps.googleusercontent.com
GOOGLE_CLIENT_SECRET=your-google-client-secret
GOOGLE_REDIRECT_URL=http://localhost:8000/api/auth/google/callback/

# GitHub Developer Settings Credentials
GITHUB_CLIENT_ID=ov-your_github_client_id
GITHUB_CLIENT_SECRET=your_github_client_secret
GITHUB_REDIRECT_URL=http://localhost:8000/api/auth/github/callback
GITHUB_CLIENT_ID=your-github-client-id
GITHUB_CLIENT_SECRET=your-github-client-secret
GITHUB_REDIRECT_URL=http://localhost:8000/api/auth/github/callback/
13 changes: 13 additions & 0 deletions .flake8
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
[flake8]
max-line-length = 88
extend-ignore = E203

# Allow star imports specifically in settings modules
per-file-ignores =
config/settings/*.py: F401, F403, F405

exclude =
.git,
__pycache__,
.venv,
*/migrations/*
54 changes: 36 additions & 18 deletions .github/workflows/backend-ci.yml
Original file line number Diff line number Diff line change
@@ -1,56 +1,74 @@
name: Backend Tests
name: Backend CI

on:
push:
branches: [ main, dev ]
paths:
- "backend/**"
- ".github/workflows/backend-ci.yml"
pull_request:
branches: [ main, dev ]
paths:
- "backend/**"
- ".github/workflows/backend-ci.yml"

permissions:
contents: read

jobs:
test:
runs-on: ubuntu-latest

env:
DJANGO_SETTINGS_MODULE: config.settings.local
POSTGRES_DB: fashio_test_db
POSTGRES_USER: fashio_test_user
POSTGRES_PASSWORD: fashio_test_password
POSTGRES_HOST: localhost
POSTGRES_PORT: 5432
JWT_SECRET: test-jwt-secret-key-for-ci-pipeline

defaults:
run:
working-directory: backend

services:
postgres:
image: postgres:16-alpine
env:
POSTGRES_USER: ${{ vars.POSTGRES_USER || 'fashio_admin' }}
POSTGRES_PASSWORD: ${{ secrets.POSTGRES_PASSWORD || 'local_test_password' }}
POSTGRES_DB: ${{ vars.POSTGRES_DB || 'fashio_db' }}
POSTGRES_DB: fashio_test_db
POSTGRES_USER: fashio_test_user
POSTGRES_PASSWORD: fashio_test_password
ports:
- 5432:5432
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-interval 5s
--health-timeout 5s
--health-retries 5

steps:
- name: Checkout source code
uses: actions/checkout@v4

- name: Install uv and set up python
- name: Install uv and enable caching
uses: astral-sh/setup-uv@v5
with:
version: "latest"
enable-cache: true
cache-dependency-lock-file: "backend/uv.lock"

- name: Install dependencies
working-directory: backend
- name: Ensure Python 3.12 is installed
run: uv python install 3.12

- name: Install project dependencies
run: uv sync --frozen

- name: Run flake8
working-directory: backend
run: |
uv run flake8 . --exclude=.venv --count --select=E9,F63,F7,F82 --show-source --statistics
uv run flake8 . --exclude=.venv --count --exit-zero --max-complexity=10 --max-line-length=119 --statistics
- name: Lint code with Ruff
run: uv run ruff check .

- name: Run black check
working-directory: backend
run: uvx black --check --verbose .
- name: Check code formatting with Ruff
run: uv run ruff format --check .

- name: Run pytest
working-directory: backend
- name: Run Pytest suite
run: uv run pytest
10 changes: 9 additions & 1 deletion backend/.dockerignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
.venv
__pycache__
*.pyc
*.pyo
*.pyd
.git
.env
.gitignore
.env
.pytest_cache
.coverage
htmlcov
media
staticfiles
56 changes: 50 additions & 6 deletions backend/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,18 +1,62 @@
FROM python:3.12-slim
FROM python:3.12-slim AS base

ENV PYTHONDONTWRITEBYTECODE=1
ENV PYTHONUNBUFFERED=1
ENV PYTHONUNBUFFERED=1 \
PYTHONDONTWRITEBYTECODE=1 \
UV_COMPILE_BYTECODE=1 \
UV_LINK_MODE=copy

WORKDIR /app

RUN pip install --no-cache-dir uv
COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /bin/

FROM base AS development

ENV UV_CACHE_DIR=/tmp/.uv-cache

COPY pyproject.toml uv.lock ./

RUN uv sync --frozen
RUN uv sync --frozen && rm -rf /tmp/.uv-cache

COPY . .

EXPOSE 8000

CMD ["uv", "run", "python", "manage.py", "runserver", "0.0.0.0:8000"]

FROM base AS builder

RUN apt-get update && apt-get install -y --no-install-recommends \
build-essential \
libpq-dev \
&& rm -rf /var/lib/apt/lists/*

COPY pyproject.toml uv.lock ./
RUN uv sync --frozen --no-dev --no-install-project

COPY . .
RUN uv sync --frozen --no-dev
FROM python:3.12-slim AS production

ENV PYTHONUNBUFFERED=1 \
PYTHONDONTWRITEBYTECODE=1 \
PATH="/app/.venv/bin:$PATH"

WORKDIR /app

RUN apt-get update && apt-get install -y --no-install-recommends \
libpq5 \
curl \
&& rm -rf /var/lib/apt/lists/*

COPY --from=builder /app/.venv /app/.venv
COPY --from=builder /app /app

RUN addgroup --gid 1000 appgroup && \
adduser --uid 1000 --gid 1000 --disabled-password --gecos "" appuser && \
chown -R appuser:appgroup /app

USER appuser

EXPOSE 8000

CMD ["uv", "run", "python", "manage.py", "runserver", "${HOST}:${PORT}"]
CMD ["gunicorn", "config.wsgi:application", "--bind", "0.0.0.0:8000", "--workers", "4"]
2 changes: 0 additions & 2 deletions backend/apps/authentication/admin.py
Original file line number Diff line number Diff line change
@@ -1,3 +1 @@
from django.contrib import admin

# Register your models here.
2 changes: 0 additions & 2 deletions backend/apps/authentication/models.py
Original file line number Diff line number Diff line change
@@ -1,3 +1 @@
from django.db import models

# Create your models here.
2 changes: 1 addition & 1 deletion backend/apps/authentication/serializers.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from rest_framework import serializers
from django.contrib.auth.models import User
from rest_framework import serializers


class RegisterSerializer(serializers.ModelSerializer):
Expand Down
2 changes: 0 additions & 2 deletions backend/apps/authentication/tests.py
Original file line number Diff line number Diff line change
@@ -1,3 +1 @@
from django.test import TestCase

# Create your tests here.
1 change: 1 addition & 0 deletions backend/apps/authentication/urls.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from django.urls import path

from . import views

urlpatterns = [
Expand Down
3 changes: 2 additions & 1 deletion backend/apps/authentication/views.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from rest_framework import generics
from django.contrib.auth.models import User
from rest_framework import generics

from .serializers import RegisterSerializer


Expand Down
2 changes: 0 additions & 2 deletions backend/apps/catalog/admin.py
Original file line number Diff line number Diff line change
@@ -1,3 +1 @@
from django.contrib import admin

# Register your models here.
2 changes: 0 additions & 2 deletions backend/apps/catalog/models.py
Original file line number Diff line number Diff line change
@@ -1,3 +1 @@
from django.db import models

# Create your models here.
2 changes: 0 additions & 2 deletions backend/apps/catalog/tests.py
Original file line number Diff line number Diff line change
@@ -1,3 +1 @@
from django.test import TestCase

# Create your tests here.
2 changes: 0 additions & 2 deletions backend/apps/orders/admin.py
Original file line number Diff line number Diff line change
@@ -1,3 +1 @@
from django.contrib import admin

# Register your models here.
2 changes: 0 additions & 2 deletions backend/apps/orders/models.py
Original file line number Diff line number Diff line change
@@ -1,3 +1 @@
from django.db import models

# Create your models here.
2 changes: 0 additions & 2 deletions backend/apps/orders/tests.py
Original file line number Diff line number Diff line change
@@ -1,3 +1 @@
from django.test import TestCase

# Create your tests here.
2 changes: 0 additions & 2 deletions backend/apps/profiles/admin.py
Original file line number Diff line number Diff line change
@@ -1,3 +1 @@
from django.contrib import admin

# Register your models here.
2 changes: 0 additions & 2 deletions backend/apps/profiles/models.py
Original file line number Diff line number Diff line change
@@ -1,3 +1 @@
from django.db import models

# Create your models here.
2 changes: 0 additions & 2 deletions backend/apps/profiles/tests.py
Original file line number Diff line number Diff line change
@@ -1,3 +1 @@
from django.test import TestCase

# Create your tests here.
2 changes: 0 additions & 2 deletions backend/apps/sellers/admin.py
Original file line number Diff line number Diff line change
@@ -1,3 +1 @@
from django.contrib import admin

# Register your models here.
2 changes: 0 additions & 2 deletions backend/apps/sellers/models.py
Original file line number Diff line number Diff line change
@@ -1,3 +1 @@
from django.db import models

# Create your models here.
2 changes: 0 additions & 2 deletions backend/apps/sellers/tests.py
Original file line number Diff line number Diff line change
@@ -1,3 +1 @@
from django.test import TestCase

# Create your tests here.
Empty file.
Loading
Loading