Skip to content

Feature/template update mutations#162

Merged
nk-coding merged 5 commits intomainfrom
feature/template_update_mutations
Nov 18, 2025
Merged

Feature/template update mutations#162
nk-coding merged 5 commits intomainfrom
feature/template_update_mutations

Conversation

@nk-coding
Copy link
Contributor

@nk-coding nk-coding commented Nov 17, 2025

Summary by CodeRabbit

  • New Features
    • Added GraphQL update mutations for templates and configuration types, including component templates, issue templates, interface specifications, and configurable items such as issue states, priorities, and types.

@nk-coding nk-coding requested a review from chriku November 17, 2025 17:46
@nk-coding nk-coding self-assigned this Nov 17, 2025
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 17, 2025

Walkthrough

This pull request adds comprehensive update mutation endpoints for 16 template types across the GraphQL API. It introduces input DTOs for each template, creates corresponding service classes that handle validation, authorization, and persistence, adds required repository interfaces, and makes specific model properties mutable to support field updates.

Changes

Cohort / File(s) Change Summary
GraphQL Mutations
api-public/src/main/kotlin/gropius/schema/mutation/TemplateMutations.kt
Added 16 new suspend update mutation methods with corresponding input types and service injection. Each delegates to the respective service's update function after retrieving authorization context from DataFetchingEnvironment.
Input DTOs — Simple
core/src/main/kotlin/gropius/dto/input/template/Update{Artefact,Assignment,Component Version,Interface Part,Interface Specification Version,Intra Component Dependency Specification,Issue State,Issue Template}TemplateInput.kt
Added 8 input classes extending UpdateNamedNodeInput with minimal additional fields. Each annotated with GraphQLDescription for their respective mutations.
Input DTOs — Extended
core/src/main/kotlin/gropius/dto/input/template/Update{Component,Interface Specification}TemplateInput.kt
Added 2 input classes with optional shape-related fields (shapeRadius: OptionalInput<Double?>, shapeType: OptionalInput<ShapeType>).
Input DTOs — Custom Fields
core/src/main/kotlin/gropius/dto/input/template/Update{IssueType,IssuePriority,IssueRelationType,RelationTemplate}Input.kt
Added 4 input classes with type-specific optional fields: iconPath, value, inverseName, and markerType respectively.
Model Mutability Changes
core/src/main/kotlin/gropius/model/template/{IssuePriority,IssueRelationType,IssueType,RelationTemplate,RelationPartnerTemplate}.kt
Changed 6 properties from immutable (val) to mutable (var): value in IssuePriority, inverseName in IssueRelationType, iconPath in IssueType, markerType in RelationTemplate, and shapeRadius/shapeType in RelationPartnerTemplate.
Base Service Logic
core/src/main/kotlin/gropius/service/template/BaseTemplateService.kt
Refactored duplicate field name detection to group by name and identify duplicates only when multiple distinct values exist for the same name; updated error messaging.
Template Services — Simple
core/src/main/kotlin/gropius/service/template/{Artefact,Assignment Type,Issue State,Issue Template,Component Version,Interface Part,Interface Specification Version}TemplateService.kt
Added 7 new service classes extending appropriate base types, each providing a suspend update*Template method that validates input, checks permissions, fetches entity, applies updates via updateNamedNode, and persists.
Template Services — Extended
core/src/main/kotlin/gropius/service/template/{Component,InterfaceSpecification,RelationTemplate}Service.kt
Added/enhanced 3 services with conditional field updates for shape/marker properties using input.ifPresent checks.
Template Services — Custom Logic
core/src/main/kotlin/gropius/service/template/{IssueType,IssuePriority,IssueRelationType}Service.kt
Added 3 new service classes with type-specific field updates (iconPath, value, inverseName).
Template Services — Specialized
core/src/main/kotlin/gropius/service/template/{IntraComponentDependencySpecificationType}Service.kt
Added 1 new service class for managing IntraComponentDependencySpecificationType with standard update flow.
Repository Interfaces
core/src/main/kotlin/gropius/repository/template/{ComponentVersionTemplate,IMS{Project,Issue,User}Template,InterfacePartTemplate,InterfaceSpecificationVersionTemplate}Repository.kt
Added 6 new Spring Data repository interfaces extending GropiusRepository<Entity, String> with @Repository annotation.

Sequence Diagram(s)

sequenceDiagram
    participant Client as GraphQL Client
    participant Mutation as TemplateMutations
    participant Service as Template Service<br/>(e.g., IssueTypeService)
    participant Repo as Repository
    participant DB as Database

    Client->>Mutation: updateIssueType(input, dfe)
    Mutation->>Service: updateIssueType(authContext, input)
    Service->>Service: input.validate()
    Service->>Service: checkCreateTemplatePermission(authContext)
    Service->>Repo: findById(input.id)
    Repo->>DB: SELECT entity WHERE id=?
    DB-->>Repo: entity
    Repo-->>Service: entity
    Service->>Service: updateNamedNode(entity, input)
    alt if optional fields present
        Service->>Service: entity.field = input.field.value
    end
    Service->>Repo: save(entity)
    Repo->>DB: UPDATE entity
    DB-->>Repo: updated entity
    Repo-->>Service: updated entity
    Service-->>Mutation: updated entity
    Mutation-->>Client: Payload { entity, ... }
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Areas requiring extra attention:

  • BaseTemplateService duplicate detection refactoring — Verify the new grouping logic correctly identifies only duplicates with differing values and doesn't introduce regression in template field validation.
  • Authorization checks — Confirm all 13+ new service classes consistently call checkCreateTemplatePermission and that permission boundaries are appropriate for update operations.
  • Model mutability changes — Review 6 model property conversions from val to var to ensure thread-safety considerations and that existing serialization/persistence logic handles mutable fields correctly.
  • Optional field handling — Validate that OptionalInput.ifPresent patterns are applied consistently across services (ComponentTemplate, InterfaceSpecificationTemplate, RelationTemplate, IssuePriority, IssueRelationType, IssueType).
  • Repository dependency wiring — Confirm all 6 new repository interfaces are properly registered and injectable into their corresponding services.

Poem

🐰 Templates dance in endless rows,
Mutations bloom where logic flows,
Val to var, the fields now shift,
Updates rise with springy lift,
Sixteen types in harmony sing,
New mutations CRUD brings!

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 55.81% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Feature/template update mutations' directly summarizes the main change: adding update mutation endpoints for various template types throughout the codebase.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feature/template_update_mutations

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 7

🧹 Nitpick comments (5)
core/src/main/kotlin/gropius/dto/input/template/UpdateRelationTemplateInput.kt (1)

7-7: Remove unused import.

The kotlin.properties.Delegates import is not used in this file.

Apply this diff:

-import kotlin.properties.Delegates
core/src/main/kotlin/gropius/dto/input/template/UpdateIssueTypeInput.kt (1)

6-6: Remove unused import.

The kotlin.properties.Delegates import is not used in this file.

Apply this diff:

-import kotlin.properties.Delegates
core/src/main/kotlin/gropius/dto/input/template/UpdateIssueRelationTypeInput.kt (1)

6-6: Remove unused import.

The kotlin.properties.Delegates import is not used in this file.

Apply this diff:

-import kotlin.properties.Delegates
core/src/main/kotlin/gropius/dto/input/template/UpdateComponentTemplateInput.kt (1)

7-7: Remove unused import.

The kotlin.properties.Delegates import is not used in this file.

Apply this diff:

-import kotlin.properties.Delegates
core/src/main/kotlin/gropius/dto/input/template/UpdateInterfaceSpecificationTemplateInput.kt (1)

7-7: Remove unused import.

The kotlin.properties.Delegates import is not used in this file.

Apply this diff:

-import kotlin.properties.Delegates
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f86e5e8 and b788129.

📒 Files selected for processing (37)
  • api-public/src/main/kotlin/gropius/schema/mutation/TemplateMutations.kt (1 hunks)
  • core/src/main/kotlin/gropius/dto/input/template/UpdateArtefactTemplateInput.kt (1 hunks)
  • core/src/main/kotlin/gropius/dto/input/template/UpdateAssignmentTypeInput.kt (1 hunks)
  • core/src/main/kotlin/gropius/dto/input/template/UpdateComponentTemplateInput.kt (1 hunks)
  • core/src/main/kotlin/gropius/dto/input/template/UpdateComponentVersionTemplateInput.kt (1 hunks)
  • core/src/main/kotlin/gropius/dto/input/template/UpdateIMSIssueTemplateInput.kt (1 hunks)
  • core/src/main/kotlin/gropius/dto/input/template/UpdateIMSProjectTemplateInput.kt (1 hunks)
  • core/src/main/kotlin/gropius/dto/input/template/UpdateIMSTemplateInput.kt (1 hunks)
  • core/src/main/kotlin/gropius/dto/input/template/UpdateIMSUserTemplateInput.kt (1 hunks)
  • core/src/main/kotlin/gropius/dto/input/template/UpdateInterfacePartTemplateInput.kt (1 hunks)
  • core/src/main/kotlin/gropius/dto/input/template/UpdateInterfaceSpecificationTemplateInput.kt (1 hunks)
  • core/src/main/kotlin/gropius/dto/input/template/UpdateInterfaceSpecificationVersionTemplateInput.kt (1 hunks)
  • core/src/main/kotlin/gropius/dto/input/template/UpdateIntraComponentDependencySpecificationTypeInput.kt (1 hunks)
  • core/src/main/kotlin/gropius/dto/input/template/UpdateIssuePriorityInput.kt (1 hunks)
  • core/src/main/kotlin/gropius/dto/input/template/UpdateIssueRelationTypeInput.kt (1 hunks)
  • core/src/main/kotlin/gropius/dto/input/template/UpdateIssueStateInput.kt (1 hunks)
  • core/src/main/kotlin/gropius/dto/input/template/UpdateIssueTemplateInput.kt (1 hunks)
  • core/src/main/kotlin/gropius/dto/input/template/UpdateIssueTypeInput.kt (1 hunks)
  • core/src/main/kotlin/gropius/dto/input/template/UpdateRelationTemplateInput.kt (1 hunks)
  • core/src/main/kotlin/gropius/model/template/IssuePriority.kt (1 hunks)
  • core/src/main/kotlin/gropius/model/template/IssueRelationType.kt (1 hunks)
  • core/src/main/kotlin/gropius/model/template/IssueType.kt (1 hunks)
  • core/src/main/kotlin/gropius/model/template/RelationPartnerTemplate.kt (1 hunks)
  • core/src/main/kotlin/gropius/model/template/RelationTemplate.kt (1 hunks)
  • core/src/main/kotlin/gropius/service/template/ArtefactTemplateService.kt (2 hunks)
  • core/src/main/kotlin/gropius/service/template/AssignmentTypeService.kt (1 hunks)
  • core/src/main/kotlin/gropius/service/template/BaseTemplateService.kt (1 hunks)
  • core/src/main/kotlin/gropius/service/template/ComponentTemplateService.kt (3 hunks)
  • core/src/main/kotlin/gropius/service/template/IMSTemplateService.kt (1 hunks)
  • core/src/main/kotlin/gropius/service/template/InterfaceSpecificationTemplateService.kt (3 hunks)
  • core/src/main/kotlin/gropius/service/template/IntraComponentDependencySpecificationTypeService.kt (1 hunks)
  • core/src/main/kotlin/gropius/service/template/IssuePriorityService.kt (1 hunks)
  • core/src/main/kotlin/gropius/service/template/IssueRelationTypeService.kt (1 hunks)
  • core/src/main/kotlin/gropius/service/template/IssueStateService.kt (1 hunks)
  • core/src/main/kotlin/gropius/service/template/IssueTemplateService.kt (2 hunks)
  • core/src/main/kotlin/gropius/service/template/IssueTypeService.kt (1 hunks)
  • core/src/main/kotlin/gropius/service/template/RelationTemplateService.kt (2 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-08-04T13:05:27.476Z
Learnt from: nk-coding
Repo: ccims/gropius-backend PR: 159
File: core/src/main/kotlin/gropius/service/issue/IssueBoardItemService.kt:103-103
Timestamp: 2025-08-04T13:05:27.476Z
Learning: In the IssueBoardItemService class in core/src/main/kotlin/gropius/service/issue/IssueBoardItemService.kt, the permission TrackablePermission.MANAGE_ISSUES is intentionally used instead of MANAGE_ISSUE_BOARDS for managing issue board items, as these operations are considered issue management rather than board structure management.

Applied to files:

  • core/src/main/kotlin/gropius/service/template/IssuePriorityService.kt
  • core/src/main/kotlin/gropius/service/template/IssueStateService.kt
  • core/src/main/kotlin/gropius/service/template/IssueTypeService.kt
🧬 Code graph analysis (14)
core/src/main/kotlin/gropius/dto/input/template/UpdateAssignmentTypeInput.kt (1)
core/src/main/kotlin/gropius/dto/input/template/AssignmentTypeInput.kt (1)
  • @GraphQLDescription("Input to create an AssignmentType") (6-7)
core/src/main/kotlin/gropius/service/template/IssueTemplateService.kt (2)
core/src/main/kotlin/gropius/service/template/BaseTemplateService.kt (1)
  • checkCreateTemplatePermission (69-74)
core/src/main/kotlin/gropius/service/common/NamedNodeService.kt (1)
  • updateNamedNode (26-33)
core/src/main/kotlin/gropius/dto/input/template/UpdateIssueTemplateInput.kt (1)
core/src/main/kotlin/gropius/dto/input/issue/UpdateBodyInput.kt (1)
  • @GraphQLDescription("Input for the updateBody mutation") (5-6)
core/src/main/kotlin/gropius/service/template/ArtefactTemplateService.kt (2)
core/src/main/kotlin/gropius/service/template/BaseTemplateService.kt (1)
  • checkCreateTemplatePermission (69-74)
core/src/main/kotlin/gropius/service/common/NamedNodeService.kt (1)
  • updateNamedNode (26-33)
core/src/main/kotlin/gropius/service/template/AssignmentTypeService.kt (1)
core/src/main/kotlin/gropius/service/common/NamedNodeService.kt (1)
  • updateNamedNode (26-33)
core/src/main/kotlin/gropius/service/template/ComponentTemplateService.kt (2)
core/src/main/kotlin/gropius/service/template/BaseTemplateService.kt (1)
  • checkCreateTemplatePermission (69-74)
core/src/main/kotlin/gropius/service/common/NamedNodeService.kt (1)
  • updateNamedNode (26-33)
core/src/main/kotlin/gropius/service/template/IssuePriorityService.kt (1)
core/src/main/kotlin/gropius/service/common/NamedNodeService.kt (1)
  • updateNamedNode (26-33)
core/src/main/kotlin/gropius/service/template/RelationTemplateService.kt (2)
core/src/main/kotlin/gropius/service/template/BaseTemplateService.kt (1)
  • checkCreateTemplatePermission (69-74)
core/src/main/kotlin/gropius/service/common/NamedNodeService.kt (1)
  • updateNamedNode (26-33)
core/src/main/kotlin/gropius/service/template/InterfaceSpecificationTemplateService.kt (2)
core/src/main/kotlin/gropius/service/template/BaseTemplateService.kt (1)
  • checkCreateTemplatePermission (69-74)
core/src/main/kotlin/gropius/service/common/NamedNodeService.kt (1)
  • updateNamedNode (26-33)
core/src/main/kotlin/gropius/service/template/IssueStateService.kt (1)
core/src/main/kotlin/gropius/service/common/NamedNodeService.kt (1)
  • updateNamedNode (26-33)
core/src/main/kotlin/gropius/service/template/IntraComponentDependencySpecificationTypeService.kt (1)
core/src/main/kotlin/gropius/service/common/NamedNodeService.kt (1)
  • updateNamedNode (26-33)
core/src/main/kotlin/gropius/service/template/IssueRelationTypeService.kt (1)
core/src/main/kotlin/gropius/service/common/NamedNodeService.kt (1)
  • updateNamedNode (26-33)
core/src/main/kotlin/gropius/service/template/IssueTypeService.kt (1)
core/src/main/kotlin/gropius/service/common/NamedNodeService.kt (1)
  • updateNamedNode (26-33)
core/src/main/kotlin/gropius/service/template/IMSTemplateService.kt (2)
core/src/main/kotlin/gropius/service/template/BaseTemplateService.kt (1)
  • checkCreateTemplatePermission (69-74)
core/src/main/kotlin/gropius/service/common/NamedNodeService.kt (1)
  • updateNamedNode (26-33)
🔇 Additional comments (34)
core/src/main/kotlin/gropius/model/template/RelationPartnerTemplate.kt (1)

17-19: LGTM! Properties made mutable to support template updates.

The changes to shapeRadius and shapeType from val to var correctly enable update operations for these shape properties via the new template update mutations.

core/src/main/kotlin/gropius/dto/input/template/UpdateIntraComponentDependencySpecificationTypeInput.kt (1)

1-7: LGTM! Input DTO follows established pattern.

The new input type correctly extends UpdateNamedNodeInput and follows the consistent pattern used by other template update input classes.

core/src/main/kotlin/gropius/model/template/RelationTemplate.kt (1)

26-26: LGTM! Property made mutable to support marker type updates.

The change from val to var for markerType correctly enables updates to the marker type through the new updateRelationTemplate mutation.

core/src/main/kotlin/gropius/model/template/IssueRelationType.kt (1)

22-22: Verify that clients handle dynamic inverseName changes.

The change from val to var enables runtime updates to inverseName. Since this affects all IssueRelation entities using this type, ensure that UI clients and consumers properly handle dynamic name changes without requiring cache invalidation or refresh.

core/src/main/kotlin/gropius/model/template/IssueType.kt (1)

20-20: LGTM! Property made mutable to support icon updates.

The change from val to var for iconPath correctly enables updates to the icon path through the new updateIssueType mutation. Icon changes will apply to all issues using this type.

core/src/main/kotlin/gropius/dto/input/template/UpdateIMSTemplateInput.kt (1)

1-7: LGTM! Input DTO follows established pattern.

The new input type correctly extends UpdateNamedNodeInput and follows the consistent pattern used by other IMS template update input classes.

core/src/main/kotlin/gropius/dto/input/template/UpdateIMSUserTemplateInput.kt (1)

1-7: LGTM! Input DTO follows established pattern.

The new input type correctly extends UpdateNamedNodeInput and follows the consistent pattern used by other IMS template update input classes.

core/src/main/kotlin/gropius/model/template/IssuePriority.kt (1)

22-22: Confirm that mutable priority values retroactively affecting associated issues is intentional.

Verification confirms the concern: changing IssuePriority.value will retroactively affect all issues currently using that priority, as Issue.priority() dereferences at runtime without caching. The service layer applies no safeguards beyond optional checking—only issuePriority.value = it is executed.

No tests, documentation, or inline comments clarify whether this behavior is intentional. Please confirm this is desired and consider documenting it or adding validation logic if necessary.

core/src/main/kotlin/gropius/dto/input/template/UpdateArtefactTemplateInput.kt (1)

1-7: LGTM! Consistent input DTO pattern.

The implementation correctly extends UpdateNamedNodeInput and provides the appropriate GraphQL description for the update mutation.

core/src/main/kotlin/gropius/dto/input/template/UpdateIssueTemplateInput.kt (1)

1-7: LGTM! Follows established pattern.

The input DTO is correctly structured for the updateIssueTemplate mutation.

core/src/main/kotlin/gropius/dto/input/template/UpdateIssueStateInput.kt (1)

1-7: LGTM! Correct implementation.

The input DTO properly extends UpdateNamedNodeInput for the updateIssueState mutation.

core/src/main/kotlin/gropius/dto/input/template/UpdateIssuePriorityInput.kt (1)

1-12: LGTM! Correctly extends base input with priority value.

The additional value field properly uses OptionalInput<Double> to support optional updates to the IssuePriority ordering value. The GraphQL description clearly explains the field's purpose.

core/src/main/kotlin/gropius/dto/input/template/UpdateAssignmentTypeInput.kt (1)

1-7: LGTM! Consistent with other template update inputs.

The implementation correctly follows the established pattern for template update DTOs.

core/src/main/kotlin/gropius/dto/input/template/UpdateInterfacePartTemplateInput.kt (1)

1-7: LGTM! Properly structured update input.

The input DTO is correctly implemented for updating InterfacePartTemplate entities.

core/src/main/kotlin/gropius/dto/input/template/UpdateIMSIssueTemplateInput.kt (1)

1-7: LGTM! Follows consistent pattern.

The implementation correctly extends UpdateNamedNodeInput for IMS issue template updates.

core/src/main/kotlin/gropius/service/template/RelationTemplateService.kt (1)

83-102: LGTM! Update method follows established service patterns.

The implementation correctly:

  • Validates input and checks permissions using the standard template permission check
  • Retrieves the existing template using the repository
  • Applies updates via updateNamedNode for base fields (name, description)
  • Conditionally updates markerType when provided (verified: UpdateRelationTemplateInput has markerType: OptionalInput<MarkerType>)
  • Persists and returns the updated entity
core/src/main/kotlin/gropius/service/template/BaseTemplateService.kt (1)

51-57: LGTM! Improved duplicate detection logic.

The new grouping-based approach correctly identifies duplicates only when a name maps to multiple distinct values, which is more precise than the previous implementation. This properly allows the same (name, value) pair to appear multiple times from different extended templates while catching actual conflicts.

core/src/main/kotlin/gropius/service/template/IssueRelationTypeService.kt (1)

32-43: LGTM! Correctly implements the update flow.

The update method follows the established pattern: validates input, checks permissions, retrieves the entity, applies updates via updateNamedNode, handles the optional inverseName field, and persists the changes reactively.

core/src/main/kotlin/gropius/service/template/IssueTemplateService.kt (1)

50-66: LGTM! Correctly implements the update flow.

The updateIssueTemplate method follows the established pattern: validates input, checks permissions, retrieves the template, applies name/description updates via updateNamedNode, and persists changes reactively.

core/src/main/kotlin/gropius/dto/input/template/UpdateIMSProjectTemplateInput.kt (1)

6-7: LGTM! Valid minimal input DTO.

This input type correctly extends UpdateNamedNodeInput to provide name and description updates for IMS project templates without requiring additional fields.

core/src/main/kotlin/gropius/dto/input/template/UpdateComponentVersionTemplateInput.kt (1)

6-7: LGTM! Valid minimal input DTO.

This input type correctly extends UpdateNamedNodeInput to provide name and description updates for component version templates without requiring additional fields.

core/src/main/kotlin/gropius/service/template/ArtefactTemplateService.kt (1)

40-56: LGTM! Correctly implements the update flow.

The updateArtefactTemplate method follows the established pattern consistently: validates input, checks permissions, retrieves the template, applies updates via updateNamedNode, and persists changes reactively.

core/src/main/kotlin/gropius/dto/input/template/UpdateInterfaceSpecificationVersionTemplateInput.kt (1)

1-7: LGTM!

The input DTO is correctly structured and consistent with other template update input types in the PR.

core/src/main/kotlin/gropius/service/template/IssuePriorityService.kt (1)

32-43: LGTM!

The update method correctly handles both the base NamedNode fields and the optional value field. The implementation follows the established pattern and properly uses OptionalInput to handle partial updates.

core/src/main/kotlin/gropius/service/template/ComponentTemplateService.kt (1)

77-91: LGTM!

The updateComponentTemplate method correctly updates the shape properties and follows the established pattern for template updates.

core/src/main/kotlin/gropius/service/template/IntraComponentDependencySpecificationTypeService.kt (1)

31-39: LGTM!

The update method follows the established pattern and correctly delegates to updateNamedNode for field updates. The implementation is consistent with other template update services in this PR.

core/src/main/kotlin/gropius/service/template/IssueTypeService.kt (1)

32-43: LGTM!

The update implementation correctly validates input, enforces permissions, retrieves the entity, updates fields conditionally, and persists changes.

core/src/main/kotlin/gropius/service/template/IssueStateService.kt (1)

31-39: LGTM!

The implementation is clean and follows the established update pattern consistently.

core/src/main/kotlin/gropius/service/template/IMSTemplateService.kt (1)

38-46: LGTM!

The base template update is implemented correctly using the type-safe repository.

core/src/main/kotlin/gropius/service/template/InterfaceSpecificationTemplateService.kt (1)

85-99: LGTM!

The implementation correctly handles optional field updates for shapeRadius and shapeType while following the established pattern.

api-public/src/main/kotlin/gropius/schema/mutation/TemplateMutations.kt (1)

102-334: LGTM!

All 16 new update mutation endpoints follow a consistent pattern with proper annotations, clear descriptions, and appropriate delegation to service layers. The authorization context is uniformly extracted and passed to service methods.

core/src/main/kotlin/gropius/service/template/AssignmentTypeService.kt (3)

3-3: No action required; the import is correct.

The GropiusAuthorizationContext class is actually located at core/src/main/kotlin/gropius/authorization/GropiusAuthorizationContext.kt, which matches the import statement on line 3. The AI summary was inaccurate—the class is in the gropius.authorization package, not gropius.security. This import will compile without errors.

Likely an incorrect or invalid review comment.


35-35: The permission check is correct; no changes needed.

The codebase consistently uses checkCreateTemplatePermission for all template update operations across 20+ services. The method's documentation explicitly states "create/update Templates," confirming this is intentional design where both operations share a single unified permission (CAN_CREATE_TEMPLATES). This is not a semantic mismatch but rather a deliberate authorization model choice.

Likely an incorrect or invalid review comment.


36-36: Error handling for repository.findById() is consistent and correctly standardized across the codebase.

The findById function in RepositoryExtensions.kt wraps Spring Data's ReactiveCrudRepository.findById() with awaitSingle(), which throws a NoSuchElementException when an entity is not found. This behavior is consistent across all 70+ service files and represents the standard error-handling strategy for this codebase. The code at line 36 of AssignmentTypeService.kt correctly follows this pattern.

Copy link
Contributor

@chriku chriku left a comment

Choose a reason for hiding this comment

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

Of course, same applies to the other .ifPresent

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (3)
core/src/main/kotlin/gropius/service/template/IMSTemplateService.kt (1)

11-37: Implementation matches the established update pattern; only KDoc might be slightly broad.

The update logic is consistent and correct. If AbstractTemplateService does not in fact provide create/delete operations (or that changes in future), consider tightening the class KDoc so it stays accurate.

core/src/main/kotlin/gropius/service/template/InterfaceSpecificationVersionTemplateService.kt (1)

11-37: Update method is correct and aligned with the other template services.

The validate → permission → load → updateNamedNode → save pattern is applied cleanly here as well. If similar update methods proliferate further, consider factoring a small helper in the base service to reduce repetition, but it’s not urgent.

core/src/main/kotlin/gropius/service/template/InterfacePartTemplateService.kt (1)

1-39: LGTM! Implementation follows the established service pattern.

The service correctly implements the update workflow and is consistent with other template services.

Note: This service is nearly identical to ComponentVersionTemplateService (both share the same structure with only type differences). While this duplication ensures type safety and clarity, consider whether a more generic approach could reduce repetition across template services if the pattern continues to grow.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b788129 and 501716a.

📒 Files selected for processing (16)
  • api-public/src/main/kotlin/gropius/schema/mutation/TemplateMutations.kt (1 hunks)
  • core/src/main/kotlin/gropius/repository/template/ComponentVersionTemplateRepository.kt (1 hunks)
  • core/src/main/kotlin/gropius/repository/template/IMSIssueTemplateRepository.kt (1 hunks)
  • core/src/main/kotlin/gropius/repository/template/IMSProjectTemplateRepository.kt (1 hunks)
  • core/src/main/kotlin/gropius/repository/template/IMSUserTemplateRepository.kt (1 hunks)
  • core/src/main/kotlin/gropius/repository/template/InterfacePartTemplateRepository.kt (1 hunks)
  • core/src/main/kotlin/gropius/repository/template/InterfaceSpecificationVersionTemplateRepository.kt (1 hunks)
  • core/src/main/kotlin/gropius/service/template/ComponentTemplateService.kt (2 hunks)
  • core/src/main/kotlin/gropius/service/template/ComponentVersionTemplateService.kt (1 hunks)
  • core/src/main/kotlin/gropius/service/template/IMSIssueTemplateService.kt (1 hunks)
  • core/src/main/kotlin/gropius/service/template/IMSProjectTemplateService.kt (1 hunks)
  • core/src/main/kotlin/gropius/service/template/IMSTemplateService.kt (1 hunks)
  • core/src/main/kotlin/gropius/service/template/IMSUserTemplateService.kt (1 hunks)
  • core/src/main/kotlin/gropius/service/template/InterfacePartTemplateService.kt (1 hunks)
  • core/src/main/kotlin/gropius/service/template/InterfaceSpecificationTemplateService.kt (2 hunks)
  • core/src/main/kotlin/gropius/service/template/InterfaceSpecificationVersionTemplateService.kt (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (13)
core/src/main/kotlin/gropius/service/template/InterfacePartTemplateService.kt (2)
core/src/main/kotlin/gropius/service/template/BaseTemplateService.kt (1)
  • checkCreateTemplatePermission (69-74)
core/src/main/kotlin/gropius/service/common/NamedNodeService.kt (1)
  • updateNamedNode (26-33)
core/src/main/kotlin/gropius/service/template/IMSProjectTemplateService.kt (2)
core/src/main/kotlin/gropius/service/template/BaseTemplateService.kt (1)
  • checkCreateTemplatePermission (69-74)
core/src/main/kotlin/gropius/service/common/NamedNodeService.kt (1)
  • updateNamedNode (26-33)
core/src/main/kotlin/gropius/repository/template/InterfacePartTemplateRepository.kt (1)
core/src/main/kotlin/gropius/repository/architecture/InterfacePartRepository.kt (1)
  • @Repository (10-11)
core/src/main/kotlin/gropius/repository/template/InterfaceSpecificationVersionTemplateRepository.kt (3)
core/src/main/kotlin/gropius/repository/template/InterfaceSpecificationTemplateRepository.kt (1)
  • @Repository (10-11)
core/src/main/kotlin/gropius/repository/architecture/InterfaceSpecificationVersionRepository.kt (1)
  • @Repository (10-11)
core/src/main/kotlin/gropius/repository/architecture/InterfaceSpecificationRepository.kt (1)
  • @Repository (10-11)
core/src/main/kotlin/gropius/service/template/ComponentVersionTemplateService.kt (2)
core/src/main/kotlin/gropius/service/template/BaseTemplateService.kt (1)
  • checkCreateTemplatePermission (69-74)
core/src/main/kotlin/gropius/service/common/NamedNodeService.kt (1)
  • updateNamedNode (26-33)
core/src/main/kotlin/gropius/service/template/IMSTemplateService.kt (2)
core/src/main/kotlin/gropius/service/template/BaseTemplateService.kt (1)
  • checkCreateTemplatePermission (69-74)
core/src/main/kotlin/gropius/service/common/NamedNodeService.kt (1)
  • updateNamedNode (26-33)
core/src/main/kotlin/gropius/service/template/IMSIssueTemplateService.kt (2)
core/src/main/kotlin/gropius/service/template/BaseTemplateService.kt (1)
  • checkCreateTemplatePermission (69-74)
core/src/main/kotlin/gropius/service/common/NamedNodeService.kt (1)
  • updateNamedNode (26-33)
core/src/main/kotlin/gropius/repository/template/IMSUserTemplateRepository.kt (2)
core/src/main/kotlin/gropius/repository/template/IMSTemplateRepository.kt (1)
  • @Repository (10-11)
core/src/main/kotlin/gropius/repository/user/IMSUserRepository.kt (1)
  • @Repository (10-11)
core/src/main/kotlin/gropius/service/template/InterfaceSpecificationTemplateService.kt (2)
core/src/main/kotlin/gropius/service/template/BaseTemplateService.kt (1)
  • checkCreateTemplatePermission (69-74)
core/src/main/kotlin/gropius/service/common/NamedNodeService.kt (1)
  • updateNamedNode (26-33)
core/src/main/kotlin/gropius/service/template/IMSUserTemplateService.kt (2)
core/src/main/kotlin/gropius/service/template/BaseTemplateService.kt (1)
  • checkCreateTemplatePermission (69-74)
core/src/main/kotlin/gropius/service/common/NamedNodeService.kt (1)
  • updateNamedNode (26-33)
core/src/main/kotlin/gropius/repository/template/IMSIssueTemplateRepository.kt (2)
core/src/main/kotlin/gropius/repository/template/IssueTemplateRepository.kt (1)
  • @Repository (10-11)
core/src/main/kotlin/gropius/repository/architecture/IMSIssueRepository.kt (1)
  • @Repository (10-11)
core/src/main/kotlin/gropius/service/template/InterfaceSpecificationVersionTemplateService.kt (2)
core/src/main/kotlin/gropius/service/template/BaseTemplateService.kt (1)
  • checkCreateTemplatePermission (69-74)
core/src/main/kotlin/gropius/service/common/NamedNodeService.kt (1)
  • updateNamedNode (26-33)
core/src/main/kotlin/gropius/service/template/ComponentTemplateService.kt (2)
core/src/main/kotlin/gropius/service/template/BaseTemplateService.kt (1)
  • checkCreateTemplatePermission (69-74)
core/src/main/kotlin/gropius/service/common/NamedNodeService.kt (1)
  • updateNamedNode (26-33)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Build
🔇 Additional comments (13)
core/src/main/kotlin/gropius/repository/template/ComponentVersionTemplateRepository.kt (1)

1-11: LGTM! Standard repository interface.

The repository interface follows the established Spring Data pattern and correctly extends GropiusRepository with appropriate type parameters.

core/src/main/kotlin/gropius/service/template/InterfaceSpecificationTemplateService.kt (1)

73-95: LGTM! Consistent update implementation.

The update method follows the established pattern for template updates: validates input, checks authorization, fetches the entity, applies updates via updateNamedNode, handles optional fields with ifPresent, and persists the changes. The implementation is correct and consistent with similar update methods across the codebase.

core/src/main/kotlin/gropius/repository/template/IMSProjectTemplateRepository.kt (1)

1-11: LGTM! Standard repository interface.

The repository follows the established pattern and correctly extends GropiusRepository for IMSProjectTemplate entities.

core/src/main/kotlin/gropius/repository/template/IMSUserTemplateRepository.kt (1)

1-11: LGTM! Standard repository interface.

The repository interface follows the established pattern and is consistent with similar repositories in the codebase (e.g., IMSTemplateRepository, IMSUserRepository).

core/src/main/kotlin/gropius/repository/template/InterfaceSpecificationVersionTemplateRepository.kt (1)

1-11: LGTM! Standard repository interface.

The repository follows the established pattern and is consistent with related repositories like InterfaceSpecificationTemplateRepository and InterfaceSpecificationVersionRepository.

core/src/main/kotlin/gropius/service/template/IMSUserTemplateService.kt (1)

1-39: LGTM! Well-structured service implementation.

The service correctly extends BaseTemplateService and implements the update method following the established pattern. Authorization, validation, and persistence are all properly handled.

core/src/main/kotlin/gropius/service/template/ComponentTemplateService.kt (1)

66-88: LGTM! Consistent update implementation.

The update method follows the established pattern and correctly handles validation, authorization, entity retrieval, property updates with ifPresent for optional fields, and persistence.

core/src/main/kotlin/gropius/repository/template/IMSIssueTemplateRepository.kt (1)

1-11: LGTM! Standard repository interface.

The repository follows the established pattern and is consistent with related repositories like IssueTemplateRepository and IMSIssueRepository.

core/src/main/kotlin/gropius/repository/template/InterfacePartTemplateRepository.kt (1)

1-11: Repository wiring looks correct and consistent with existing pattern.

Package, imports, annotation, and generic parameters align with InterfacePartRepository; nothing to change here.

core/src/main/kotlin/gropius/service/template/IMSProjectTemplateService.kt (1)

11-37: Update flow is straightforward and consistent with other template services.

Validation, permission check, lookup, update, and save are ordered sensibly and use the shared helpers; no changes needed.

core/src/main/kotlin/gropius/service/template/IMSIssueTemplateService.kt (1)

11-37: Consistent and type-safe update implementation.

Follows the same validated, permission-checked update flow as other template services and relies on the typed repository without unsafe casts; looks good.

core/src/main/kotlin/gropius/service/template/ComponentVersionTemplateService.kt (1)

1-39: LGTM! Clean service implementation following established patterns.

The service correctly implements the update workflow: validation → authorization → retrieval → update → persistence. The pattern is consistent with other template services in the codebase.

api-public/src/main/kotlin/gropius/schema/mutation/TemplateMutations.kt (1)

102-334: LGTM! All 18 update mutations correctly implement the GraphQL schema.

Each mutation properly:

  • Declares authorization requirements (CAN_CREATE_TEMPLATES)
  • Uses the correct service type for its template
  • Delegates to the corresponding service update method
  • Follows the established pattern consistently

The highly repetitive structure is typical for explicit GraphQL mutation definitions and ensures type safety. While the duplication could theoretically be reduced through code generation or meta-programming, the current approach prioritizes clarity and explicitness.

nk-coding and others added 2 commits November 17, 2025 21:41
…rvice.kt

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (1)
api-public/src/main/kotlin/gropius/schema/mutation/TemplateMutations.kt (1)

102-282: Optional: Reduce repeated GraphQL wiring for future maintenance.

All these update* methods share nearly identical plumbing (input + DataFetchingEnvironment + injected service + dfe.gropiusAuthorizationContext delegation). If you expect to add more of these, consider a small helper/extension (or even codegen) to centralize this pattern and reduce copy‑paste overhead. This is purely optional and the current explicit version is perfectly fine.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ea5fe8e and 2536c85.

📒 Files selected for processing (1)
  • api-public/src/main/kotlin/gropius/schema/mutation/TemplateMutations.kt (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Build
🔇 Additional comments (1)
api-public/src/main/kotlin/gropius/schema/mutation/TemplateMutations.kt (1)

102-282: New update mutations are consistent and correctly wired.

The added update* mutations consistently mirror the existing create* and deprecation mutations: each uses the appropriate Update*Input type, delegates to the matching Service.update method with dfe.gropiusAuthorizationContext, and returns the correct model type. Annotations (@GraphQLDescription, @AutoPayloadType, @GraphQLIgnore, @Autowired) are applied uniformly, and I don't see correctness, auth, or transactional issues in this wiring.

@nk-coding nk-coding merged commit e8b32dd into main Nov 18, 2025
2 checks passed
@nk-coding nk-coding deleted the feature/template_update_mutations branch November 18, 2025 02:02
@coderabbitai coderabbitai bot mentioned this pull request Dec 18, 2025
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.

2 participants