Skip to content

feat: add GuardLinker to create PROTECTS edges between GUARD/MIDDLEWARE and ENDPOINT nodes#14

Merged
aksOps merged 4 commits into
mainfrom
feat/guard-linker-protects-edges
Apr 3, 2026
Merged

feat: add GuardLinker to create PROTECTS edges between GUARD/MIDDLEWARE and ENDPOINT nodes#14
aksOps merged 4 commits into
mainfrom
feat/guard-linker-protects-edges

Conversation

@aksOps

@aksOps aksOps commented Apr 1, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Implements RAN-61: GuardLinker wires security architecture into the graph
  • New GuardLinker (@Component, Linker) groups GUARD and MIDDLEWARE nodes by file path and creates PROTECTS edges to ENDPOINT nodes in the same file
  • Covers Spring @PreAuthorize/@Secured (class and method level), Django auth, FastAPI auth, NestJS guards, and Express/Koa middleware — any node with NodeKind.GUARD or NodeKind.MIDDLEWARE
  • Uses TreeMap/TreeSet for deterministic output per project conventions
  • Deduplicates against pre-existing PROTECTS edges

Test plan

  • linksGuardToEndpointInSameFile — basic positive match
  • linksMiddlewareToEndpointInSameFile — MIDDLEWARE kind covered
  • classLevelGuardProtectsAllEndpointsInSameFile — one guard → multiple endpoints
  • guardInDifferentFileDoesNotProtectEndpoint — negative: cross-file guards skipped
  • noGuardsReturnsEmpty — early-exit path
  • noEndpointsReturnsEmpty — early-exit path
  • avoidsDuplicateEdges — pre-existing PROTECTS edge not duplicated
  • nodesWithNullFilePathAreIgnored — null filePath safety
  • determinismRunTwiceProducesSameResult — same input → same edge ordering
  • Full suite: 1468 tests, 0 failures

🤖 Generated with Claude Code

aksOps and others added 4 commits April 1, 2026 16:11
…her query

Added GraphStore.findEndpointNeighborsBatch() that fetches all endpoint
neighbors for a list of node IDs in one MATCH ... WHERE n.id IN $nodeIds
query, eliminating up to 50 separate findNeighbors() calls per invocation.

QueryService.findRelatedEndpoints() now separates the direct-endpoint pass
from the neighbor pass, using the new batch method for the latter. Deduplication
and connected_via semantics are preserved.

Added 3 unit tests covering: batch usage (verifying findNeighbors is never
called), direct endpoint matches, and deduplication.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
…s for search

Store label_lower and fqn_lower on every node during bulkSave() so that
case-insensitive search can hit a B-tree index instead of doing a full
graph scan with toLower() on both sides of the CONTAINS predicate.

- nodeToProps(): adds label_lower/fqn_lower to the Neo4j property map
- bulkSave(): creates indexes on label_lower and fqn_lower
- EnrichCommand: creates label_lower/fqn_lower indexes alongside kind/layer/module/filePath
- GraphStore.search(text, limit): lowercase input, query against pre-lowered props
- GraphRepository.search(): same query update (SDN path)
- nodeFromNeo4j(): label_lower/fqn_lower implicitly excluded (no prop_ prefix)

All 1459 tests pass.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
…RE and ENDPOINT nodes

Implements RAN-61. GuardLinker uses file-path proximity (same file = match)
to infer that guards and middleware in a file protect endpoints in that file.
This surfaces security architecture in the graph for Spring @PreAuthorize,
@secured, DjangoAuth, FastAPIAuth, NestJSGuards, and generic middleware nodes.

- 9 unit tests: positive match, middleware, class-level, cross-file negative,
  no-guards, no-endpoints, duplicate avoidance, null filePath, determinism
- 1468 total tests pass, 0 failures

Co-Authored-By: Paperclip <noreply@paperclip.ing>
…tection

- Add GUARD, MIDDLEWARE, TOPIC, QUEUE, EVENT, MESSAGE_QUEUE to ENTRY_POINT_KINDS
  so they are never flagged as dead code (they are entry points / cross-cutting concerns)
- Remove invalid 'uses' edge kind from SEMANTIC_EDGE_KINDS (not a valid EdgeKind)
- Add 'protects' to SEMANTIC_EDGE_KINDS so PROTECTS edges from GuardLinker count
  as semantic usage when determining reachability
- Add two new tests: verifying new entry point kinds are excluded, and verifying
  'protects' is included / 'uses' is excluded from semantic edge kinds

Co-Authored-By: Paperclip <noreply@paperclip.ing>
@sonarqubecloud

sonarqubecloud Bot commented Apr 1, 2026

Copy link
Copy Markdown

Quality Gate Failed Quality Gate failed

Failed conditions
75.4% Coverage on New Code (required ≥ 80%)

See analysis details on SonarQube Cloud

@aksOps aksOps merged commit 8b81027 into main Apr 3, 2026
9 of 10 checks passed
@aksOps aksOps deleted the feat/guard-linker-protects-edges branch April 3, 2026 15:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant