3.7 KiB
Szpitale-graph — agent instructions
TL;DR: cd szpitale-graph && ./mvnw -q compile (wrapper, not mvn). Build lives in szpitale-graph/. Neo4j via docker compose up -d from same dir. CLAUDE.md has full TDD rules and PLAN2.md has the execution backlog. This file covers what CLAUDE.md doesn't.
Project location & structure
- Application root:
szpitale-graph/(not the repo root). - All Maven commands run from
szpitale-graph/using./mvnw. - Source:
src/main/java/com/developx/szpitale/ - Tests:
src/test/java/com/developx/szpitale/(mirror packages)
Key commands
| Task | Command |
|---|---|
| Compile | ./mvnw -q compile |
| Test single | ./mvnw -q test -Dtest=ClassName |
| All tests | ./mvnw -q test |
| Verify | ./mvnw -q verify |
| Run CLI | java -jar target/szpitale-graph.jar |
| Neo4j up | docker compose up -d |
| Neo4j down | docker compose down -v |
Architecture (two layers, JSON between them)
ingest (layer 1) ──canonical/*.json──→ load (layer 2 → Neo4j)
- Ingest = source parsing + normalisation + dedup. No Neo4j dependency.
- Load = canonical JSON → UNWIND/MERGE into Neo4j. No network dependency.
- Canonical files:
canonical/<voivodeship>.jsonorcanonical/all.json.
Code layout (src/main/java/com/developx/szpitale/)
| Package | Purpose |
|---|---|
model/ |
CanonicalDataset, Hospital, Person, Affiliation, Role, Mandate, RawHospitalRecord |
model/enums/ |
LegalForm, RoleType, MandateType, ConfidenceLevel, RoleStatus, AffiliationType, OrganType, SupervisoryBodyType |
ingest/ |
IngestCommand, CanonicalWriter, IngestResults |
ingest/source/ |
MarkdownRegistrySource (parses research-*.md), VoivodeshipSource (interface) |
ingest/normalize/ |
NameNormalizer, PartyNormalizer, Deduplicator |
load/ |
LoadCommand, CanonicalReader, GraphSchema, GraphLoader, GraphValidator |
SzpitaleGraphApplication.java |
@SpringBootApplication entry point |
Data format
Research files: research-<voivodeship>.md (e.g. research-podlaskie.md). Table header:
| Funkcja | Imię i nazwisko | Afiliacja partyjna | Źródło (URL) |
Every cell must have an https://... URL. No URL = BRAK_DANYCH or skip.
Current state: build is broken (T1 blocker)
Deduplicator.java:75 — groups is Map<String, List<Person>> but code puts List<String>. Fix needed before any test can run. See PLAN2.md §11, task T1.
Dependencies
- Spring Boot 3.4.4 (spring-shell, neo4j-starter, web)
- Jackson (databind + jsr310)
- Jsoup 1.18.3 (HTML/Mobile Markdown parsing)
- Commons Text 1.12.0 (Jaro-Winkler fuzzy match)
- Commons CSV 1.12.0 (reports)
- Lombok: declared in pom.xml but has NO
<version>— add one if you modify it - Spring Shell: declared in pom.xml with empty line — needs
<version>if you enable it - Testcontainers Neo4j 1.20.4 + JUnit Jupiter
Test conventions
- Tests mirror main package structure.
- Class-name based:
./mvnw -q test -Dtest=NameNormalizerTest - Integration tests (
*IT) use@Testcontainers+Neo4jContainer. - Fixture files →
src/test/resources/fixtures/
Git / checkpoint protocol
PLAN2.md mandates: one checkpoint commit per task (-m "T<n>: descript [checkpoint]"). The local-agent-progress.json file tracks task states. On conflicts, git log is the source of truth (PLAN2.md §13.5).
Getting a new voivodeship
- Deep-research → produce
research-<voiv>.mdin same table format asresearch-podlaskie.md - Place file in
old/or aresearch/directory - Run
ingest --voivodeship <voiv>→ generates canonical JSON - Run
load --voivodeship <voiv>→ pushes to Neo4j
No code changes needed to add a new region.