This reverts commit 5f81d2dcf7.
Visione Backend
C++20 API backend built with Drogon for the Visione urban reporting project. Docker is used only for local external services: MySQL and Mailpit.
Setup
Install native build dependencies first. On Ubuntu:
sudo apt install build-essential cmake ninja-build git pkg-config \
libjsoncpp-dev uuid-dev zlib1g-dev libssl-dev \
libmariadb-dev libmariadb-dev-compat
If CMake prints MySql was not found, the backend will compile without MySQL
support and /api/v1/ready will not be useful. Install the MariaDB/MySQL client
development packages above and re-run CMake.
cp .env.example .env
docker compose up -d
cmake -S . -B build -G Ninja -DCMAKE_BUILD_TYPE=Debug
cmake --build build
./build/visione-backend
The API listens on http://localhost:5555.
Mailpit listens on http://localhost:8025.
Local CORS allows http://localhost:5173 by default for the future Vue frontend.
Multipart uploads currently accept report images and videos up to the app body
limit configured in config.json.
Swagger UI is available at http://localhost:5555/api/v1/docs after the app
has been built.
Local seeded admin:
- email:
[email protected] - access uses OTP through Mailpit and is for local development only.
If you already had a MySQL volume from the old scaffold, create the local database/user once:
docker compose exec -T mysql mysql -uroot -proot -e \
"CREATE DATABASE IF NOT EXISTS visione CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; \
CREATE USER IF NOT EXISTS 'visione'@'%' IDENTIFIED BY 'visione'; \
ALTER USER 'visione'@'%' IDENTIFIED BY 'visione'; \
GRANT ALL PRIVILEGES ON visione.* TO 'visione'@'%'; \
FLUSH PRIVILEGES;"
curl http://localhost:5555/api/v1/health
curl http://localhost:5555/api/v1/ready
curl -X POST http://localhost:5555/api/v1/auth/otp/request \
-H 'Content-Type: application/json' \
-d '{"email":"[email protected]"}'
Use -DUSE_SYSTEM_DROGON=ON only if Drogon is already installed and
discoverable by CMake. The default build uses CPM.cmake and downloads Drogon
v1.9.13.
Project Docs
AGENTS.md: durable instructions for coding agents.docs/LLM_CONTEXT.md: short project context for future LLM sessions.docs/MILESTONE_01.md: what this milestone implemented and what comes next.docs/MILESTONE_02.md: workflow and authorization milestone.docs/MILESTONE_03.md: media upload, OpenAPI generator and API lab milestone.docs/MILESTONE_04.md: backend completion milestone.docs/API_SPEC.md: API surface.docs/DATABASE_SCHEMA.md: schema overview.docs/ARCHITECTURE.md: backend structure.
OpenAPI
The OpenAPI spec is generated from Drogon controller route macros plus the
manual standard OpenAPI document in docs/openapi/visione.openapi.yaml.
The script extracts paths and methods from C++ and lets the manual file own
summaries, request bodies, responses, schemas and examples.
The manual file uses JSON-compatible YAML so the CMake build does not require
extra Python packages.
cmake --build build --target openapi
python3 -m json.tool build/openapi/visione.openapi.json >/dev/null
python3 -m unittest scripts/test_generate_openapi.py
The app serves the generated JSON at /api/v1/openapi.json and Swagger UI at
/api/v1/docs.
Visione Lab
scripts/lab/ is a small Streamlit frontend used only to test the backend
visually while the real frontend is not ready.
cd scripts/lab
uv sync
uv run streamlit run app.py
Keep the backend running on http://127.0.0.1:5555. The lab calls the API from
Python, so it is not blocked by browser CORS settings.
Development Workflow
- Keep MySQL running with
docker compose up -d. - Add API endpoints in
controllers/usingHttpController. - Register routes in the controller
METHOD_LIST_BEGINblock withADD_METHOD_TO(Controller::handler, "/api/v1/path", drogon::Get). - Implement handlers with the Drogon signature:
void handler(const HttpRequestPtr &, std::function<void(const HttpResponsePtr &)> &&callback). - Return JSON with
HttpResponse::newHttpJsonResponse(...). - Read app/database settings from
config.json; do not hardcode connection details in controllers. - Add focused endpoint or helper tests for high-risk behavior, then run:
cmake --build build
ctest --test-dir build --output-on-failure
- After each completed and verified feature, create a short commit.
The RequestLogger plugin logs every response as method, path, status and
client address.
Dokploy
Use docker-compose.prod.yml as the Dokploy compose path for a self-contained
backend deployment with MySQL and a local SMTP catcher. Configure the public
domain in Dokploy against service backend and container port 5555.
The runtime image includes config.json; override environment-specific values
with Dokploy environment variables. The SMTP catcher service uses the
multi-architecture Mailpit image to avoid exec format error failures on ARM
servers.
Set DB_NAME, DB_USER, DB_PASSWORD, MYSQL_ROOT_PASSWORD and
CORS_ALLOWED_ORIGIN in Dokploy environment variables. Use the exact browser
origin without quotes or a trailing slash, for example
https://visione.studentindipendenti.it.
Docker builds use BuildKit cache mounts for CPM dependencies and ccache, so
repeat Dokploy builds can reuse Drogon and C++ compilation cache.
Current Endpoints
GET /api/v1/health: process health check, no external dependency.GET /api/v1/ready: checks MySQL withSELECT 1.- Auth, reports and admin endpoints are documented in
docs/API_SPEC.md.
Drogon Docs
Official docs entrypoint: https://drogonframework.github.io/drogon-docs/
Useful mirrored sections:
- Install and CPM: https://github.com/drogonframework/drogon/wiki/ENG-02-Installation
- Controller introduction: https://github.com/drogonframework/drogon/wiki/ENG-04-0-Controller-Introduction
- HttpController: https://github.com/drogonframework/drogon/wiki/ENG-04-2-Controller-HttpController
- Configuration file: https://github.com/drogonframework/drogon/wiki/ENG-11-Configuration-File
- Database client: https://github.com/drogonframework/drogon/wiki/ENG-08-1-Database-DbClient
- Testing: https://github.com/drogonframework/drogon/wiki/ENG-19-Testing-Framework