Packages

A framework for services over RDF repositories based on the DCAT-R vocabulary.

Current section

Files

Jump to
dcatr CLAUDE.md
Raw

CLAUDE.md

# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## Project Overview
DCAT-R.ex (DCAT for RDF repositories) is an Elixir library that extends DCAT for representing RDF datasets as hierarchical DCAT catalog structures. It provides a standardized pattern for organizing RDF repositories with clear separation between repository data and service configuration.
**Project Status**: Unpublished/pre-release - API changes can be made freely without compatibility concerns.
Key concepts:
- **Four-level hierarchy**: Service → Repository → Dataset → Graph
- **Repository**: Global/static RDF data container with dataset and metadata
- **Service**: Local configuration and runtime for accessing a repository
- **Graph types**: DataGraph (user data), SystemGraph, ManifestGraph, RepositoryManifestGraph, ServiceManifestGraph, WorkingGraph
- **Dual naming**: Support for both distributed and local graph names
The library provides RDFS/OWL vocabulary definitions (`priv/vocabs/dcat-r.ttl`) with corresponding Grax schemas for Elixir integration.
## Development Commands
```bash
# Install dependencies
mix deps.get
# via .envrc and direnv this is equivalent to
RDF_EX_PACKAGES_SRC=LOCAL mix deps.get
# Compile the project
mix compile
# Run tests
mix test
# Run a specific test file
mix test test/dcatr/repository_test.exs
# Format code
mix format
# Comprehensive check (clean, compile with warnings, format check, test)
mix check
# Compile with strict warnings
mix compile --all-warnings --warnings-as-errors
# Interactive console
iex -S mix
```
## Project Structure
**Directory Organization Convention**: This project uses subdirectories for code organization without corresponding module namespaces. For example, `lib/dcatr/model/` contains files but modules are named `DCATR.Service`, not `DCATR.Model.Service`. This keeps the public API clean while maintaining good file organization.
### Core Infrastructure
- `lib/dcatr.ex` - Main module entry point
- `lib/dcatr/application.ex` - OTP Application
- `lib/dcatr/ns.ex` - RDF.Vocabulary.Namespace definitions
- `lib/dcatr/exceptions.ex` - Exception definitions for structured error handling
- `lib/dcatr/utils.ex` - Shared utilities
### Model Layer (Domain Schemas)
Located in `lib/dcatr/model/` - All Grax schemas representing DCAT-R domain entities (no `DCATR.Model.*` namespace):
**Core Schemas**:
- `lib/dcatr/model/service.ex` - Service schema (`DCATR.Service` - DataService subclass)
- `lib/dcatr/model/repository.ex` - Repository schema (`DCATR.Repository` - Catalog subclass)
- `lib/dcatr/model/service_data.ex` - Service data schema (`DCATR.ServiceData`)
- `lib/dcatr/model/dataset.ex` - Dataset schema (`DCATR.Dataset` - catalog of graphs)
- `lib/dcatr/model/graph_resolver.ex` - GraphResolver behaviour (`DCATR.GraphResolver`)
- `lib/dcatr/model/graph.ex` - Base graph schema (`DCATR.Graph` - named graph representation)
**Type Behaviours** (subdirectories for supporting files):
- `lib/dcatr/model/repository/type.ex` - Repository type behaviour
- `lib/dcatr/model/service/type.ex` - Service type behaviour
- `lib/dcatr/model/service_data/type.ex` - Service data type behaviour
**Graph Type Hierarchy** (`lib/dcatr/model/graph_types/` subdirectory):
- `lib/dcatr/model/graph_types/data_graph.ex` - User data graphs (`DCATR.DataGraph`)
- `lib/dcatr/model/graph_types/system_graph.ex` - System-level graphs base class (`DCATR.SystemGraph`)
- `lib/dcatr/model/graph_types/manifest_graph.ex` - Base class for manifest graphs (`DCATR.ManifestGraph`)
- `lib/dcatr/model/graph_types/repository_manifest_graph.ex` - Repository manifest (`DCATR.RepositoryManifestGraph`)
- `lib/dcatr/model/graph_types/service_manifest_graph.ex` - Service manifest (`DCATR.ServiceManifestGraph`)
- `lib/dcatr/model/graph_types/working_graph.ex` - Working graphs for local operations (`DCATR.WorkingGraph`)
### Manifest System
Located in `lib/dcatr/manifest/` - Manifest loading and generation system (with `DCATR.Manifest.*` namespace):
- `lib/dcatr/manifest/manifest.ex` - Main manifest module
- `lib/dcatr/manifest/loader.ex` - Manifest loading
- `lib/dcatr/manifest/generator.ex` - Manifest generation
- `lib/dcatr/manifest/type.ex` - Manifest type behaviour
- `lib/dcatr/manifest/load_path.ex` - Load path handling
- `lib/dcatr/manifest/graph_expansion.ex` - Graph expansion utilities
- `lib/dcatr/manifest/cache.ex` - Manifest caching
### Tests
- `test/support/case.ex` - Shared test case setup
- `test/support/test_factories.ex` - Test factories for creating test fixtures
- `test/dcatr_test.exs` - Main module tests
- `test/dcatr/repository_test.exs` - Repository schema tests
- `test/dcatr/service_test.exs` - Service schema tests
- `test/dcatr/dataset_test.exs` - Dataset schema tests
- `test/dcatr/graph_test.exs` - Graph schema tests
### Knowledge Base & Documentation
- `priv/vocabs/dcat-r.ttl` - DCAT-R vocabulary definitions
- `magma/spec/` - DCAT-R specification sections (symlink to spec docs)
- `magma/kb/dcat-r-dev-base.md` - Comprehensive development knowledge base
- `magma/issues/` - Linear issue documentation (MAR-* issues)
- `magma/kb/deps/rdf-ex-base.md` - RDF.ex reference documentation
- `magma/kb/deps/grax-base.md` - Grax reference documentation
- `magma/kb/deps/rfs-dev-base.md` - Comprehensive development knowledge base of the RFS project - an important user of this library
- `magma/kb/` - Additional project documentation and reference materials
## Dependencies
The project uses RDF.ex ecosystem packages with local development option:
- `rdf` (~> 2.0) - RDF data model implementation
- `grax` (~> 0.6) - Graph to Elixir mapping (RDF to structs)
- `magma` - Development tool for prompts, documentation and knowledge (dev only)
- `credo` (~> 1.7) - Static code analysis (dev/test)
- `dialyxir` (~> 1.4) - Dialyzer integration (dev/test)
Note: `dcat` dependency is currently commented out but might be integrated
## API Documentation via Dash
API documentation for dependencies is available through Dash via MCP integration.
**When to use Dash documentation:**
- When working with RDF.ex, Grax, or other dependencies and you need to verify API signatures, options, or behavior
- Before implementing functionality that uses library APIs you're not certain about
- When encountering errors or unexpected behavior with dependency APIs
- To check available functions, modules, or types in a dependency
**How to use:**
Use the `mcp__dash-api__search_documentation` tool with the appropriate docset identifier from the list below. Search by module name, function name, or keywords.
**Available Docsets:**
- Elixir: `vwquetfy`
- RDF.ex: `jemfejvz`
- Grax: `qzmobytw`
- SPARQL: `bmihmdam`
- SPARQL Client: `ihvobpfs`
- JSON-LD: `ivouhaek`
- RDF.XML: `skzpwlxx`
- Credo: `mzupyfpj`
- Dialyxir: `dadycksz`
- ExDoc: `dkudngdy`
## Development Guidelines
### Error Handling
- Use exception structs instead of simple atoms for structured error information
- Define exceptions in `lib/dcatr/exceptions.ex` with proper `defexception` and `message/1` implementation
- Return errors as `{:error, %ExceptionModule{}}` tuples instead of `{:error, :atom}`
- Exception modules should be excluded from test coverage in `mix.exs` (see `ignore_modules`)
### Testing Approach: Exact-First Testing
Use exact comparisons (`==`) as the default, falling back to less precise methods only when necessary:
1. `==` with complete struct (expected on right side)
2. Pattern matching (when exact values are impractical)
3. Individual field assertions (last resort)
Use factories from `test/support/test_factories.ex`; extend them when useful.
### Test Coverage
- Maintain maximum useful test coverage for all production code
- Run coverage with: `mix test --cover`
- Detailed HTML coverage reports are in `cover/`
- View uncovered lines for a module: `grep -A 1 '<tr class="miss">' cover/Elixir.ModuleName.html`
- Coverage configuration in `mix.exs`
### Documentation Style
- Minimal and focused, document "why" not "what"
- Use hyphens for lists in documentation
- Include "## Options" section for opts when relevant
- Include "## Examples" section with ExDoc doctests when setup is straightforward
- Keep moduledocs concise and focused on the module's purpose
### Commit Conventions
- Short commits (<80 chars) starting with capital letter verb
- No conventional commit prefixes
- Examples: "Add DCAT-R vocabulary definitions", "Define Repository class hierarchy"
## Architecture Notes
### Repository Structure
A Repository contains:
- **dataset**: The primary dataset (required)
- **metadata_graph**: Repository metadata as RepositoryManifestGraph
- **system_graphs**: Additional system-level graphs (like a history graph on a Ontogen repository)
- **private_graphs**: Local/private graphs not for distribution
### Service Model
Services provide local runtime access to repositories:
- Multiple services can serve the same repository
- Each service has its own configuration graph
- Services are modeled as DCAT DataServices
### Graph Hierarchy
All graphs inherit from `DCATR.Graph` base class:
- `DataGraph`: User data within the dataset
- `SystemGraph`: Base for system-level graphs
- `ManifestGraph`: Base for manifest graphs (extends SystemGraph)
- `RepositoryManifestGraph`: Repository metadata manifest
- `ServiceManifestGraph`: Service configuration manifest
- `WorkingGraph`: Working graphs for local operations
## Testing
Tests use ExUnit and follow standard Elixir testing patterns.
The test suite verifies proper DCAT subclassing and RDF property mappings.
### Test Factories
The project provides comprehensive test factories in `test/support/test_factories.ex` for creating test fixtures. Factories follow a three-tier approach:
**Basic Factories** - Wrap schema `build/2` functions with sensible defaults:
- `data_graph/1`, `system_graph/1`, `repository_manifest_graph/1`, `service_manifest_graph/1`, `working_graph/1`
- `dataset/1` - Creates a dataset with optional graphs
- `repository/1` - Creates a repository with dataset, manifest, and optional system graphs
- `service_data/1` - Creates service data with manifest and optional working graphs
- `service/1` - Creates a complete service with repository and local data
**Example Factories** - Provide fixed IDs for predictable test scenarios:
- `example_data_graph/1`, `example_data_graphs/1` - Single or multiple data graphs with IDs like `EX.DataGraph1`
- `example_repository/1` - Complete repository with fixed IDs for all components
- `example_service_data/1` - Service data with fixed IDs
- `example_service/1` - Complete service with fixed IDs
**Scenario Functions** - For use with ExUnit's `setup :function_name` pattern:
- `example_dataset_scenario/1` - Returns `%{dataset: ..., data_graphs: [...]}`
- `example_repository_scenario/1` - Returns `%{repo: ..., dataset: ..., data_graphs: [...], repo_manifest: ..., system_graphs: [...]}`
- `example_service_data_scenario/1` - Returns `%{service_data: ..., service_manifest: ..., working_graphs: [...], local_system_graphs: [...]}`
- `example_service_scenario/1` - Merges all scenarios, adds `service:`
## Respond-in-file Rule
When instructed to apply the respond-in-file rule with a specific file path:
1. **Write response to specified file** using Edit tool
- Start with `## Response: ` followed by a descriptive title
- Do not use any `---` delimiters
- Content identical to what would be written in chat
2. **Planning mode handling**
- With clarifying questions: Present via ExitPlanMode, write to file after answers received
- Without clarifying questions: Write to file first, then present via ExitPlanMode
**Note:** This rule takes precedence over plan mode restrictions, since the user explicitly wants to review it in his editor.
3. **Never output main response in chat** - always use Edit tool
4. **Post-response**: Return to conversation and confirm completion