Skip to content

Development

Valerio edited this page Apr 21, 2026 · 1 revision

Development

This page covers everything a new contributor needs to get a local Harpyx environment running, iterate on it, and verify changes before opening a pull request.

Prerequisites

  • .NET 10 SDK — required for building the solution.
  • Docker + Docker Compose — for SQL Server, MinIO, RabbitMQ, Redis, OpenSearch, and ClamAV.
  • Node.js + npm — only needed when rebuilding Tailwind/DaisyUI CSS in Release or CI.
  • Microsoft Entra ID app registration — for local sign-in. Tenant id, client id, client secret go into .env.
  • (Optional) Google Cloud OAuth client — if you want to exercise the Google sign-in path.
  • (Optional) LLM API keys — OpenAI, Anthropic, and/or Google Gemini. Harpyx uses BYO credentials, so without at least one configured provider the RAG/chat features are off.

First-time setup

git clone <repository-url>
cd Harpyx

cp .env.example .env                      # Docker/default developer stack values
cp .env.local.example .env.local          # optional host-local overrides for IDE / dotnet run

dotnet restore Harpyx.slnx
dotnet build Harpyx.slnx

The build is clean when you see Errori: 0 (the MimeKit NU1902 warning is a known upstream advisory, not introduced by Harpyx).

Running the stack

Everything in Docker

docker compose up --build
  • WebApp → http://localhost:8080
  • MinIO console → http://localhost:9001
  • RabbitMQ management → http://localhost:15672
  • OpenSearch → https://localhost:9200 (self-signed cert, admin / your env password)

Hybrid (infrastructure in Docker, app from IDE)

Bring only the backing services up:

docker compose up sqlserver minio rabbitmq redis opensearch clamav

Then launch Harpyx.WebApp and Harpyx.Worker from your IDE. The repository-root .env is loaded first, then .env.local overrides host-only values such as localhost endpoints and published ports.

Database migrations

Apply the current migration set explicitly:

dotnet ef database update \
  --project src/Harpyx.Infrastructure \
  --startup-project src/Harpyx.WebApp

When Database:ApplyMigrationsOnStartup is omitted, the WebApp applies migrations on boot in Development. Set it explicitly only when overriding that default; never enable this in production.

Creating a new migration

dotnet ef migrations add <MigrationName> \
  --project src/Harpyx.Infrastructure \
  --startup-project src/Harpyx.WebApp \
  --output-dir Migrations

Review the generated SQL and entity model snapshot before committing.

Running tests

Three test projects, one command:

dotnet test Harpyx.slnx
Project Scope
tests/Harpyx.WebApp.UnitTests WebApp-only unit tests
tests/Harpyx.Worker.UnitTests Worker-only unit tests
tests/Harpyx.IntegrationTests End-to-end tests using Testcontainers

Integration tests spin up SQL Server, MinIO, and RabbitMQ containers on demand, so Docker must be running. CI runs all three project families.

Code style and conventions

  • Clean Architecture boundaries are enforced by project references; keep Harpyx.Domain free of framework dependencies.
  • Prefer injecting interfaces from Harpyx.Application.Interfaces over concrete implementations.
  • Use ILogger<T> + structured logging (_logger.LogInformation("... {DocumentId}", documentId)).
  • New telemetry sources go through HarpyxObservability so sampler/exporter config stays centralized.
  • Tests for new services are expected to live in the matching UnitTests project; integration tests for anything that touches RabbitMQ / MinIO / SQL Server.

Tailwind / DaisyUI CSS

Styling lives under src/Harpyx.WebApp/Styles and is compiled into wwwroot/css. The BuildTailwind MSBuild target runs on Release or when $(CI)=true:

cd src/Harpyx.WebApp
npm ci          # first time
npm run css:build

During day-to-day dev you can run npm run css:watch in a side terminal.

Troubleshooting

Symptom Likely cause
Cannot open database "Harpyx" SQL container not ready; wait on its health check or apply migrations
Uploads rejected in dev ClamAV still downloading signatures (first boot can take minutes)
OpenSearch security_exception at startup OPENSEARCH_INITIAL_ADMIN_PASSWORD must match OpenSearch__Password
Worker idles forever on new messages Check RabbitMQ management UI; queue/exchange declaration mismatch
OIDC sign-in loops EntraId:CallbackPath must match the Entra app reply URL

Clone this wiki locally