Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
71 commits
Select commit Hold shift + click to select a range
f8a2b23
fix(cicd): update renovate.json to preserve semver ranges
simonvanlierde Oct 17, 2025
30d992b
fix(backend): Include disposable email check in backend registration …
simonvanlierde Oct 17, 2025
6b7ca36
fix(cicd): Fix versioning issues across the repo
simonvanlierde Oct 21, 2025
793b2a5
fix(backend): Don't seed dummy data by default
simonvanlierde Oct 21, 2025
eaf6b42
fix(backend): improve seeding scripts
simonvanlierde Oct 21, 2025
6a59854
fix(docker): Fix postgres-backup-local config
simonvanlierde Oct 28, 2025
8774ecf
feat(backend): add manual pg backup script and rclone backup sync script
simonvanlierde Oct 28, 2025
c68890f
feat(backend): Print backup stats after rclone
simonvanlierde Oct 28, 2025
f2e1eaf
fix(backend): Use rclone symlink files for symlinked backups
simonvanlierde Oct 28, 2025
8755867
fix(backend): Move username validation from model to schema
simonvanlierde Oct 29, 2025
4e7a0ac
refactor(frontend-app): Deduplicate product name validation
simonvanlierde Oct 29, 2025
93a938e
chore(deps): update pre-commit yaml
simonvanlierde Oct 29, 2025
5875e1e
feat(frontend-app): update registration validation and error handling
simonvanlierde Oct 29, 2025
acdd1f0
fix(cicd): Format frontend instead of just linting
simonvanlierde Oct 29, 2025
4b5e80b
chore: linting
simonvanlierde Oct 29, 2025
cd06b02
fix(backend): remove logging info
simonvanlierde Oct 29, 2025
8b6f233
docs(backend): Clarify config setup (local .env file vs. env vars in …
simonvanlierde Oct 29, 2025
2fe6e36
feature(frontend-app): Add tooltip to product save button showing val…
simonvanlierde Oct 29, 2025
ac2ab05
feature(backend): add order_by, created_at and updated_at filters for…
simonvanlierde Nov 3, 2025
d0f5247
feature(backend): Move to mjml email templates and fastapi-email to s…
simonvanlierde Nov 4, 2025
ebfa5ae
feature(backend): Move to fastapi-mail and redis for disposable mail …
simonvanlierde Nov 6, 2025
31bd113
feature(backend): add order_by query param to get_products route
simonvanlierde Nov 6, 2025
662c32e
fix(backend): graceful handling of failed redis connection on app sta…
simonvanlierde Nov 6, 2025
9db5f41
fix(backend): Include built email templates in git
simonvanlierde Nov 7, 2025
5c4d92c
fix(backend): Fix cache dependency in docker compose file (backend, n…
simonvanlierde Nov 7, 2025
775728b
chore: update pre-commit revs
simonvanlierde Nov 7, 2025
36434c3
feature(backend): Use SecretStr for secret env vars in the core config
simonvanlierde Nov 7, 2025
fd86e95
fix(docker): Improve healthcheck timing and override REDIS_HOST var i…
simonvanlierde Nov 7, 2025
f2662a4
fix(backend): default example redis password should be empty
simonvanlierde Nov 7, 2025
d98d002
feature(backend): Use custom fork of fastapi-mail and pass redis clie…
simonvanlierde Nov 7, 2025
623961d
fix(backend): Use try except else pattern
simonvanlierde Nov 7, 2025
dc94217
fix(docker): Persist cache data in prod
simonvanlierde Nov 7, 2025
0097982
fix(backend): Move Annotated validation from database models to Creat…
simonvanlierde Nov 7, 2025
5194bd3
feature(backend): Fix Pydantic 2.12 issues and move to python 3.14
simonvanlierde Nov 8, 2025
5bd435c
fix(backend): Init disposable email checker without Redis if no Redis…
simonvanlierde Nov 8, 2025
a0e4533
fix(cicd): Lint pre-commit yaml and update mdformat pre-commit hook
simonvanlierde Nov 8, 2025
9bbd556
fix(backend): Move back to python 3.13 because Dockerized asyncpg doe…
simonvanlierde Nov 8, 2025
7ed08d9
chore(deps): update infrastructure
renovate[bot] Oct 21, 2025
ec74a11
fix(deps): update expo monorepo
renovate[bot] Oct 21, 2025
dadebaa
chore(deps): update dependency @react-navigation/bottom-tabs to v7.4.9
renovate[bot] Oct 20, 2025
086f963
fix(backend): Use TypeAlias over simple type declaration for custom s…
simonvanlierde Nov 8, 2025
b4f3fb6
fix(backend): Only apply sorting if explicit sorting was requested
simonvanlierde Nov 8, 2025
3325db7
feature(backend): Mask user emails in logs for privacy
simonvanlierde Nov 8, 2025
1511004
Potential fix for code scanning alert no. 8: Log Injection
simonvanlierde Nov 8, 2025
7a43515
fix(backend): Simplify URL serializing to DB
simonvanlierde Nov 8, 2025
db2e6e5
fix(backend): Simplify dummy data checking logic
simonvanlierde Nov 8, 2025
fbb34dd
fix(backend): Spellcheck
simonvanlierde Nov 8, 2025
fffbff3
feat(backend): Add circularity_properties model to products
simonvanlierde Nov 17, 2025
d9d2edb
fix(backend): Don't initialize email checker for on synthetic user cr…
simonvanlierde Nov 17, 2025
3b49519
feature(backend): Allow superuser to remove any product
simonvanlierde Nov 17, 2025
e66f286
feature(backend): Move from kg to g for physical_properties weight field
simonvanlierde Nov 17, 2025
0cd5def
feature: paginate users/me/products
simonvanlierde Nov 17, 2025
100039d
fix(backend): make circularity properties optional
simonvanlierde Nov 24, 2025
71a680e
chore(backend): Update to python 3.14
simonvanlierde Nov 25, 2025
04715fe
chore: linting
simonvanlierde Nov 25, 2025
5e69941
feat(backend): Allow patching videos
simonvanlierde Nov 27, 2025
93a469e
Merge pull request #80 from CMLPlatform/frontend-app-circularity-prop…
simonvanlierde Nov 27, 2025
89c64ce
chore: linting
simonvanlierde Nov 27, 2025
ba4017b
chore(backend): Simplify circularity properties model
simonvanlierde Nov 27, 2025
0223b0e
fix(docker): Update runtime stage python version to 3.14 in backend_m…
simonvanlierde Nov 27, 2025
671c006
fix(frontend-app): omit circularityproperties if all fields are null
simonvanlierde Nov 27, 2025
6cf7e9f
fix(backend): Add some logging on rpi-cam related network errors
simonvanlierde Nov 27, 2025
f68a950
fix(backend): Remove unused docker arg
simonvanlierde Nov 27, 2025
ef7deb5
fix(backend): update ruff target python version
simonvanlierde Dec 1, 2025
1ef6d7a
fix(backend): Update python target version for ruff to 3.14
simonvanlierde Dec 1, 2025
cbdfbc3
fix(backend): Move logging module
simonvanlierde Dec 1, 2025
324ce8e
fix(backend): Lint backend with ruff targeted to 3.14 and remove unus…
simonvanlierde Dec 2, 2025
c4eb2be
fix(backend): Remove min length constraints from CircularityPropertie…
simonvanlierde Dec 8, 2025
88a6cbc
fix(backend): Hotfix for SQLmodel issues
simonvanlierde Dec 8, 2025
d74517d
fix(backend): Revert to old-school sqlalchemy typing to fix runtime O…
simonvanlierde Dec 8, 2025
c6665bd
feat(backend): Add timeout and use-cookies vars to rclone backup script
simonvanlierde Dec 8, 2025
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
12 changes: 9 additions & 3 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@ TUNNEL_TOKEN=your_token
# Host directory where database and user upload backups are stored
BACKUP_DIR=./backups

# Remote backup config (for use of backend/scripts/backup/backup_rclone.sh script)
BACKUP_REMOTE_HOST=user@host
BACKUP_REMOTE_PATH=/path/to/remote/backup
# Remote rsync backup config (for use of backend/scripts/backup/rsync_backup.sh script)
BACKUP_RSYNC_REMOTE_HOST=user@host
BACKUP_RSYNC_REMOTE_PATH=/path/to/remote/backup

# Remote rclone backup config (for use of backend/scripts/backup/rclone_backup.sh script)
BACKUP_RCLONE_REMOTE=myremote:/path/to/remote/backup
BACKUP_RCLONE_MULTI_THREAD_STREAMS=16
BACKUP_RCLONE_TIMEOUT=5m
BACKUP_RCLONE_USE_COOKIES=false
6 changes: 3 additions & 3 deletions .github/ISSUE_TEMPLATE/bug_report.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
---
name: Bug report
about: Create a report to help us improve
title: 'bug: '
labels: bug
assignees: ''
labels: bug
name: Bug report
title: 'bug: '
---

## Bug description
Expand Down
6 changes: 3 additions & 3 deletions .github/ISSUE_TEMPLATE/feature-request.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
---
name: Feature request
about: Suggest an idea for this project
title: 'feature request: '
labels: feature request
assignees: ''
labels: feature request
name: Feature request
title: 'feature request: '
---

## Problem statement
Expand Down
6 changes: 3 additions & 3 deletions .github/ISSUE_TEMPLATE/internal-ticket.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
---
name: Internal ticket
about: For internal development
title: ''
labels: ''
assignees: ''
labels: ''
name: Internal ticket
title: ''
---

## Problem
Expand Down
117 changes: 58 additions & 59 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,106 +5,105 @@

repos:
### Global hooks
- repo: https://gitlab.com/vojko.pribudic.foss/pre-commit-update
rev: v0.8.0
- repo: https://gitlab.com/vojko.pribudic.foss/pre-commit-update
rev: v0.9.0
hooks:
- id: pre-commit-update # Autoupdate pre-commit hooks
- id: pre-commit-update # Autoupdate pre-commit hooks

- repo: https://github.com/gitleaks/gitleaks
rev: v8.28.0
- repo: https://github.com/gitleaks/gitleaks
rev: v8.30.0
hooks:
- id: gitleaks
- id: gitleaks

- repo: https://github.com/executablebooks/mdformat
- repo: https://github.com/executablebooks/mdformat
rev: 1.0.0
hooks:
- id: mdformat # Format Markdown files.
- id: mdformat # Format Markdown files.
additional_dependencies:
- mdformat-gfm # Support GitHub Flavored Markdown.
- mdformat-footnote
- mdformat-frontmatter
- mdformat-ruff # Support Python code blocks linted with Ruff.
- mdformat-tables # Support GitHub style tables.
- mdformat-gfm>=1.0.0 # Support GitHub Flavored Markdown.
- mdformat-front-matters
- mdformat-ruff # Support Python code blocks linted with Ruff.

- repo: https://github.com/pre-commit/pre-commit-hooks
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v6.0.0
hooks:
- id: check-added-large-files
- id: check-case-conflict # Check for files with names that differ only in case.
- id: check-executables-have-shebangs
- id: check-shebang-scripts-are-executable
- id: check-toml
- id: check-yaml
- id: check-added-large-files
- id: check-case-conflict # Check for files with names that differ only in case.
- id: check-executables-have-shebangs
- id: check-shebang-scripts-are-executable
- id: check-toml
- id: check-yaml
exclude: ^docs/mkdocs.yml$ # Exclude mkdocs.yml because it uses an obscure tag to allow for mermaid formatting
- id: detect-private-key
- id: end-of-file-fixer # Ensure files end with a newline.
- id: mixed-line-ending
- id: no-commit-to-branch # Prevent commits to main and master branches.
- id: trailing-whitespace
- id: detect-private-key
- id: end-of-file-fixer # Ensure files end with a newline.
- id: mixed-line-ending
- id: no-commit-to-branch # Prevent commits to main and master branches.
- id: trailing-whitespace
args: ["--markdown-linebreak-ext", "md"] # Preserve Markdown hard line breaks.

- repo: https://github.com/commitizen-tools/commitizen
rev: v4.9.1
- repo: https://github.com/commitizen-tools/commitizen
rev: v4.10.0
hooks:
- id: commitizen
- id: commitizen
stages: [commit-msg]

- repo: https://github.com/simonvanlierde/check-json5
- repo: https://github.com/simonvanlierde/check-json5
rev: v1.1.0
hooks:
- id: check-json5
- id: check-json5
files: ^ (?!(backend/frontend-app|frontend-web)/data/)
### Backend hooks
- repo: https://github.com/RobertCraigie/pyright-python # Lint backend code with Pyright.
rev: v1.1.406

### Backend hooks
- repo: https://github.com/RobertCraigie/pyright-python # Lint backend code with Pyright.
rev: v1.1.407
hooks:
- id: pyright
- id: pyright
files: ^backend/(app|scripts|tests)/
entry: pyright --project backend

- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.14.0
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.14.6
hooks:
- id: ruff-check # Lint code
- id: ruff-check # Lint code
files: ^backend/(app|scripts|tests)/
args: ["--fix", "--config", "backend/pyproject.toml", "--ignore", "FIX002"] # Allow TODO comments in commits.
- id: ruff-format # Format code
- id: ruff-format # Format code
files: ^backend/(app|scripts|tests)/
args: ["--config", "backend/pyproject.toml"]

- repo: https://github.com/astral-sh/uv-pre-commit
rev: 0.9.3
- repo: https://github.com/astral-sh/uv-pre-commit
rev: 0.9.13
hooks:
- id: uv-lock # Update the uv lockfile for the backend.
- id: uv-lock # Update the uv lockfile for the backend.
files: ^backend/(uv\.lock|pyproject\.toml|uv\.toml)$
entry: uv lock --project backend

- repo: local
- repo: local
hooks: # Check if Alembic migrations are up-to-date. Uses uv to ensure the right environment when executed through VS Code Git extension.
- id: backend-alembic-autogen-check
- id: backend-alembic-autogen-check
name: check alembic migrations
entry: bash -c 'cd backend && uv run alembic-autogen-check'
language: system
files: ^(backend/(app|alembic)/|alembic\.ini$)
pass_filenames: false
stages: [pre-commit]

### Frontend hooks
- repo: local
### Frontend hooks
- repo: local
hooks:
- id: frontend-web-lint
name: lint frontend-web code
entry: bash -c 'cd frontend-web && npm run lint'
language:
system
# Match frontend JavaScript and TypeScript files for linting.
files: ^frontend-web\/.*\.(jsx?|tsx?|c(js|ts)|m(js|ts)|d\\.(ts|cts|mts)|jsonc?)$
- id: frontend-web-format
name: format frontend-web code
entry: bash -c 'cd frontend-web && npm run format'
language: system
# Match frontend JavaScript and TypeScript files for formatting.
files:
^frontend-web\/.*\.(jsx?|tsx?|c(js|ts)|m(js|ts)|d\\.(ts|cts|mts)|jsonc?)$
pass_filenames: false
- id: frontend-app-lint
name: lint frontend-app code
entry: bash -c 'cd frontend-app && npm run lint'
language:
system
# Match frontend JavaScript and TypeScript files for linting.
files: ^frontend-app\/.*\.(jsx?|tsx?|c(js|ts)|m(js|ts)|d\\.(ts|cts|mts)|jsonc?)$
- id: frontend-app-format
name: format frontend-app code
entry: bash -c 'cd frontend-app && npm run format'
language: system
# Match frontend JavaScript and TypeScript files for formatting.
files:
^frontend-app\/.*\.(jsx?|tsx?|c(js|ts)|m(js|ts)|d\\.(ts|cts|mts)|jsonc?)$
pass_filenames: false
34 changes: 30 additions & 4 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ Thank you for your interest in contributing to the Reverse Engineering Lab proje
- [Backend Code Style](#backend-code-style)
- [Backend Testing](#backend-testing)
- [Database Migrations](#database-migrations)
- [Email templates](#email-templates)
- [Frontend Development](#frontend-development)
- [Frontend Code Style](#frontend-code-style)
- [Frontend Testing](#frontend-testing)
Expand Down Expand Up @@ -172,10 +173,7 @@ It is still recommended to use VS Code as your IDE, as we have provided some rec

The API is now available at <http://127.0.0.1:8000>.

You can log in with the superuser details specified in the `.env` file. This gives you access to:

- Interactive API documentation at <http://127.0.0.1:8000/swagger/full>
- Admin panel for database management at <http://127.0.0.1:8000/dashboard>
You can log in with the superuser details specified in the `.env` file. This gives you access to the interactive API documentation at <http://127.0.0.1:8000/swagger/full>

#### Documentation Setup

Expand Down Expand Up @@ -339,6 +337,34 @@ When making changes to the database schema:
uv run alembic upgrade head
```

#### Email templates

This project uses [MJML](https://mjml.io/) to write email templates and [Jinja2](https://jinja.palletsprojects.com/en/latest/) for variable substitution at runtime.

- **Location**

- Source MJML templates: `backend/app/templates/emails/src/`
- Reusable components: `backend/app/templates/emails/src/components/`
- Compiled HTML output: `backend/app/templates/emails/build/` (This directory is **auto-generated**—do not edit files here.)

- **Editing Guidelines**

- Use **MJML** for structure and the `{{include:component_name}}` directive to reuse components.
- Use **Jinja2-style variables** in templates, e.g., `{{ username }}`, `{{ verification_link }}`.
- Keep components small and shared styles in `src/components/styles.mjml`.
- **Do not modify** files in `build/`.

- **Compiling Templates**
Run the compilation script from the repository root:

```bash
cd backend
python scripts/compile_email_templates.py
```

- **Interactive Preview**
For visual development, use MJML online tools or the [MJML VS Code extension](https://marketplace.visualstudio.com/items?itemName=mjmlio.vscode-mjml).

### Frontend Development

Set up your environment as described in the [Getting Started](#getting-started) section.
Expand Down
3 changes: 3 additions & 0 deletions backend/.dockerignore
Original file line number Diff line number Diff line change
Expand Up @@ -96,3 +96,6 @@ MANIFEST

# Local logs
./logs

# Include built email templates
!app/templates/emails/build/
6 changes: 6 additions & 0 deletions backend/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,12 @@ EMAIL_PASSWORD='your-email-password' # 🔀 Password for
EMAIL_FROM='Your Name <your.sending.alias.@example.com>' # 🔀 Email address from which the emails are sent. Can be different from the SMTP server username.
EMAIL_REPLY_TO='your.replyto.alias.@example.com' # 🔀 Email address to which replies are sent. Can be different from the SMTP server username.

# Redis settings for caching (disposable email domains, sessions, etc.)
REDIS_HOST='localhost' # Redis server host (use 'cache' in Docker)
REDIS_PORT='6379' # Redis server port
REDIS_DB='0' # Redis database number (0-15)
REDIS_PASSWORD='' # 🔀 Redis password (leave empty if no password)

# Superuser details
SUPERUSER_EMAIL='your-email@example.com' # 🔀
SUPERUSER_PASSWORD='example_password' # 🔀
Expand Down
3 changes: 3 additions & 0 deletions backend/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -80,3 +80,6 @@ backups/*
# VS Code settings
!.vscode/settings.json
!.vscode/extensions.json

# Include built email templates
!app/templates/emails/build/
11 changes: 5 additions & 6 deletions backend/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# --- Builder stage ---
FROM ghcr.io/astral-sh/uv:0.9-python3.13-trixie-slim@sha256:87db60325200a4fa5e9259fe43ff14c90c429adee952a8efe3f21b278409d09a AS builder
FROM ghcr.io/astral-sh/uv:0.9-python3.14-trixie-slim AS builder

# Install git for custom dependencies (fastapi-users-db-sqlmodel)
RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
Expand Down Expand Up @@ -34,11 +34,10 @@ RUN --mount=type=cache,target=/root/.cache/uv \
uv sync --locked --no-editable --no-default-groups --group=api

# --- Final runtime stage ---
FROM python:3.14-slim@sha256:1e7c3510ceb3d6ebb499c86e1c418b95cb4e5e2f682f8e195069f470135f8d51
FROM python:3.14-slim

# Build arguments
ARG WORKDIR=/opt/relab/backend
ARG APP_PORT=8000
ARG APP_USER=appuser

# Set up a non-root user
Expand All @@ -54,11 +53,11 @@ ENV PYTHONPATH=$WORKDIR \
PYTHONUNBUFFERED=1 \
PATH="$WORKDIR/.venv/bin:$PATH"

# Expose the application port
EXPOSE 8000

# Switch to non-root user
USER $APP_USER

# Expose the application port
EXPOSE 8000

# Run the FastAPI application
CMD [".venv/bin/fastapi", "run", "app/main.py", "--host", "0.0.0.0", "--port", "8000"]
2 changes: 1 addition & 1 deletion backend/Dockerfile.dev
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Development Dockerfile for FastAPI Backend
# Note: This requires mounting the source code as a volume in docker-compose.override.yml
FROM ghcr.io/astral-sh/uv:0.9-python3.13-trixie-slim@sha256:87db60325200a4fa5e9259fe43ff14c90c429adee952a8efe3f21b278409d09a
FROM ghcr.io/astral-sh/uv:0.9-python3.14-trixie-slim

# Build arguments
ARG WORKDIR=/opt/relab/backend
Expand Down
5 changes: 2 additions & 3 deletions backend/Dockerfile.migrations
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
# --- Builder stage ---
FROM ghcr.io/astral-sh/uv:0.9-python3.13-trixie-slim@sha256:87db60325200a4fa5e9259fe43ff14c90c429adee952a8efe3f21b278409d09a AS builder

FROM ghcr.io/astral-sh/uv:0.9-python3.14-trixie-slim AS builder
WORKDIR /opt/relab/backend_migrations

# Install git for custom dependencies (fastapi-users-db-sqlmodel)
Expand Down Expand Up @@ -33,7 +32,7 @@ COPY scripts/ scripts/
COPY app/ app/

# --- Final runtime stage ---
FROM python:3.14-slim@sha256:1e7c3510ceb3d6ebb499c86e1c418b95cb4e5e2f682f8e195069f470135f8d51
FROM python:3.14-slim

# Build arguments
ARG WORKDIR=/opt/relab/backend_migrations
Expand Down
3 changes: 2 additions & 1 deletion backend/alembic/env.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@
from pathlib import Path

import alembic_postgresql_enum # noqa: F401 (Make sure the PostgreSQL ENUM type is recognized)
from alembic import context
from sqlalchemy import engine_from_config, pool
from sqlmodel import SQLModel # Include the SQLModel metadata

from alembic import context

# Load settings from the FastAPI app config
project_root = Path(__file__).resolve().parents[1]
sys.path.append(str(project_root))
Expand Down
Loading