Contributing#

Self Hosted

Development setup#

API

Requires Python 3.13 and a virtual environment:

cd api
make install-test   # installs production + test dependencies
make run            # starts dev server on :8080 with SQLite and auth disabled

Web UI

Requires Node 22:

cd web
npm install
npm run dev         # starts Vite dev server, proxies API to localhost:8080

Running tests#

Python (API):

cd api
make test           # run all tests
pytest tests/test_batch.py::test_add   # single test

Tests use a real SQLite database. The conftest.py drops and recreates all tables at session start. Auth is disabled in the test environment.

JavaScript (web):

cd web
npm run test

Code style#

Python:

cd api
make lint   # ruff + pylint
make fmt    # ruff format

JavaScript:

cd web
npm run lint   # ESLint

Adding a new feature#

Follow the layered conventions strictly:

  1. Add the ORM model in core/models/ — no business logic.

  2. Add Pydantic schemas in core/schemas/ using the camelCase base.

  3. Add the service in core/services/ extending BaseService.

  4. Add the router in core/routers/ delegating to the service.

  5. Import the new model in core/db.py so create_all picks it up.

  6. Add the table name to truncate_database() in tests/conftest.py.

  7. Write tests in tests/.