Development
Prerequisites
- Docker and Docker Compose (for the full stack)
- Python 3.14
- Node.js 20+ and npm
Backend
The backend is a Python/FastAPI service located in backend/.
Setup
Run
Tests
Coverage is collected automatically. The report is written to coverage.xml.
Lint & type-check
The project uses ruff with select = ["ALL"] — all rules are active. Never add # noqa suppressions without explicit review.
Smoke-test rule loading
After changing DSL models, verify that all rule files in rules.d still load correctly:
from pathlib import Path
from secretary.infra.loader import load_rules_from_path
rules = load_rules_from_path(Path("../rules.d"))
print(f"{len(rules)} rules loaded OK")
Frontend
The frontend is a Vue 3 + TypeScript SPA located in frontend/.
Setup & run
The dev server starts at http://localhost:5173/ and proxies API calls to the backend.
Build
Output is written to frontend/dist/ (which maps to static/ in the Docker image).
Type-check & lint
Full stack (Docker)
The development docker-compose.yml builds the full container and adds a Traefik reverse proxy:
The Secretary UI is then available at http://localhost/secretary/. The Traefik dashboard is at http://localhost:8080/.
Documentation
Documentation is built with zensical (a docs tool wrapping MkDocs Material).
Setup
Serve locally
Build
Project conventions
- Python 3.14+ — use modern syntax (
X | Yunions,match/case, walrus operator) - Pydantic v2 — use
model_validator,field_validator,BeforeValidator;mode="before"validators must raiseValueError - No speculative abstraction — only build what is needed
- No dead code, no commented-out code
- No docstrings on code you did not touch
Release
Docker images are published to ghcr.io/tb1337/paperless-secretary via GitHub Actions on every tagged release.