This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
DSP-API is the Digital Humanities Service Platform API - a Scala-based REST API for managing semantic data and digital assets in the humanities. The project uses ZIO for functional programming, zio-http as HTTP server and tapir for defining endpoints of the API, and integrates with Apache Jena Fuseki triplestore and Sipi media server.
- Primary:
sbt(Scala Build Tool) - use./sbtxwrapper script - Alternative:
just(command runner) for common tasks - Alternative:
makefor Docker and documentation tasks
Testing:
- Run a single test:
sbt "testOnly *TestClassName*" - Run tests in a specific package:
sbt "testOnly org.knora.webapi.slice.admin.*" sbt test- Run unit tests- Integration tests use
latestSipi image by default. To use exact git version locally, setSIPI_USE_EXACT_VERSION=trueor build withmake docker-build-sipi-image. make test-it- Run integration tests (requires Docker)make test-e2e- Run end-to-end HTTP API tests (requires Docker)make test-all- Run all tests
Code Quality:
sbt fmt- Format code with Scalafmtsbt check- Check code formatting and lintingsbt "scalafixAll --check"- Check Scalafix rules
Building:
sbt compile- Compile the projectmake docker-build- Build Docker imagesmake docker-build-dsp-api-image- Build only the API Docker image
Local Development Stack:
just stack-start- Start the full stack (Fuseki, Sipi, API)just stack-start-dev- Start stack without API (for development)just stack-stop- Stop the stackjust stack-init-test- Initialize with test data
The codebase is organized into several key modules:
Core Modules:
webapi/- Main API applicationmodules/bagit/- BagIt library for creating, reading, and validating BagIt packages (RFC 8493, https://www.rfc-editor.org/rfc/rfc8493)modules/testkit/- Shared test utilities and base classesmodules/test-it/- Integration tests (service/repo/Sipi tests)modules/test-e2e/- End-to-end HTTP API testssipi/- Custom Sipi media server configuration
Slice Architecture (webapi/src/main/scala/org/knora/webapi/slice/):
admin/- Administrative endpoints (users, groups, projects, permissions)common/- Shared utilities and base classesinfrastructure/- Cross-cutting concerns (metrics, caching, JWT)lists/- List management functionalityontology/- Ontology managementresources/- Resource and value managementsearch/- Search functionalitysecurity/- Authentication and authorizationshacl/- SHACL validation
Each slice typically contains:
api/- REST endpoints and routesdomain/- Business logic and domain modelsrepo/- Data access layer
- Language: Scala 3.3.5
- Framework: ZIO 2.x for functional programming
- HTTP: Pekko HTTP (Apache Pekko) with Tapir for endpoint definition
- Database: Apache Jena Fuseki (RDF triplestore)
- Media Server: Sipi (C++ media server)
- Testing: ZIO Test framework, some ScalaTests exist but will be migrated to ZIO Test
- JSON: ZIO JSON for serialization
- Functional Programming: Heavy use of ZIO effects
- Repository Pattern: Data access abstraction
- Service Layer: Business logic separation
- Dependency Injection: ZIO layers for service composition
- Unit tests:
webapi/src/test/scala/ - Integration tests:
modules/test-it/src/test/scala/ - End-to-end tests:
modules/test-e2e/src/test/scala/ - Shared test utilities:
modules/testkit/src/main/scala/ - Tests are organized by module following the main source structure
- Unit tests run against in-memory implementations
- Integration tests use Testcontainers for real database/service instances
- Test data located in
test_data/directory - Project ontologies in
test_data/project_ontologies/ - Project data in
test_data/project_data/
- JDK Temurin 21
- sbt
- Docker Desktop
- just (optional)
- Scala 3.3.X
- Start the development stack:
just stack-start-dev - This provides Fuseki (port 3030) and Sipi (port 1024)
- Run the API locally via IDE or
sbt run - API will be available at http://localhost:3333
When changes are hard to test with local test data (e.g. they need realistic data), run the API against the remote dev Fuseki:
- Create a
.envfile in the repo root withDEV_DB_PASSWORD=<password>(this file is git-ignored). Passwords can be found in ops-deploy/host_vars. - Run
just run-with-dev-db - The API will start connected to
db.dev.dasch.swissvia HTTPS
- Main config:
webapi/src/main/resources/application.conf - Test config:
webapi/src/test/resources/test.conf - Docker config:
docker-compose.yml
- Uses Tapir for type-safe endpoint definitions
- Endpoints defined in
*Endpoints.scalafiles - Handlers in
*EndpointsHandler.scalafiles - Routes in
*Routes.scalafiles
- Admin API: Administrative functions
- API v2: Main application API
- Management API: Health checks and metrics
- JWT-based authentication
- Scopes for authorization
- Session management
- Define endpoint in the appropriate
*Endpoints.scala - Connect endpoint definition with server logic in
*ServerEndpoints.scala - Register in
CompleteApiServerEndpoints.scala - Add unit/integration tests mirroring the main structure
- Use Scalafmt for formatting
- Follow functional programming principles
- Prefer ZIO effects over side effects
- Use meaningful names and types
- Docker: Ensure Docker Desktop is running
- Database: Check Fuseki is accessible at localhost:3030
- Tests: Integration tests require built Docker images
- Use
make stack-logsto view all service logs - Check
make stack-healthfor API health status - Use
make stack-statusto see container status