Files
joulenap/CONTRIBUTING.md
T
Catubba 22f7063f2e docs: add the 0.3.1 changelog links and mention the wizard fixtures
The `## [0.3.1]` heading is a reference link with no definition, so it
rendered as literal text; `[Unreleased]` still compared from v0.3.0.
2026-07-09 23:48:07 +02:00

3.5 KiB

Contributing to Joulenap

Thanks for your interest in improving Joulenap! This guide covers the local dev setup, how to run the checks CI runs, and the conventions we follow.

By contributing you agree that your contributions are licensed under the project's AGPL-3.0.

Project layout

  • backend/ — Python 3.12 + FastAPI + APScheduler. The app package is backend/app.
  • frontend/ — React + TypeScript SPA (Vite). Built output is served by the backend.
  • docs/ — design and setup docs. Start with ARCHITECTURE.md and CONFIG-WIZARD.md.

Dev setup

You need Python 3.12+ and Node 20+.

Backend

cd backend
python -m venv .venv
# Windows: .venv\Scripts\activate   |   macOS/Linux: source .venv/bin/activate
pip install -e ".[dev]"

ruff check .    # lint
pytest          # tests

Frontend

cd frontend
npm ci
npm run dev      # Vite dev server (proxies /api to the backend on :8080)
npm run build    # type-check (tsc --noEmit) + production build

For a running app, copy the config first and start the backend:

cp config.example.yaml config.yaml
cd backend && python -m app.main    # serves the API (and the built SPA if you ran `npm run build`)

The example config ships unconfigured, so the app drops you into the first-run registration and setup wizard — no real Proxmox needed to click around the UI.

Frontend without a backend

To work on the UI alone — layout, styling, i18n — you can run the SPA against a built-in stub instead of a real backend and a real Proxmox:

cd frontend
npm run dev -- --mode stub

frontend/src/devStub.ts answers every /api/* request from fixtures (a configured install, three guests, a few log lines, and enough wizard responses to click through the whole setup flow) and pins the clock, so the UI renders exactly the same on every run — handy for screenshots and layout comparisons. It is loaded only when VITE_STUB_API=1, which frontend/.env.stub sets for the stub mode, and Vite eliminates it from production builds.

Add --host 0.0.0.0 to reach the dev server from a phone on the same network.

Before you open a PR

Run what CI runs (see .github/workflows/ci.yml); all of it must pass:

  • Backend: ruff check . and pytest (CI runs the suite on Python 3.12 and 3.13).
  • Frontend: npm run build (this type-checks with tsc --noEmit).

CI also runs dependency (pip-audit / npm audit) and Docker image (Trivy) security scans.

Conventions

  • Small, reviewable commits; work on a feature branch and open a PR against main.
  • Tests for the connectors and backup-cycle logic — that's where correctness matters most.
  • Keep it config-driven — nothing hard-coded (no specific IPs/MACs in code); validate config with pydantic and fail clearly.
  • Secrets never get committed. config.yaml is git-ignored; don't add real hosts/tokens/MACs to code, tests, or docs — use placeholder/192.0.2.x (TEST-NET) values.
  • i18n: user-facing UI strings go through t('key') with entries in both frontend/src/i18n/en.json and frontend/src/i18n/it.json (English is the source language). Backend-facing strings (errors, notifications) use the server-side dictionary. Never concatenate translated strings — use interpolation.

Reporting bugs and requesting features

Use the issue templates (bug report / feature request). For security vulnerabilities, do not open a public issue — follow SECURITY.md instead.