6.7 KiB
Deep API Audit — MultiTableImportJob + its complete call/wiring tree (the whole batch job)
Preconditions: Before you start this audit, run ./rebuild-and-refresh.sh and wait for its
"Both deep refreshes finished" banner. It stops the server, rebuilds + redeploys it (so the audit runs
against the current code), then deep-refreshes both upms and pur. For this audit prompt you are
explicitly authorized to run that script yourself — the standing "never deploy / never start Docker"
rule is waived for rebuild-and-refresh.sh in this context (only for this script; do not run
manage-ac.sh/docker directly). If the script fails, stop and report rather than proceeding against a
stale or down server. Do not interrupt the deep refresh once it is running.
Project: pur — a Java (Spring Batch) codebase. Root on host:
/home/ingo/deve/uniqa/pur-sources/backend (sources are .java, UTF-8; test/target are excluded
from ingest). Entry point under audit: the batch job class MultiTableImportJob.
Task
Perform a very deep analysis of all agentic API endpoints, in two tiers:
- Deep dive — MultiTableImportJob (worked example): ingest class MultiTableImportJob and, for each endpoint, determine whether the response is correct by manually reading the Java source and comparing it against the API output, field-by-field.
- Broad sweep — MultiTableImportJob's complete tree (the whole batch job): verify the same
endpoints across every module transitively reachable from MultiTableImportJob, i.e. the full
transitive closure of its
call-tree/graph— following not only method calls but the Java wiring edges (EXTENDS/IMPLEMENTS,INJECTS,REFERENCES,CONSTRUCTOR), to unlimited depth. This is the complete job that MultiTableImportJob fans out into (its steps, listeners, injected collaborators, base classes). Manual reading of every source at that scale is infeasible, so drive the sweep with automated cross-checks (below) that catch whole classes of defects, and escalate any module that fails a check to a manual, source-level deep dive like tier 1.
How to work
- Use the REST API (
GET /api/projects/pur/modules/{name}/...), falling back to theacCLI for quick manual checks. For MultiTableImportJob (and any escalated module) pull every relevant endpoint:callees,callers,db-accesses,functions,data-structures,dispatch-table,digest,context,call-tree,sql-statements,graph. - Read the Java source manually (the class plus its base classes, injected collaborators, and
referenced step/listener classes) and verify each response field-by-field: call/wiring graph, DB
accesses (READ/WRITE mode via JPA/JDBC/Spring Data), field/parameter reads/writes, type resolution,
dispatch table. Sources are UTF-8
.javafiles parsed with JavaParser. - Broad-sweep cross-checks (MultiTableImportJob's complete tree). Enumerate the full transitive
closure of modules reachable from MultiTableImportJob — pull its
call-tree/graphat unlimited depth (raise thedepthparameter until the module set stops growing andtruncatedis false; thegraphendpoint caps nodes, so if it staystruncateddrive the closure by iteratingcalleesbreadth-first instead), take everyMODULE-typed node, and iterate. Follow wiring as well as calls: a Spring Batch job reaches its steps/listeners/config throughINJECTS/REFERENCES, not plainMETHOD_CALL, so a calls-only closure misses most of the job. Then assert API-derivable invariants that need no per-module reading, e.g.:- No
MODULEself-loop:callers/calleesnever list a class as its own caller/callee. callersdefault is external-only: the default view lists incoming calls/wiring from other classes only (rolled up to the calling class) — never the class's own methods (those belong toscope=internalor the/functions/{fn}/callersendpoint), and never duplicated one-row-per-call-site.- Callee resolution matches source: every
calleestarget (METHOD_CALL,CONSTRUCTOR,EXTENDS/IMPLEMENTS,INJECTS,REFERENCES) appears as a real reference in the class source (a call,new,extends/implements, injected field/param, or type use — grep-verifiable), with correctedgeKindand provenance, and no phantom targets. Note JDK/library types (e.g.List,Map,ArrayList,HashMap) legitimately surface as unresolved external types — record how they are represented and treat them as a known, distinct class rather than a defect. - Method count parity:
digest.functionCount== the number of declared methods in the source (constructors handled consistently — state the rule); every method invoked internally exists as aFUNCTION. - DB access sanity: classes with no JPA/JDBC/Spring-Data access report empty
db-accesses/sql-statements; those with them resolve to realDB_TABLEs (or the entity/table they map to). A pure orchestrator (like the job class, which delegates persistence to its steps) must report empty — verify the DB access lives on the steps/repositories it wires, not the job. - Closure completeness: every callee/wiring target surfaced by any module in the tree is itself in the enumerated module set (the closure is self-consistent — no reachable project class is missed), excluding only explicitly-recognised JDK/third-party types. Rank modules by check failures; the worst offenders get a tier-1 manual deep dive.
- No
- Report every discrepancy you find. For each: the endpoint and exact wrong value, the ground truth from the source (with line references), and the suspected root cause in the parser/enricher/Cypher. For sweep findings, report the failing invariant, the count and list of affected modules, and a representative worked example.
- Propose a concrete fix for each error.
- Write failing characterization tests first (Testcontainers ITs with minimal Java fixtures that reproduce the bug), then confirm they go green after the fix.
Output
A structured report:
- Per-endpoint for MultiTableImportJob: PASS or the list of discrepancies with ground-truth evidence, root-cause hypothesis, fix proposal, and the test that covers it.
- Broad sweep (MultiTableImportJob tree closure): the enumerated module set (count + how depth was driven to completeness, and confirmation that wiring edges were followed), then per invariant PASS or the affected-module count + list + a worked example, with the same root-cause/fix/test treatment for each distinct defect class.