Skip to content

feat: Add api/v2/relationship-kinds/{relationship_kind_id} - BED-8757 - #3061

Merged
brandonshearin merged 16 commits into
mainfrom
BED-8757-v2
Aug 3, 2026
Merged

feat: Add api/v2/relationship-kinds/{relationship_kind_id} - BED-8757#3061
brandonshearin merged 16 commits into
mainfrom
BED-8757-v2

Conversation

@brandonshearin

@brandonshearin brandonshearin commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

Description

  • GetRelationshipKind DB/service/handler methods following the onion architecture
  • Extracted KindInfoView into dedicated handlers/kindinfo.go for consumption by both nodekind and relkind endpoints
  • Swagger docs

Motivation and Context

Resolves BED-8757
We want users to be able to read the relationship kinds they have registered via OpenGraph in their DB.

How Has This Been Tested?

  • A cornocopia of automated unit/integration tests
  • For manual testing, use the API explorer. I like to add some kind infos to a relationship kind and then query for that relationship kind.

Here is an example API response when I query for the AD WriteDacl relationship:
Screenshot 2026-07-27 at 2 49 06 PM

Then, I added some kind infos to the WriteDacl relationship. I queried the endpoint again, and see that info is populated as expected:
Screenshot 2026-07-27 at 2 51 05 PM

Please describe in detail how you tested your changes.
Include details of your testing environment, and the tests you ran to
see how your change affects other areas of the code, etc.

Screenshots (optional):

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 an API endpoint to retrieve relationship-kind details by ID.
    • Responses include relationship metadata, traversability, extension information, and optional kind-info content.
    • Added validation and clear handling for invalid IDs, missing records, and server errors.
    • Protected the endpoint with read permissions and rate limiting.
  • Documentation
    • Updated the API specification with endpoint details, response schemas, examples, and standard error responses.
  • Bug Fixes
    • Improved handling and presentation of markdown content in kind information.

@brandonshearin
brandonshearin requested review from a team as code owners July 27, 2026 21:56
@coderabbitai

coderabbitai Bot commented Jul 27, 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

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

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

Review profile: CHILL

Plan: Pro

Run ID: 58a544a0-a3ae-4884-865c-530b51095338

📥 Commits

Reviewing files that changed from the base of the PR and between e39249a and 278ed3a.

📒 Files selected for processing (1)
  • packages/go/openapi/doc/openapi.json
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/go/openapi/doc/openapi.json

📝 Walkthrough

Walkthrough

Adds a GET /api/v2/relationship-kinds/{relationship_kind_id} endpoint. The change adds database and service retrieval, JSON view construction, route protection, tests, and OpenAPI definitions for relationship-kind responses.

Changes

Relationship kind retrieval

Layer / File(s) Summary
Persistence and service retrieval
server/extensions/internal/services/..., server/extensions/internal/appdb/...
Adds the database contract, store query, relationship-kind mapping, service enrichment, mocks, integration coverage, and related test updates.
HTTP response and view construction
server/extensions/internal/handlers/...
Adds relationship-kind views, markdown conversion, handler error mapping, handler tests, and the shared ExtensionView type used by node-kind responses.
Route and API specification
server/extensions/internal/routes/routes.go, packages/go/openapi/src/..., packages/go/openapi/doc/openapi.json
Registers the permission- and rate-limited route and documents its parameters, response schema, examples, and error responses.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant GetRelationshipKindByID
  participant ExtensionsService
  participant RelationshipKindStore
  Client->>GetRelationshipKindByID: GET relationship-kind ID
  GetRelationshipKindByID->>ExtensionsService: GetRelationshipKind(ctx, id)
  ExtensionsService->>RelationshipKindStore: GetRelationshipKind(ctx, id)
  RelationshipKindStore-->>ExtensionsService: RelationshipKind data
  ExtensionsService-->>GetRelationshipKindByID: RelationshipKind
  GetRelationshipKindByID-->>Client: JSON response or mapped error
Loading

Possibly related PRs

Suggested labels: documentation, enhancement, api, go

Suggested reviewers: urangel, seanjso

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 25.00% 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 new relationship-kinds API endpoint and includes the associated ticket.
Description check ✅ Passed The description covers the change, motivation, ticket, testing, and screenshots, but leaves type selections and checklist items incomplete.
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
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch BED-8757-v2

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

@brandonshearin brandonshearin self-assigned this Jul 27, 2026
Base automatically changed from BED-8756 to main July 29, 2026 17:01
Comment thread package.json
@superlinkx

Copy link
Copy Markdown
Contributor

Structurally this doesn't seem particularly problematic, however 4k lines is quite large and you've got a lot of conflicts to resolve as a result. 21 commits tells me this PR could have been broken up into smaller atomic PRs. While I wouldn't block this PR on that, being mindful of your fellow devs (and AI reviewers for context bounding reasons) and creating atomic PRs of <1k lines will lead to faster, stronger review and improve overall velocity.

@brandonshearin brandonshearin changed the title feat: Add api/v2/relationship-kinds/{relationship_kind_id} - BED-8757 DRAFT feat: Add api/v2/relationship-kinds/{relationship_kind_id} - BED-8757 Jul 29, 2026
@coderabbitai coderabbitai Bot added api A pull request containing changes affecting the API code. documentation Improvements or additions to documentation enhancement New feature or request go Pull requests that update go code labels Jul 30, 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 (2)
server/extensions/internal/appdb/relationshipkind.go (1)

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

Remove the stale extension-join TODO.

The row model and query below already join schema_extensions and populate its fields.

🤖 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/extensions/internal/appdb/relationshipkind.go` at line 31, Remove the
obsolete extension-join TODO comment above the relationship row model/query,
leaving the existing schema_extensions join and field population unchanged.
server/extensions/internal/handlers/relationshipkind.go (1)

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

Group view and markdownErr into a single var (...) block.

Per repo Go guidelines, variable initializations should be grouped in a var (...) block and hoisted to the top of the function. Here view is built via := and markdownErr is declared separately below it.

♻️ Proposed grouping
 func buildRelationshipKindView(relationshipKind services.RelationshipKind) (RelationshipKindView, error) {
-
-	view := RelationshipKindView{
-		RelationshipKindID: relationshipKind.ID,
-		Name:               relationshipKind.Name,
-		Description:        relationshipKind.Description,
-		IsTraversable:      relationshipKind.IsTraversable,
-		Extension: ExtensionView{
-			ExtensionID: relationshipKind.Extension.ID,
-			Name:        relationshipKind.Extension.Name,
-			DisplayName: relationshipKind.Extension.DisplayName,
-			Namespace:   relationshipKind.Extension.Namespace,
-			Version:     relationshipKind.Extension.Version,
-		},
-		Info: map[string]KindInfoView{},
-	}
-
-	var markdownErr error
+	var (
+		markdownErr error
+		view        = RelationshipKindView{
+			RelationshipKindID: relationshipKind.ID,
+			Name:               relationshipKind.Name,
+			Description:        relationshipKind.Description,
+			IsTraversable:      relationshipKind.IsTraversable,
+			Extension: ExtensionView{
+				ExtensionID: relationshipKind.Extension.ID,
+				Name:        relationshipKind.Extension.Name,
+				DisplayName: relationshipKind.Extension.DisplayName,
+				Namespace:   relationshipKind.Extension.Namespace,
+				Version:     relationshipKind.Extension.Version,
+			},
+			Info: map[string]KindInfoView{},
+		}
+	)

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/extensions/internal/handlers/relationshipkind.go` around lines 70 -
88, Update buildRelationshipKindView to hoist and group view and markdownErr in
a single var (...) declaration at the top of the function, preserving their
existing initial values and subsequent 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/extensions/internal/routes/routes.go`:
- Around line 32-42: Update Register so router.With applies rateLimit to both
nodeKindRoute and relationshipKindRoute. Keep the existing GraphDBRead
permission requirements unchanged for each route.

In `@server/extensions/internal/services/relationshipkind.go`:
- Around line 25-26: Correct the doc comment immediately above
ErrRelationshipKindNotFound so it names ErrRelationshipKindNotFound
consistently.

---

Nitpick comments:
In `@server/extensions/internal/appdb/relationshipkind.go`:
- Line 31: Remove the obsolete extension-join TODO comment above the
relationship row model/query, leaving the existing schema_extensions join and
field population unchanged.

In `@server/extensions/internal/handlers/relationshipkind.go`:
- Around line 70-88: Update buildRelationshipKindView to hoist and group view
and markdownErr in a single var (...) declaration at the top of the function,
preserving their existing initial values and subsequent behavior.
🪄 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: 8ef520bf-2cd3-4693-9735-ab1bc0a37afb

📥 Commits

Reviewing files that changed from the base of the PR and between 74dd3da and 501b162.

📒 Files selected for processing (21)
  • packages/go/openapi/doc/openapi.json
  • packages/go/openapi/src/openapi.yaml
  • packages/go/openapi/src/paths/opengraph.relationship-kind.yaml
  • packages/go/openapi/src/schemas/model.relationship-kind-response.yaml
  • server/extensions/internal/appdb/kindinfo_test.go
  • server/extensions/internal/appdb/relationshipkind.go
  • server/extensions/internal/appdb/relationshipkind_integration_test.go
  • server/extensions/internal/handlers/extension.go
  • server/extensions/internal/handlers/handlers.go
  • server/extensions/internal/handlers/kindinfo.go
  • server/extensions/internal/handlers/mocks/extensions.go
  • server/extensions/internal/handlers/nodekind.go
  • server/extensions/internal/handlers/nodekind_test.go
  • server/extensions/internal/handlers/relationshipkind.go
  • server/extensions/internal/handlers/relationshipkind_test.go
  • server/extensions/internal/routes/routes.go
  • server/extensions/internal/services/mocks/database.go
  • server/extensions/internal/services/nodekind_test.go
  • server/extensions/internal/services/relationshipkind.go
  • server/extensions/internal/services/relationshipkind_test.go
  • server/extensions/internal/services/services.go

Comment thread server/extensions/internal/routes/routes.go
Comment thread server/extensions/internal/services/relationshipkind.go Outdated
@brandonshearin brandonshearin changed the title DRAFT feat: Add api/v2/relationship-kinds/{relationship_kind_id} - BED-8757 feat: Add api/v2/relationship-kinds/{relationship_kind_id} - BED-8757 Jul 30, 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: 1

🤖 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/extensions/internal/services/relationshipkind.go`:
- Around line 48-50: Update the extension lookup in the relationship-kind
retrieval method to store relKind.Extension.ID in a local variable before
assigning the fetched extension, then use that preserved ID in the
fetching-extension error message. Keep the existing lookup and
ErrExtensionNotFound handling unchanged.
🪄 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: f905c338-2049-4ce2-aa1b-a0900db6e8c5

📥 Commits

Reviewing files that changed from the base of the PR and between 501b162 and ca3da42.

📒 Files selected for processing (6)
  • server/extensions/internal/appdb/relationshipkind.go
  • server/extensions/internal/appdb/relationshipkind_integration_test.go
  • server/extensions/internal/handlers/relationshipkind_test.go
  • server/extensions/internal/services/relationshipkind.go
  • server/extensions/internal/services/relationshipkind_test.go
  • server/extensions/internal/services/services.go
💤 Files with no reviewable changes (2)
  • server/extensions/internal/appdb/relationshipkind_integration_test.go
  • server/extensions/internal/services/services.go
🚧 Files skipped from review as they are similar to previous changes (2)
  • server/extensions/internal/handlers/relationshipkind_test.go
  • server/extensions/internal/services/relationshipkind_test.go

Comment on lines +48 to +50
if relKind.Extension.ID != 0 {
if relKind.Extension, err = s.db.GetExtension(ctx, relKind.Extension.ID); err != nil && !errors.Is(err, ErrExtensionNotFound) {
return RelationshipKind{}, fmt.Errorf("fetching extension %d for relationship kind %d: %w", relKind.Extension.ID, id, err)

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.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Preserve the requested extension ID for error reporting.

The assignment on Line 49 overwrites relKind.Extension before Line 50 formats the error. When the lookup returns an empty extension, the error reports extension 0 instead of the ID that was actually requested.

Proposed fix
-		if relKind.Extension.ID != 0 {
-			if relKind.Extension, err = s.db.GetExtension(ctx, relKind.Extension.ID); err != nil && !errors.Is(err, ErrExtensionNotFound) {
-				return RelationshipKind{}, fmt.Errorf("fetching extension %d for relationship kind %d: %w", relKind.Extension.ID, id, err)
+		if extensionID := relKind.Extension.ID; extensionID != 0 {
+			if relKind.Extension, err = s.db.GetExtension(ctx, extensionID); err != nil && !errors.Is(err, ErrExtensionNotFound) {
+				return RelationshipKind{}, fmt.Errorf("fetching extension %d for relationship kind %d: %w", extensionID, id, err)
			}
		}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if relKind.Extension.ID != 0 {
if relKind.Extension, err = s.db.GetExtension(ctx, relKind.Extension.ID); err != nil && !errors.Is(err, ErrExtensionNotFound) {
return RelationshipKind{}, fmt.Errorf("fetching extension %d for relationship kind %d: %w", relKind.Extension.ID, id, err)
if extensionID := relKind.Extension.ID; extensionID != 0 {
if relKind.Extension, err = s.db.GetExtension(ctx, extensionID); err != nil && !errors.Is(err, ErrExtensionNotFound) {
return RelationshipKind{}, fmt.Errorf("fetching extension %d for relationship kind %d: %w", extensionID, id, err)
}
}
🤖 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/extensions/internal/services/relationshipkind.go` around lines 48 -
50, Update the extension lookup in the relationship-kind retrieval method to
store relKind.Extension.ID in a local variable before assigning the fetched
extension, then use that preserved ID in the fetching-extension error message.
Keep the existing lookup and ErrExtensionNotFound handling unchanged.

Comment thread server/extensions/internal/services/nodekind_test.go Outdated
Comment thread server/extensions/internal/appdb/relationshipkind.go
Description string `json:"description"`
IsTraversable bool `json:"is_traversable"`
Info map[string]KindInfoView `json:"info"`
Extension ExtensionView `json:"extension"`

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.

Do you think this should be a pointer, *ExtensionView like it is for NodeKind?

@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.

Nothing blocking that I see, send it!

@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.

Looks good to me, great work! 🚀

@brandonshearin
brandonshearin enabled auto-merge (squash) August 3, 2026 21:48
@brandonshearin
brandonshearin merged commit ac44218 into main Aug 3, 2026
14 checks passed
@brandonshearin
brandonshearin deleted the BED-8757-v2 branch August 3, 2026 22:34
@github-actions github-actions Bot locked and limited conversation to collaborators Aug 3, 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. 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.

4 participants