Skip to content

feat: Entity Panel templating - BED 9017 - #3095

Merged
brandonshearin merged 17 commits into
mainfrom
BED-9017
Aug 12, 2026
Merged

feat: Entity Panel templating - BED 9017#3095
brandonshearin merged 17 commits into
mainfrom
BED-9017

Conversation

@brandonshearin

@brandonshearin brandonshearin commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

Description

  • add the sprig library for fancy templating
  • add templating logic in graphdb/services, following new onion arch
  • wire templating into existing api/v2/nodes/{node_id} and api/v2/relationships/{relationship_id}
  • These APIs, when template execution fails, return the unexecuted template string and a template_error field, such as:
{
  "markdown": {
    "content": "the unexecuted string",
    "template_errors":  "Reason as to why template execution failed"
  }
}

Motivation and Context

Resolves BED-9017

We want users to be able to define "dynamic" entity panels. For example, a node entity panel should be able to render dynamic information about that node, and the same is true for a relationship.

We can achieve dynamic entity panels through "templating". This PR uses the sprig library to implement templating on entity panels.

How Has This Been Tested?

  • Automated unit/integration tests
  • To manually test this functionality you need to provide a valid template string for an entity panel in your opengraph extension upload. Pick a node or an edge, and add an info object like this:
"info": {
        "overview": {
          "title": "Area Overview",
          "position": 0,
          "markdown": {
            "content": "**Object ID:** `{{ .Properties.objectid }}`"
          }
        },
      }

Screenshots (optional):

The original ticket provided an example template for a node panel and an edge panel. Here are those dynamic templates rendered in the application:

for a node:
Screenshot 2026-08-03 at 4 43 52 PM

for an edge:
Screenshot 2026-08-03 at 4 44 30 PM

Types of changes

  • Chore (a change that does not modify the application functionality)
  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Database Migrations

Checklist:

Summary by CodeRabbit

  • New Features

    • Added Markdown template rendering for node and relationship information.
    • Templates can use relevant node, relationship, kind, and property data.
    • Added support for reporting individual template rendering errors.
  • Bug Fixes

    • Failed renders now preserve the original template content instead of losing the Markdown.
    • Node access restrictions consistently return forbidden responses.
    • Endpoint lookup failures now return appropriate error responses.
  • Documentation

    • Updated API documentation to describe rendered content and template error responses.

@coderabbitai

coderabbitai Bot commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

The PR adds restricted Markdown template rendering for node and relationship kind information. Services preserve fallback content and per-entry template errors, handlers return the pre-rendered values, access checks move into the service layer, and OpenAPI schemas document the response fields.

Changes

Kind-info Markdown rendering

Layer / File(s) Summary
Template contexts and rendering
go.mod, server/graphdb/internal/services/template.go, server/graphdb/internal/services/template_test.go
Adds restricted Sprig-backed template rendering, node and relationship contexts, fallback content, template errors, and rendering tests.
Node rendering integration
server/graphdb/internal/services/services.go, server/graphdb/internal/services/node.go, server/graphdb/internal/services/node_test.go, server/graphdb/internal/services/access_checker_test.go, server/graphdb/internal/services/mocks/nodeaccesschecker.go
Adds node access-checking contracts, renders node kind information, and tests successful, failed, and empty-content cases.
Relationship rendering integration
server/graphdb/internal/services/relationship.go, server/graphdb/internal/services/relationship_test.go
Fetches endpoint nodes, enforces endpoint access, renders relationship kind information, and tests rendering and access-denial behavior.
API response and handler wiring
server/graphdb/graphdb.go, server/graphdb/graphdb_e2e_test.go, server/graphdb/internal/handlers/*, server/graphdb/internal/routes/routes_test.go, packages/go/openapi/src/..., packages/go/openapi/doc/openapi.json
Moves authorization into services, returns pre-rendered Markdown and template errors from handlers, updates HTTP error handling, and documents the response schema.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant GetNodeByID
  participant Service.GetNode
  participant renderNodeKindInfos
  Client->>GetNodeByID: Request node details
  GetNodeByID->>Service.GetNode: Fetch node and kind information
  Service.GetNode->>renderNodeKindInfos: Render Markdown templates
  renderNodeKindInfos-->>Service.GetNode: Rendered content or fallback with template_error
  Service.GetNode-->>GetNodeByID: NodeView
  GetNodeByID-->>Client: Node response
Loading

Possibly related PRs

Suggested labels: documentation, enhancement, api, dependencies, go

Suggested reviewers: lawsonwillard

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 14.29% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly identifies the main change: entity panel templating.
Description check ✅ Passed The description covers the change, motivation, testing, screenshots, and ticket, but leaves checklist items unchecked.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch BED-9017

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot added api A pull request containing changes affecting the API code. dependencies Pull requests that update a dependency file documentation Improvements or additions to documentation enhancement New feature or request go Pull requests that update go code labels Aug 3, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (1)
server/graphdb/internal/handlers/relationship_test.go (1)

63-70: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add response coverage for template_error.

The fixture verifies rendered content but does not verify TemplateError. Add a case with one failed relationship template and assert that the response preserves its fallback content and template_error.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@server/graphdb/internal/handlers/relationship_test.go` around lines 63 - 70,
Add response coverage in the relationship fixture around the existing
RenderedMarkdown case by including a relationship with a failed template, its
fallback content, and the expected TemplateError value. Assert that the handler
response preserves both the fallback rendered content and template_error for
that relationship while retaining the existing successful-template coverage.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@server/graphdb/internal/services/template.go`:
- Around line 171-174: Update both WarnContext calls in the relationship-kind
markdown rendering flow to pass structured slog.String and slog.Any attributes
instead of alternating key-value arguments, preserving the existing info_key and
error values.
- Around line 68-97: Update the unsupportedFns list to use Sprig’s exact randInt
identifier instead of randint, and add a regression test verifying that parsing
a template containing {{ randInt 1 2 }} fails.

---

Nitpick comments:
In `@server/graphdb/internal/handlers/relationship_test.go`:
- Around line 63-70: Add response coverage in the relationship fixture around
the existing RenderedMarkdown case by including a relationship with a failed
template, its fallback content, and the expected TemplateError value. Assert
that the handler response preserves both the fallback rendered content and
template_error for that relationship while retaining the existing
successful-template coverage.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro

Run ID: 4f1d0075-6f30-4b0a-9a4d-24ea061533e5

📥 Commits

Reviewing files that changed from the base of the PR and between 1fc1979 and 9551a0e.

⛔ Files ignored due to path filters (1)
  • go.sum is excluded by !**/*.sum
📒 Files selected for processing (15)
  • go.mod
  • packages/go/openapi/doc/openapi.json
  • packages/go/openapi/src/paths/graph.nodes.id.yaml
  • packages/go/openapi/src/schemas/model.kind-info-markdown.yaml
  • server/graphdb/internal/handlers/node.go
  • server/graphdb/internal/handlers/node_test.go
  • server/graphdb/internal/handlers/relationship.go
  • server/graphdb/internal/handlers/relationship_test.go
  • server/graphdb/internal/services/node.go
  • server/graphdb/internal/services/node_test.go
  • server/graphdb/internal/services/relationship.go
  • server/graphdb/internal/services/relationship_test.go
  • server/graphdb/internal/services/services.go
  • server/graphdb/internal/services/template.go
  • server/graphdb/internal/services/template_test.go

Comment thread server/graphdb/internal/services/template.go
Comment thread server/graphdb/internal/services/template.go
Comment thread server/graphdb/internal/handlers/relationship.go
Comment thread server/graphdb/internal/services/relationship.go Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (2)
server/graphdb/internal/handlers/relationship_test.go (2)

50-51: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Group the endpoint node declarations in a var (...) block.

Proposed change
-	sourceNode := services.Node{ID: relationship.SourceNodeID}
-	targetNode := services.Node{ID: relationship.TargetNodeID}
+	var (
+		sourceNode = services.Node{ID: relationship.SourceNodeID}
+		targetNode = services.Node{ID: relationship.TargetNodeID}
+	)

As per coding guidelines, “When possible, group variable initializations in a var (...) block and hoist them to the top of the function.”

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@server/graphdb/internal/handlers/relationship_test.go` around lines 50 - 51,
Group the sourceNode and targetNode declarations at the top of the containing
test function in a single var (...) block, preserving their existing
services.Node initializers and identifiers.

Source: Coding guidelines


77-85: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add a response test for template_error.

Add a KindInfo fixture with RenderedMarkdown set to the original template and TemplateError set. Assert that the HTTP response contains both fallback Markdown content and template_error. The current test only covers successful rendering.

Based on PR objectives, failed rendering must return the original template and a template_error field.

Also applies to: 128-147

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@server/graphdb/internal/handlers/relationship_test.go` around lines 77 - 85,
Add a failed-rendering response case in the relationship handler test alongside
the existing successful KindInfo fixture: create a fixture with RenderedMarkdown
containing the original template and TemplateError set, then assert the HTTP
response includes both the fallback Markdown content and the template_error
field. Keep the existing successful-rendering assertions intact.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@server/graphdb/internal/handlers/relationship_test.go`:
- Around line 50-51: Group the sourceNode and targetNode declarations at the top
of the containing test function in a single var (...) block, preserving their
existing services.Node initializers and identifiers.
- Around line 77-85: Add a failed-rendering response case in the relationship
handler test alongside the existing successful KindInfo fixture: create a
fixture with RenderedMarkdown containing the original template and TemplateError
set, then assert the HTTP response includes both the fallback Markdown content
and the template_error field. Keep the existing successful-rendering assertions
intact.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro

Run ID: 50c482c5-0d34-4b31-9d22-dbf8bc6cf33f

📥 Commits

Reviewing files that changed from the base of the PR and between 99c09cd and 65ff68f.

📒 Files selected for processing (2)
  • server/graphdb/internal/handlers/relationship.go
  • server/graphdb/internal/handlers/relationship_test.go

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
server/graphdb/internal/services/relationship.go (1)

68-77: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Hoist the endpoint variables.

Define sourceNode and targetNode in the existing var (...) block. Assign them with err during endpoint retrieval.

As per coding guidelines, “When possible, group variable initializations in a var (...) block and hoist them to the top of the function.”

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@server/graphdb/internal/services/relationship.go` around lines 68 - 77,
Update the relationship endpoint retrieval in the surrounding function by
declaring sourceNode and targetNode in the existing var (...) block, then assign
them using the shared err variable when calling GetNode. Preserve the current
source- and target-specific wrapped error messages and return behavior.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@server/graphdb/internal/services/relationship.go`:
- Around line 68-77: Update the relationship retrieval function around
GetKindByName so both source and target nodes are resolved and ETAC-authorized
before handling the ErrKindNotFound early return. Preserve the existing endpoint
error wrapping and prevent graph-only relationships from exposing IDs or
properties without authorization. Add a regression test covering denied endpoint
access through the ErrKindNotFound branch.

---

Nitpick comments:
In `@server/graphdb/internal/services/relationship.go`:
- Around line 68-77: Update the relationship endpoint retrieval in the
surrounding function by declaring sourceNode and targetNode in the existing var
(...) block, then assign them using the shared err variable when calling
GetNode. Preserve the current source- and target-specific wrapped error messages
and return behavior.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro

Run ID: 6d1c5a24-8067-4a33-9dfb-7f15f80e03de

📥 Commits

Reviewing files that changed from the base of the PR and between 65ff68f and 0132666.

⛔ Files ignored due to path filters (1)
  • go.sum is excluded by !**/*.sum
📒 Files selected for processing (18)
  • go.mod
  • packages/go/openapi/doc/openapi.json
  • server/graphdb/graphdb.go
  • server/graphdb/graphdb_e2e_test.go
  • server/graphdb/internal/handlers/handlers.go
  • server/graphdb/internal/handlers/mocks/nodeauthorizer.go
  • server/graphdb/internal/handlers/node.go
  • server/graphdb/internal/handlers/node_test.go
  • server/graphdb/internal/handlers/relationship.go
  • server/graphdb/internal/handlers/relationship_test.go
  • server/graphdb/internal/routes/routes_test.go
  • server/graphdb/internal/services/access_checker_test.go
  • server/graphdb/internal/services/mocks/nodeaccesschecker.go
  • server/graphdb/internal/services/node.go
  • server/graphdb/internal/services/node_test.go
  • server/graphdb/internal/services/relationship.go
  • server/graphdb/internal/services/relationship_test.go
  • server/graphdb/internal/services/services.go
💤 Files with no reviewable changes (1)
  • server/graphdb/internal/handlers/mocks/nodeauthorizer.go
🚧 Files skipped from review as they are similar to previous changes (3)
  • go.mod
  • server/graphdb/internal/services/node_test.go
  • packages/go/openapi/doc/openapi.json

Comment thread server/graphdb/internal/services/relationship.go
@LawsonWillard

Copy link
Copy Markdown
Contributor

Is there anyway the Dog Park schema can be updated to include a template for one of the node or relationship kinds?

@LawsonWillard LawsonWillard left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Non blocking: may be worth an end 2 end test checking against an expected templated response

Otherwise looks good to me! 🚀

@brandonshearin
brandonshearin enabled auto-merge (squash) August 11, 2026 22:38

@AD7ZJ AD7ZJ left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good!

@brandonshearin
brandonshearin merged commit 72643f3 into main Aug 12, 2026
13 checks passed
@brandonshearin
brandonshearin deleted the BED-9017 branch August 12, 2026 00:46
@github-actions github-actions Bot locked and limited conversation to collaborators Aug 12, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

api A pull request containing changes affecting the API code. dependencies Pull requests that update a dependency file documentation Improvements or additions to documentation enhancement New feature or request go Pull requests that update go code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants