Files
backend/README.md
T

6.4 KiB

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

  1. Keep MySQL running with docker compose up -d.
  2. Add API endpoints in controllers/ using HttpController.
  3. Register routes in the controller METHOD_LIST_BEGIN block with ADD_METHOD_TO(Controller::handler, "/api/v1/path", drogon::Get).
  4. Implement handlers with the Drogon signature: void handler(const HttpRequestPtr &, std::function<void(const HttpResponsePtr &)> &&callback).
  5. Return JSON with HttpResponse::newHttpJsonResponse(...).
  6. Read app/database settings from config.json; do not hardcode connection details in controllers.
  7. Add focused endpoint or helper tests for high-risk behavior, then run:
cmake --build build
ctest --test-dir build --output-on-failure
  1. 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.

For CIE auth deploys, also override values that vary by environment:

  • CIE_AUTH_SERVICE_BASE_URL
  • CIE_AUTH_START_PATH
  • CIE_AUTH_SHARED_SECRET
  • CIE_AUTH_STATE_TTL_MINUTES
  • CIE_AUTH_DEFAULT_FRONTEND_REDIRECT_URI

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 with SELECT 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: