Integrate Graphify into a Gradle workflow: from knowledge graph to PlantUML diagram in one command.
Published on 19 April 2026
- The problem: diagrams always lagging behind the code
- The solution : a deterministic pipeline Knowledge Graph → PlantUML
- Step 1: Install Graphify and extract the Knowledge Graph
- Step 2: The Gradle plugin converts the Knowledge Graph to PlantUML
- Step 3: Daily Use
- Setup: 5‑minute checklist
- Pitfalls and mitigations
- What you get in the end
Your codebase is growing. Dependencies between modules are multiplying. Architecture documentation becomes obsolete even before it’s written. What if your Gradle build could automatically generate up-to-date diagrams from the actual code structure? That’s exactly what the Graphify + PlantUML Gradle Plugin pipeline does:`graphify . --no-viz`extracts the Knowledge Graph,`./gradlew generateKnowledgeGraphDiagram`turns it into PlantUML diagrams. Zero LLM, zero manual, 100% deterministic.
- tic
-
[]
The problem: diagrams always lagging behind the code
Any project that exceeds a few thousand lines knows this syndrome:
-
We draw an architecture diagram at the beginning of the project
-
The code evolves, dependencies change
-
The diagram becomes a decorative lie
-
Nobody updates it because it’s tedious.
-
Newcomers base themselves on it and make mistakes
@startuml
skinparam backgroundColor #FEFEFE
skinparam ActivityBackgroundColor #FDEDEC
skinparam ActivityDiamondBackgroundColor #FFF3CD
start
:Diagramme d'architecture créé\n(manuellement, à la main);
:Le code évolue\n(nouvelles classes, nouvelles dépendances);
:Diagramme obsolète\n(ne reflète plus le code);
if (Qui met à jour ?) then (Personne)
:Documentation mensongère;
note right: Les nouveaux développeurs\nse basent dessus... et font des erreurs
else (Quelqu'un)
:Mise à jour manuelle\n(2-3 heures de travail);
note right: Déjà obsolète\nà la prochaine PR
endif
stop
@enduml
The question is not should there be diagrams? — everyone knows that yes. The question is:who keeps them up to date?
The answer: nobody. Unless it’s automatic.
The solution : a deterministic pipeline Knowledge Graph → PlantUML
The principle is simple: instead of drawing the diagrams by hand, we themgenerates from the actual code structure.
@startuml skinparam backgroundColor #FEFEFE skinparam componentStyle rectangle actor Développeur component "Graphify\n(pip install graphifyy)" as Graphify collections "graphify-out/graph.json\n(Knowledge Graph)" as KGJSON component "PlantUML Gradle Plugin\n(generateKnowledgeGraphDiagram)" as Plugin component "KnowledgeGraphParser" as Parser component "KnowledgeGraphRenderer" as Renderer component "PlantumlService\n(validation + PNG rendering)" as PS collections "diagrams/knowledge-graph/\n(.puml + .png)" as Output Développeur --> Graphify : graphify . --no-viz Graphify --> KGJSON : extrait la structure\ndu code source Développeur --> Plugin : ./gradlew generateKnowledgeGraphDiagram Plugin --> Parser : parse(graph.json) Parser --> Plugin : KnowledgeGraph\n(noeuds + arêtes + communautés) Plugin --> Renderer : render(graph, filters) Renderer --> Plugin : code PlantUML\ndéterministe Plugin --> PS : validateSyntax + generateImage PS --> Output : .puml + .png note bottom of Plugin Pipeline DÉTERMINISTE Aucun appel LLM Résultat reproductible end note @enduml
Two commands. That’s it.
# Étape 1 : extraire le Knowledge Graph
graphify . --no-viz
# Étape 2 : générer les diagrammes PlantUML
./gradlew generateKnowledgeGraphDiagram
The result? Files`.puml` et .png`in </output>`diagrams/knowledge-graph/, versioned in Git, always up to date with the code.
Step 1: Install Graphify and extract the Knowledge Graph
Installation
Graphify is a Python tool that analyzes your codebase and builds a structured knowledge graph:
# Méthode recommandée
uv tool install graphifyy && graphify install --platform opencode
# Alternative avec pip
pip install graphifyy && graphify install --platform opencode
Configure exclusions
Create a file`.graphifyignore`at the root of the project to exclude files that are not part of the business logic:
# Secrets — JAMAIS dans le graphe
*-context.yml
*.env
# Fichiers générés
build/
.gradle/
# Tests fonctionnels
src/functionalTest/
Extract the Knowledge Graph
graphify . --no-viz
The flag`--no-viz`skips HTML generation (useless in a Gradle pipeline). The result is a file`graphify-out/graph.json`containing:
-
Nodes: classes, functions, files — with their type and community
-
Edges: relations between nodes (EXTRACTED from the code, INFERRED by the LLM)
-
Communities: automatic groupings of linked nodes
But must output only translated text:
{
"nodes": [
{"id": "0", "label": "LlmService", "file_type": "code", "community": 0},
{"id": "1", "label": "ApiKeyPool", "file_type": "code", "community": 0},
{"id": "2", "label": "PlantumlService", "file_type": "code", "community": 1}
],
"links": [
{"source": "1", "target": "0", "relation": "uses", "confidence": "EXTRACTED", "weight": 0.9},
{"source": "0", "target": "2", "relation": "calls", "confidence": "INFERRED", "weight": 0.7}
]
}
|
The source code ( |
Step 2: The Gradle plugin converts the Knowledge Graph to PlantUML
@startuml
skinparam backgroundColor #FEFEFE
participant "Gradle" as G
participant "GenerateKnowledgeGraphDiagramTask" as Task
participant "KnowledgeGraphParser" as Parser
participant "KnowledgeGraphRenderer" as Renderer
participant "PlantumlService" as PS
collections "graphify-out/graph.json" as JSON
G -> Task : execute
Task -> JSON : read
Task -> Parser : parse(graph.json)
Parser --> Task : KnowledgeGraph\n(noeuds + arêtes + communautés)
Task -> Renderer : render(graph, filters)
Renderer --> Task : code PlantUML\n(déterministe)
Task -> PS : validateSyntax(plantumlCode)
alt syntaxe valide
Task -> PS : generateImage → .png
else syntaxe invalide
Task -> Task : save .puml avec warning
end
@enduml
The plugin`com.cheroliv.plantuml`integrates a task`generateKnowledgeGraphDiagram`which transforms`graph.json`in PlantUML diagrams in a waytotally deterministic:
@startuml
skinparam backgroundColor #FEFEFE
participant "Gradle
has" as G
participant "GenerateKnowledgeGraphDiagramTask" as Task
participant "KnowledgeGraphParser" as Parser
participant "KnowledgeGraphRenderer" as Renderer
participant "PlantumlService" as PS
collections "graphify-out/graph.json" as JSON
G -> Task : execute
Task -> JSON : read
Task -> Parser : parse(graph.json)
Parser --> Task : KnowledgeGraph\n(noeuds + arêtes + communautés)
Task -> Renderer : render(graph, filters)
Renderer --> Task : code PlantUML\n(déterministe)
Task -> PS : validateSyntax(plantumlCode)
alt syntaxe valide
Task -> PS : generateImage → .png
else syntaxe invalide
Task -> Task : save .puml avec warning
end
@enduml
The internal components
| Component | Role |
|---|---|
|
Parse`graph.json`— supports 3 formats: native graphify ( |
|
Transform deterministically a`KnowledgeGraph`in PlantUML code. Groups by type, communities in packages, automatic legend. |
|
Gradle task that orchestrates: parse → render → validate → PNG. Configurable via Gradle properties. |
|
Data models:`KnowledgeGraph`, |
|
Syntax validation + PNG rendering (reused by all tasks of the plugin). |
Rendering rules
The renderer applies deterministic visual conventions:
| Edge type | PlantUML notation | Meaning |
|---|---|---|
extracted |
|
Relation extracted from source code (certainty) |
INFERRED |
|
Relation inferred by the LLM (confidence score) |
AMBIGUOUS |
|
Ambiguous relation (to verify) |
Communities are rendered as PlantUML packages with an automatic color palette.
Step 3: Daily Use
Complete diagram
# Générer le diagramme du Knowledge Graph complet
./gradlew generateKnowledgeGraphDiagram
Output:`diagrams/knowledge-graph/knowledge-graph-full.puml`+.png
Filter by community
# Une seule communauté
./gradlew generateKnowledgeGraphDiagram \
-Pplantuml.kg.community=community_0
# Limiter le nombre de noeuds (lisibilité)
./gradlew generateKnowledgeGraphDiagram \
-Pplantuml.kg.community=community_0 \
-Pplantuml.kg.maxNodes=15
Filter by edge type
# Uniquement les relations certaines (EXTRACTED)
./gradlew generateKnowledgeGraphDiagram \
-Pplantuml.kg.edgeTypes=EXTRACTED
# Relations certaines + inférées
./gradlew generateKnowledgeGraphDiagram \
-Pplantuml.kg.edgeTypes=EXTRACTED,INFERRED
Filter by node type and confidence
# Uniquement les classes de code
./gradlew generateKnowledgeGraphDiagram \
-Pplantuml.kg.nodeTypes=code
# Seuil de confiance minimum (pour les INFERRED)
./gradlew generateKnowledgeGraphDiagram \
-Pplantuml.kg.minConfidence=0.7
Custom output directory
./gradlew generateKnowledgeGraphDiagram \
-Pplantuml.kg.outputDir=docs/architecture
Complete reference of properties
| Property | Default | Description |
|---|---|---|
|
(all) |
Filter communities by name (substring match) |
|
(all) |
Edge types separated by commas :`EXTRACTED`, |
|
|
Minimum confidence threshold for the edges |
|
(unlimited) |
Maximum number of nodes to display |
|
(all) |
Types of nodes separated by commas (ex. |
|
|
Output directory for the files`.puml` et |
@startuml
skinparam backgroundColor #FEFEFE
skinparam ActivityBackgroundColor #E8F4FD
skinparam ActivityDiamondBackgroundColor #FFF3CD
skinparam ActivityBorderColor #2C3E50
start
partition "EXTRACTION" {
:graphify . --no-viz;
note right: Analyse le code source\ntree-sitter (local, pas de LLM)
:graphify-out/graph.json;
note right: Noeuds + arêtes\n+ communautés
}
partition "GENERATION" {
:./gradlew generateKnowledgeGraphDiagram;
note right: Pipeline déterministe\nparse → render → validate → PNG
if (Filtres actifs ?) then (Oui)
:Appliquer filtres\n(community, edgeTypes,\nmaxNodes, nodeTypes);
else (Non)
:Diagramme complet;
endif
:diagrams/knowledge-graph/\nknowledge-graph-full.puml\nknowledge-graph-full.png;
}
partition "INTEGRATION" {
:git add diagrams/knowledge-graph/;
:git commit;
note right: Diagrammes versionnés\ntoujours à jour avec le code
}
stop
@enduml
Workflow type
@startuml
skinparam backgroundColor #FEFEFE
skinparam ActivityBackgroundColor #E8F4FD
skinparam ActivityDiamondBackgroundColor #FFF3CD
skinparam ActivityBorderColor #2C3E50
start
partition "EXTRACTION" {
:graphify . --no-viz;
note right: Analyse le code source\ntree-sitter (local, pas de LLM)
:graphify-out/graph.json;
note right: Noeuds + arêtes\n+ communautés
}
partition "GENERATION" {
:./gradlew generateKnowledgeGraphDiagram;
note right: Pipeline déterministe\nparse → render → validate → PNG
if (Filtres actifs ?) then (Oui)
:Appliquer filtres\n(community, edgeTypes,\nmaxNodes, nodeTypes);
else (Non)
:Diagramme complet;
endif
:diagrams/knowledge-graph/\nknowledge-graph-full.puml\nknowledge-graph-full.png;
}
partition "INTEGRATION" {
:git add diagrams/knowledge-graph/;
:git commit;
note right: Diagrammes versionnés\ntoujours à jour avec le code
}
stop
@enduml
@startuml skinparam backgroundColor #FEFEFE state "Development" as dev state "Extraction\ngraphify . --no-viz" as extract state "Generation\n./gradlew generateKnowledgeGraphDiagram" as generate state "Commit\nversioned diagrams" as commit [*] --> dev dev --> extract : Code modifié extract --> generate : graph.json à jour generate --> commit : .puml + .png générés commit --> dev : Diagrammes dans le repo note right of extract Quasi instantané sur du code Kotlin (tree-sitter, pas de LLM) end note note right of generate Déterministe Pas de LLM Résultat reproductible end note @enduml
The pipeline integrates naturally into the key stages of development:
@startuml skinparam backgroundColor #FEFEFE state "Development" as dev state "Extraction graphify . --no-viz" as extract state "Generation ./gradlew generateKnowledgeGraphDiagram" as generate state "Commit versioned diagrams" as commit [*] --> dev dev --> extract : Code modifié extract --> generate : graph.json à jour generate --> commit : .puml + .png générés commit --> dev : Diagrammes dans le repo note right of extract Quasi instantané sur du code Kotlin (tree-sitter, pas de LLM) end note note right of generate Déterministe Pas de LLM Résultat reproductible end note @enduml
Incremental update
When the code changes, we do not rebuild the entire graph from scratch:
# Mise à jour incrémentale (fichiers modifiés uniquement)
graphify . --update
# Puis régénérer les diagrammes
./gradlew generateKnowledgeGraphDiagram
|
|
@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle
package "Normal pipeline\n(user → diagrams)" as normal {
[Fichier .prompt] as prompt
[LlmService\n+ ApiKeyPool] as llm1
[ProcessPlantumlPromptsTask] as task1
[Diagramme PNG] as out1
prompt --> task1
task1 --> llm1
llm1 --> out1
}
package "Knowledge Graph pipeline\n(deterministic, no LLM)" as kg {
[graphify-out/graph.json] as kgjson
[KnowledgeGraphParser] as parser
[KnowledgeGraphRenderer] as renderer
[PlantumlService] as ps
[Diagramme PNG\n(documentation du plugin)] as out2
kgjson --> parser
parser --> renderer
renderer --> ps
ps --> out2
}
package "Dogfooding pipeline\n(LLM → plugin documentation)" as dogfood {
[GraphifyPromptAdapter] as gpa
[Fichiers .prompt\nauto-générés] as auto_prompt
[LlmService\n+ ApiKeyPool] as llm2
[ProcessPlantumlPromptsTask] as task2
[Diagramme PNG\n(documentation LLM)] as out3
kgjson --> gpa
gpa --> auto_prompt
auto_prompt --> task2
task2 --> llm2
llm2 --> out3
}
note "Same LlmService, same ApiKeyPool,\nsame PlantumlService\n— ZERO duplication" as N
@enduml
The PlantUML plugin exists to transform prompts into diagrams. It can also transform the Knowledge Graph of its own codebase into documentation diagrams. This is dogfooding : the plugin consumes its own service.
@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle
package "Normal pipeline
(user → diagrams)" as normal {
[Fichier .prompt] as prompt
[LlmService\n+ ApiKeyPool] as llm1
[ProcessPlantumlPromptsTask] as task1
[Diagramme PNG] as out1
prompt --> task1
task1 --> llm1
llm1 --> out1
}
package "Pipeline Knowledge Graph
(deterministic, no LLM)" as kg {
[graphify-out/graph.json] as kgjson
[KnowledgeGraphParser] as parser
[KnowledgeGraphRenderer] as renderer
[PlantumlService] as ps
[Diagramme PNG\n(documentation du plugin)] as out2
kgjson --> parser
parser --> renderer
renderer --> ps
ps --> out2
}
package "Pipeline Dogfooding
(LLM → plugin documentation)" as dogfood {
[GraphifyPromptAdapter] as gpa
[Fichiers .prompt\nauto-générés] as auto_prompt
[LlmService\n+ ApiKeyPool] as llm2
[ProcessPlantumlPromptsTask] as task2
[Diagramme PNG\n(documentation LLM)] as out3
kgjson --> gpa
gpa --> auto_prompt
auto_prompt --> task2
task2 --> llm2
llm2 --> out3
}
note "Same LlmService, same ApiKeyPool,
same PlantumlService
— ZERO duplication" as N
@enduml
Associated Gradle tasks :
| Task | LLM ? | Description |
|---|---|---|
|
No |
Transform`graph.json`in PlantUML (deterministic) |
|
Yes |
Generate some`.prompt`from the graph, processes them via LLM (dogfooding) |
# Documentation déterministe (rapide, pas de LLM)
./gradlew generateKnowledgeGraphDiagram
# Documentation LLM (plus riche, consomme des tokens)
./gradlew generateDiagramDocs
@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle
rectangle "DETERMINISTIC Pipeline\n(generateKnowledgeGraphDiagram)" as det {
[graph.json] as json
[KnowledgeGraphParser] as parser
[KnowledgeGraphRenderer] as renderer
[PlantUML code] as puml
json --> parser : parse
parser --> renderer : KnowledgeGraph
renderer --> puml : render (fonction pure)
}
rectangle "LLM Pipeline\n(processPlantumlPrompts)" as llm {
[.prompt] as prompt
[LlmService] as llmSvc
[ChatModel] as model
[PlantUML code] as puml2
prompt --> llmSvc
llmSvc --> model : API call
model --> puml2 : réponse non-déterministe
}
note bottom of det
Même entrée → même sortie
Pas de latence réseau
Pas de coût en tokens
Reproductible en CI
end note
note bottom of llm
Même entrée → sortie variable
Latence réseau (1-5s)
Coût en tokens
Nécessite une clave API
end note
@enduml
The key point of the pipeline`generateKnowledgeGraphDiagram`:it does not call any LLM. The transformation`graph.json`→ PlantUML is a pure function.
@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle
rectangle "Deterministic Pipeline
(generateKnowledgeGraphDiagram)" as det {
[graph.json] as json
[KnowledgeGraphParser] as parser
[KnowledgeGraphRenderer] as renderer
[PlantUML code] as puml
json --> parser : parse
parser --> renderer : KnowledgeGraph
renderer --> puml : render (fonction pure)
}
rectangle "Pipeline LLM
(processPlantumlPrompts)" as llm {
[.prompt] as prompt
[LlmService] as llmSvc
[ChatModel] as model
[PlantUML code] as puml2
prompt --> llmSvc
llmSvc --> model : API call
model --> puml2 : réponse non-déterministe
}
note bottom of det
Même entrée → même sortie
Pas de latence réseau
Pas de coût en tokens
Reproductible en CI
end note
note bottom of llm
Même entrée → sortie variable
Latence réseau (1-5s)
Coût en tokens
Nécessite une clave API
end note
@enduml
The concrete benefits:
| Advantage | Impact |
|---|---|
Reproducibility |
same`graph.json`→ same diagram. Exactly. Every time. |
Zero cost |
No LLM call = no tokens = no API invoice |
Zero latency |
Parse + render takes ~100ms, not 1-5 seconds. |
CI-compatible |
No API key required. No flaky test due to a variable LLM response. |
Versionable |
Le |
@startuml
skinparam backgroundColor #FEFEFE
participant "Developer" as Dev
participant "Gradle" as G
participant "GenerateKnowledgeGraphDiagramTask" as Task
participant "KnowledgeGraphParser" as Parser
participant "KnowledgeGraphRenderer" as Renderer
participant "PlantumlService" as PS
collections "graphify-out/graph.json" as JSON
collections "diagrams/knowledge-graph/" as Out
Dev -> G : ./gradlew generateKnowledgeGraphDiagram
G -> Task : execute
Task -> JSON : read
Task -> Parser : parse(graph.json)
Parser --> Task : KnowledgeGraph
alt filtres actifs
Task -> Task : appliquer filtres\n(community, edgeTypes, maxNodes…)
end
Task -> Renderer : render(graph, filters)
Renderer --> Task : code PlantUML
Task -> PS : validateSyntax()
alt valide
Task -> PS : generateImage()
PS --> Out : .puml + .png
else invalide
Task -> Out : .puml (avec warning)
end
@enduml
To close the loop, here is the pipeline diagram as it would be generated by the plugin:
@startuml
skinparam backgroundColor #FEFEFE
participant "Developer" as Dev
participant "Gradle" as G
participant "GenerateKnowledgeGraphDiagramTask" as Task
participant "KnowledgeGraphParser" as Parser
participant "KnowledgeGraphRenderer" as Renderer
participant "PlantumlService" as PS
collections "graphify-out/graph.json" as JSON
collections "diagrams/knowledge-graph/" as Out
Dev -> G : ./gradlew generateKnowledgeGraphDiagram
G -> Task : execute
Task -> JSON : read
Task -> Parser : parse(graph.json)
Parser --> Task : KnowledgeGraph
alt filtres actifs
Task -> Task : appliquer filtres\n(community, edgeTypes, maxNodes…)
end
Task -> Renderer : render(graph, filters)
Renderer --> Task : code PlantUML
Task -> PS : validateSyntax()
alt valide
Task -> PS : generateImage()
PS --> Out : .puml + .png
else invalide
Task -> Out : .puml (avec warning)
end
@enduml
@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle
package "EAGER\n(always loaded)" as eager {
[PROMPT_REPRISE.adoc\n(contexte session)] as pr
[INDEX.adoc\n(vue d'ensemble)] as idx
[GRAPH_REPORT.adoc\n(~50 lignes)] as gr
}
package "LAZY — Strategy\n(on demand)" as lazy_strat {
[Méthodologies] as meth
[Archives sessions] as sessions
}
package "LAZY — Graphify\n(targeted queries)" as lazy_graph {
[graph.json] as gj
[Queries\n(query/path/explain)] as queries
}
package "PlantUML Pipeline\n(auto-generated)" as puml {
[generateKnowledgeGraphDiagram] as kgTask
[generateDiagramDocs] as ddTask
[Diagrammes PNG] as diagrams
}
Agent --> eager : Lit en début de session
Agent ..> lazy_strat : Charge si type détecté
Agent ..> lazy_graph : Query si besoin structurel
kgTask --> diagrams : Déterministe
ddTask --> diagrams : Via LLM
note right of gr
Condensé du Knowledge Graph
God nodes + communautés
Remplace ECOSYSTEM_OVERVIEW
(225 lignes → 50 lignes)
end note
@enduml
In our project, this pipeline integrates into an EAGER/LAZY context management strategy for the AI agent. The Knowledge Graph replaces manual architecture documentation with a structured, queryable, and automatically updated graph.
@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle
package "EAGER
(always charged)" as eager {
[PROMPT_REPRISE.adoc\n(contexte session)] as pr
[INDEX.adoc\n(vue d'ensemble)] as idx
[GRAPH_REPORT.adoc\n(~50 lignes)] as gr
}
package "LAZY — Strategy\n(on demand)" as lazy_strat {
[Méthodologies] as meth
[Archives sessions] as sessions
}
package "LAZY — Graphify
(targeted queries)" as lazy_graph {
[graph.json] as gj
[Queries\n(query/path/explain)] as queries
}
package "Pipeline PlantUML\n(auto-generated)" as puml {
[generateKnowledgeGraphDiagram] as kgTask
[generateDiagramDocs] as ddTask
[Diagrammes PNG] as diagrams
}
Agent --> eager : Lit en début de session
Agent ..> lazy_strat : Charge si type détecté
Agent ..> lazy_graph : Query si besoin structurel
kgTask --> diagrams : Déterministe
ddTask --> diagrams : Via LLM
note right of gr
Condensé du Knowledge Graph
God nodes + communautés
Remplace ECOSYSTEM_OVERVIEW
(225 lignes → 50 lignes)
end note
@enduml
The marriage of the two systems is complementary:
-
The strategy manages WHEN and HOW— governance, workflow, archiving
-
Graphify handles the WHAT and the WHERE— code structure, relationships, targeted queries
_ The session strategy manages theWHEN et le comment(governance, workflow, thresholds), Graphify manages theWHAT et le where(code structure, relationships, targeted queries). The PlantUML pipeline handles theWITH WHAT(deterministic diagrams, versioned, always up-to-date) _
Setup: 5‑minute checklist
| # | Step | Order |
|---|---|---|
1 |
Install Graphify |
|
2 |
Configure the exclusions |
Create`.graphifyignore` |
3 |
Extract the Knowledge Graph |
|
4 |
Generate the diagrams |
|
5 |
Commit the results |
|
# Script complet en 5 commandes
uv tool install graphifyy
cat > .graphifyignore << 'EOF'
*-context.yml
*.env
build/
.gradle/
EOF
graphify . --no-viz
./gradlew generateKnowledgeGraphDiagram
git add graphify-out/GRAPH_REPORT.adoc graphify-out/graph.json diagrams/knowledge-graph/
Pitfalls and mitigations
@startuml
skinparam backgroundColor #FEFEFE
rectangle "BEFORE" as avant {
card "Hand-drawn diagrams\nAlways outdated\nNo one updates them" as av1 #FDEDEC
}
rectangle "AFTER" as apres {
card "Automatically generated diagrams\nAlways up to date with the code\nVersioned in Git\nDeterministic and reproducible" as ap1 #E8F8E8
}
avant --> apres : graphify . --no-viz\n+ ./gradlew generateKnowledgeGraphDiagram
@enduml
What you get in the end
@startuml
skinparam backgroundColor #FEFEFE
rectangle "BEFORE" as avant {
card "Hand-drawn diagrams
Always outdated
No one updates them" as av1 #FDEDEC
}
rectangle "AFTER" as apres {
card "Automatically generated diagrams
Always up to date with the code
Versioned in Git
Deterministic and reproducible" as ap1 #E8F8E8
}
avant --> apres : graphify . --no-viz\n+ ./gradlew generateKnowledgeGraphDiagram
@enduml
The concrete benefits:
| Profit | Detail |
|---|---|
Documentation always up to date |
The diagrams reflect the current code, not a manual snapshot |
Zero maintenance effort |
The diagrams are regenerated on each build |
Technical debt reduction |
No need to maintain diagrams by hand |
Visual context for the newcomers |
A new developer understands the architecture by examining the diagrams. |
Potential fine-tuning |
The pairs (subgraph → diagram) are examples of AI training. |
Automatic validation |
`PlantumlService.validateSyntax()`checks each generated diagram |
Rapid onboarding |
5 diagrams = complete view of the architecture |
_ He who has a _why can bear all the how_s. _
The why : diagrams always up to date. The how : two commands in a Gradle pipeline.