# jmanuelbr/aem-groups-graph architecture

> Architecture diagram of the GitHub repository jmanuelbr/aem-groups-graph, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-09-26). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/jmanuelbr/aem-groups-graph
- Repository: https://github.com/jmanuelbr/aem-groups-graph

## Overview

Groups Membership Graph is an AEM author-side administrator tool for exploring direct and inherited group membership. An administrator opens the tool, selects a user or group with AEM’s built-in autocomplete, and the browser requests a protected graph endpoint. The servlet authorizes the request and invokes breadth-first membership traversal using the caller’s resolver; returned nodes and edges feed Cytoscape visualization, including depth coloring, built-in-group filtering, path tracing, and details. The README documents the page-level access guard and UI capabilities; the graph shows only wiring evidenced by the supplied source and documentation.

Main entry points: [`ui.apps/src/main/content/jcr_root/apps/groupsgraph/clientlibs/clientlib-tool/js/graph.js`](https://github.com/jmanuelbr/aem-groups-graph/blob/master/ui.apps/src/main/content/jcr_root/apps/groupsgraph/clientlibs/clientlib-tool/js/graph.js) (Interactive graph), [`core/src/main/java/io/github/jmanuelbr/groupsgraph/core/servlets/GraphDataServlet.java`](https://github.com/jmanuelbr/aem-groups-graph/blob/master/core/src/main/java/io/github/jmanuelbr/groupsgraph/core/servlets/GraphDataServlet.java) (Graph endpoint), [`ui.apps/src/main/content/jcr_root/apps/groupsgraph/components/page/page.html`](https://github.com/jmanuelbr/aem-groups-graph/blob/master/ui.apps/src/main/content/jcr_root/apps/groupsgraph/components/page/page.html) (Tool page), [`core/src/main/java/io/github/jmanuelbr/groupsgraph/core/graph/impl/MembershipGraphServiceImpl.java`](https://github.com/jmanuelbr/aem-groups-graph/blob/master/core/src/main/java/io/github/jmanuelbr/groupsgraph/core/graph/impl/MembershipGraphServiceImpl.java) (Membership traversal)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_ui["Author UI"]
  node_page["Tool page<br/>[page.html]"]
  node_picker["Principal picker<br/>[page.html]"]
  node_controller["Graph controller<br/>[graph.js]"]
  node_visualization["Interactive graph<br/>[graph.js]"]
  node_details["Node details<br/>[graph.js]"]
  node_builtinfilter["Built-in filter<br/>[graph.js]"]
end

subgraph group_access["Access control"]
  node_accessmodel["Page access model"]
  node_principalaccess["Admin check"]
end

subgraph group_graph["Graph service"]
  node_endpoint["Graph endpoint"]
  node_service["Membership traversal"]
  node_graphdata["Graph result<br/>[GraphData.java]"]
  node_nodes["Graph nodes<br/>[GraphNode.java]"]
  node_edges["Membership edges<br/>[GraphEdge.java]"]
end

node_admin(("Administrator"))
node_autocomplete["AEM autocomplete"]
node_userrepo[("AEM authorizables")]
node_cytoscape["Cytoscape.js"]

node_admin -->|"opens"| node_page
node_page -->|"renders with"| node_accessmodel
node_accessmodel -->|"checks access"| node_principalaccess
node_page -->|"renders"| node_picker
node_picker -->|"uses"| node_autocomplete
node_admin -->|"selects principal"| node_controller
node_controller -->|"requests graph"| node_endpoint
node_endpoint -->|"checks access"| node_principalaccess
node_endpoint -->|"builds graph"| node_service
node_service -->|"reads memberships"| node_userrepo
node_service -->|"produces"| node_graphdata
node_graphdata -->|"contains"| node_nodes
node_graphdata -->|"contains"| node_edges
node_endpoint -->|"returns JSON"| node_controller
node_controller -->|"renders result"| node_visualization
node_visualization -->|"draws layout"| node_cytoscape
node_visualization -->|"applies toggle"| node_builtinfilter
node_visualization -->|"opens on click"| node_details

click node_page "https://github.com/jmanuelbr/aem-groups-graph/blob/master/ui.apps/src/main/content/jcr_root/apps/groupsgraph/components/page/page.html"
click node_accessmodel "https://github.com/jmanuelbr/aem-groups-graph/blob/master/core/src/main/java/io/github/jmanuelbr/groupsgraph/core/models/ToolAccessModel.java"
click node_principalaccess "https://github.com/jmanuelbr/aem-groups-graph/blob/master/core/src/main/java/io/github/jmanuelbr/groupsgraph/core/security/PrincipalAccess.java"
click node_picker "https://github.com/jmanuelbr/aem-groups-graph/blob/master/ui.apps/src/main/content/jcr_root/apps/groupsgraph/components/page/page.html"
click node_controller "https://github.com/jmanuelbr/aem-groups-graph/blob/master/ui.apps/src/main/content/jcr_root/apps/groupsgraph/clientlibs/clientlib-tool/js/graph.js"
click node_endpoint "https://github.com/jmanuelbr/aem-groups-graph/blob/master/core/src/main/java/io/github/jmanuelbr/groupsgraph/core/servlets/GraphDataServlet.java"
click node_service "https://github.com/jmanuelbr/aem-groups-graph/blob/master/core/src/main/java/io/github/jmanuelbr/groupsgraph/core/graph/impl/MembershipGraphServiceImpl.java"
click node_graphdata "https://github.com/jmanuelbr/aem-groups-graph/blob/master/core/src/main/java/io/github/jmanuelbr/groupsgraph/core/graph/GraphData.java"
click node_nodes "https://github.com/jmanuelbr/aem-groups-graph/blob/master/core/src/main/java/io/github/jmanuelbr/groupsgraph/core/graph/GraphNode.java"
click node_edges "https://github.com/jmanuelbr/aem-groups-graph/blob/master/core/src/main/java/io/github/jmanuelbr/groupsgraph/core/graph/GraphEdge.java"
click node_visualization "https://github.com/jmanuelbr/aem-groups-graph/blob/master/ui.apps/src/main/content/jcr_root/apps/groupsgraph/clientlibs/clientlib-tool/js/graph.js"
click node_details "https://github.com/jmanuelbr/aem-groups-graph/blob/master/ui.apps/src/main/content/jcr_root/apps/groupsgraph/clientlibs/clientlib-tool/js/graph.js"
click node_builtinfilter "https://github.com/jmanuelbr/aem-groups-graph/blob/master/ui.apps/src/main/content/jcr_root/apps/groupsgraph/clientlibs/clientlib-tool/js/graph.js"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_page,node_picker,node_controller,node_visualization,node_details,node_builtinfilter toneBlue
class node_accessmodel,node_principalaccess,node_userrepo toneAmber
class node_endpoint,node_service,node_graphdata,node_nodes,node_edges toneMint
class node_admin,node_autocomplete,node_cytoscape toneIndigo
```

## Components

### Author UI

- [Tool page](https://github.com/jmanuelbr/aem-groups-graph/blob/master/ui.apps/src/main/content/jcr_root/apps/groupsgraph/components/page/page.html): `ui.apps/src/main/content/jcr_root/apps/groupsgraph/components/page/page.html`
- [Principal picker](https://github.com/jmanuelbr/aem-groups-graph/blob/master/ui.apps/src/main/content/jcr_root/apps/groupsgraph/components/page/page.html): `ui.apps/src/main/content/jcr_root/apps/groupsgraph/components/page/page.html`
- [Graph controller](https://github.com/jmanuelbr/aem-groups-graph/blob/master/ui.apps/src/main/content/jcr_root/apps/groupsgraph/clientlibs/clientlib-tool/js/graph.js): `ui.apps/src/main/content/jcr_root/apps/groupsgraph/clientlibs/clientlib-tool/js/graph.js`
- [Interactive graph](https://github.com/jmanuelbr/aem-groups-graph/blob/master/ui.apps/src/main/content/jcr_root/apps/groupsgraph/clientlibs/clientlib-tool/js/graph.js): `ui.apps/src/main/content/jcr_root/apps/groupsgraph/clientlibs/clientlib-tool/js/graph.js`
- [Node details](https://github.com/jmanuelbr/aem-groups-graph/blob/master/ui.apps/src/main/content/jcr_root/apps/groupsgraph/clientlibs/clientlib-tool/js/graph.js): `ui.apps/src/main/content/jcr_root/apps/groupsgraph/clientlibs/clientlib-tool/js/graph.js`
- [Built-in filter](https://github.com/jmanuelbr/aem-groups-graph/blob/master/ui.apps/src/main/content/jcr_root/apps/groupsgraph/clientlibs/clientlib-tool/js/graph.js): `ui.apps/src/main/content/jcr_root/apps/groupsgraph/clientlibs/clientlib-tool/js/graph.js`

### Access control

- [Page access model](https://github.com/jmanuelbr/aem-groups-graph/blob/master/core/src/main/java/io/github/jmanuelbr/groupsgraph/core/models/ToolAccessModel.java): `core/src/main/java/io/github/jmanuelbr/groupsgraph/core/models/ToolAccessModel.java`
- [Admin check](https://github.com/jmanuelbr/aem-groups-graph/blob/master/core/src/main/java/io/github/jmanuelbr/groupsgraph/core/security/PrincipalAccess.java): `core/src/main/java/io/github/jmanuelbr/groupsgraph/core/security/PrincipalAccess.java`

### Graph service

- [Graph endpoint](https://github.com/jmanuelbr/aem-groups-graph/blob/master/core/src/main/java/io/github/jmanuelbr/groupsgraph/core/servlets/GraphDataServlet.java): `core/src/main/java/io/github/jmanuelbr/groupsgraph/core/servlets/GraphDataServlet.java`
- [Membership traversal](https://github.com/jmanuelbr/aem-groups-graph/blob/master/core/src/main/java/io/github/jmanuelbr/groupsgraph/core/graph/impl/MembershipGraphServiceImpl.java): `core/src/main/java/io/github/jmanuelbr/groupsgraph/core/graph/impl/MembershipGraphServiceImpl.java`
- [Graph result](https://github.com/jmanuelbr/aem-groups-graph/blob/master/core/src/main/java/io/github/jmanuelbr/groupsgraph/core/graph/GraphData.java): `core/src/main/java/io/github/jmanuelbr/groupsgraph/core/graph/GraphData.java`
- [Graph nodes](https://github.com/jmanuelbr/aem-groups-graph/blob/master/core/src/main/java/io/github/jmanuelbr/groupsgraph/core/graph/GraphNode.java): `core/src/main/java/io/github/jmanuelbr/groupsgraph/core/graph/GraphNode.java`
- [Membership edges](https://github.com/jmanuelbr/aem-groups-graph/blob/master/core/src/main/java/io/github/jmanuelbr/groupsgraph/core/graph/GraphEdge.java): `core/src/main/java/io/github/jmanuelbr/groupsgraph/core/graph/GraphEdge.java`

### Other components

- **Administrator**
- **AEM autocomplete**
- **AEM authorizables**
- **Cytoscape.js**

## Connections

- Administrator → Tool page: opens
- Tool page → Page access model: renders with
- Page access model → Admin check: checks access
- Tool page → Principal picker: renders
- Principal picker → AEM autocomplete: uses
- Administrator → Graph controller: selects principal
- Graph controller → Graph endpoint: requests graph
- Graph endpoint → Admin check: checks access
- Graph endpoint → Membership traversal: builds graph
- Membership traversal → AEM authorizables: reads memberships
- Membership traversal → Graph result: produces
- Graph result → Graph nodes: contains
- Graph result → Membership edges: contains
- Graph endpoint → Graph controller: returns JSON
- Graph controller → Interactive graph: renders result
- Interactive graph → Cytoscape.js: draws layout
- Interactive graph → Built-in filter: applies toggle
- Interactive graph → Node details: opens on click
