mirror of
https://github.com/Joulenap/joulenap.git
synced 2026-08-11 13:21:43 +02:00
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.
95 lines
3.5 KiB
Markdown
95 lines
3.5 KiB
Markdown
# 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](LICENSE).
|
|
|
|
## 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`](docs/ARCHITECTURE.md) and
|
|
[`CONFIG-WIZARD.md`](docs/CONFIG-WIZARD.md).
|
|
|
|
## Dev setup
|
|
|
|
You need Python 3.12+ and Node 20+.
|
|
|
|
### Backend
|
|
|
|
```bash
|
|
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
|
|
|
|
```bash
|
|
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:
|
|
|
|
```bash
|
|
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:
|
|
|
|
```bash
|
|
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`](.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`](SECURITY.md) instead.
|