feat: add catalog support, entity pages, and creation wizards for ProjectType / ClusterProjectType#645
Conversation
📝 WalkthroughWalkthroughAdds complete Backstage catalog support for OpenChoreo ChangesProjectType & ClusterProjectType Catalog Support
Sequence Diagram(s)sequenceDiagram
rect rgba(70, 130, 180, 0.5)
note over TemplateWizard,ImmediateCatalog: Scaffolder creation flow
TemplateWizard->>ScaffolderBackend: submit ProjectType YAML + namespace
ScaffolderBackend->>ScaffolderBackend: validate YAML kind/apiVersion/metadata
ScaffolderBackend->>OpenChoreoAPI: POST /api/v1/namespaces/{ns}/projecttypes
OpenChoreoAPI-->>ScaffolderBackend: created ProjectType metadata
ScaffolderBackend->>ImmediateCatalog: insertEntity(ProjectTypeEntity)
ScaffolderBackend-->>TemplateWizard: outputs entityRef, projectTypeName
end
rect rgba(34, 139, 34, 0.5)
note over OpenChoreoEntityProvider,BackstageCatalog: Full-sync and event ingestion
OpenChoreoEntityProvider->>OpenChoreoAPI: list projecttypes per namespace
OpenChoreoEntityProvider->>OpenChoreoAPI: list clusterprojecttypes
OpenChoreoEntityProvider->>BackstageCatalog: upsert translated entities
EventDeltaApplier->>OpenChoreoAPI: fetch projecttype/clusterprojecttype on webhook
EventDeltaApplier->>BackstageCatalog: upsert or remove entity refs
end
rect rgba(180, 70, 70, 0.5)
note over EntityPage,ProjectTypeOverviewCard: Catalog UI rendering
EntityPage->>ProjectTypeOverviewCard: render for projecttype/clusterprojecttype entity
ProjectTypeOverviewCard->>OpenChoreoBackend: getResourceDefinition(kind, ns, name)
OpenChoreoBackend-->>ProjectTypeOverviewCard: spec with parameters/resources/validations
ProjectTypeOverviewCard->>EntityPage: render Parameters, EnvConfigs, Resources, Validations
end
Estimated code review effort🎯 4 (Complex) | ⏱️ ~75 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
|
Changeset detected — the following file(s) will be released with this PR: |
5bd6895 to
eb1be4f
Compare
Codecov Report❌ Patch coverage is 📢 Thoughts on this report? Let us know! |
79742bf to
676c46d
Compare
|
@coderabbitai full-review |
|
✅ Action performedFull review finished. |
There was a problem hiding this comment.
Actionable comments posted: 7
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
packages/openchoreo-client-node/openapi/openchoreo-api.yaml (1)
7145-7197:⚠️ Potential issue | 🟠 MajorResolve the
Project.spec.typerequired/default contract.
Projectstill only requiresmetadata, andProjectSpechas norequiredlist, so generated clients will modelspec.typeas optional. That conflicts with the PR objective that Projects now have a required ProjectType linkage; the documentedClusterProjectType/defaultfallback is also prose-only, while the nestedkinddefault isProjectType. Either requirespec.typein the upstream schema or make the downstream translators/services synthesize the documented cluster default before emitting annotations and relations.This applies to lines 7145-7197 and 7228-7249 (both the ProjectSpec and Project schema definitions).
🤖 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 `@packages/openchoreo-client-node/openapi/openchoreo-api.yaml` around lines 7145 - 7197, The ProjectSpec schema lacks a required constraint on the type field, making it optional in generated clients despite the intended requirement that Projects must have a ProjectType linkage with a documented fallback to the cluster-scoped default ClusterProjectType. Either add type to the required list in the ProjectSpec schema definition to enforce it at the schema level, or ensure downstream translators and services synthesize the documented cluster default before emitting annotations and relations. Apply this fix consistently across both schema definitions mentioned (ProjectSpec at the starting point and the Project schema definition that also needs updating).Source: Learnings
🧹 Nitpick comments (5)
plugins/openchoreo-backend/src/services/PlatformResourceService/PlatformResourceService.test.ts (1)
168-205: 🧹 Nitpick | 🔵 Trivial | ⚡ Quick winAssert exact client route/params for the new kinds.
These tests currently prove success flow, but they don’t verify the endpoint contracts (
/projecttypes/{ptName}and/clusterprojecttypes/{cptName}). AddtoHaveBeenCalledWithchecks so route or param-key regressions fail fast.Suggested assertion additions
@@ expect(result.success).toBe(true); expect(result.data).toEqual(pt); + expect(mockGET).toHaveBeenCalledWith( + '/api/v1/namespaces/{namespaceName}/projecttypes/{ptName}', + { params: { path: { namespaceName: 'test-ns', ptName: 'standard-project' } } }, + ); @@ expect(result.success).toBe(true); expect(result.data).toEqual(cpt); + expect(mockGET).toHaveBeenCalledWith('/api/v1/clusterprojecttypes/{cptName}', { + params: { path: { cptName: 'global-project' } }, + }); @@ expect(result.success).toBe(true); expect(result.data?.kind).toBe('ProjectType'); expect(mockPUT).toHaveBeenCalledTimes(1); + expect(mockPUT).toHaveBeenCalledWith( + '/api/v1/namespaces/{namespaceName}/projecttypes/{ptName}', + expect.objectContaining({ + params: { path: { namespaceName: 'test-ns', ptName: 'standard-project' } }, + }), + ); @@ expect(result.success).toBe(true); expect(result.data?.kind).toBe('ClusterProjectType'); expect(mockPUT).toHaveBeenCalledTimes(1); + expect(mockPUT).toHaveBeenCalledWith( + '/api/v1/clusterprojecttypes/{cptName}', + expect.objectContaining({ params: { path: { cptName: 'global-project' } } }), + ); @@ expect(result.success).toBe(true); expect(result.data?.kind).toBe('ProjectType'); + expect(mockDELETE).toHaveBeenCalledWith( + '/api/v1/namespaces/{namespaceName}/projecttypes/{ptName}', + { params: { path: { namespaceName: 'test-ns', ptName: 'standard-project' } } }, + ); @@ expect(result.success).toBe(true); expect(result.data?.kind).toBe('ClusterProjectType'); + expect(mockDELETE).toHaveBeenCalledWith('/api/v1/clusterprojecttypes/{cptName}', { + params: { path: { cptName: 'global-project' } }, + });Also applies to: 345-386, 496-531
🤖 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 `@plugins/openchoreo-backend/src/services/PlatformResourceService/PlatformResourceService.test.ts` around lines 168 - 205, The tests for fetches projecttype via new API and fetches clusterprojecttype via new API currently only verify the success flow but do not verify that the correct client routes and parameters are being used. Add toHaveBeenCalledWith assertions to the mockGET mock object after each service call to verify that the correct endpoint paths are being called, such as /projecttypes/{ptName} for the projecttype test and /clusterprojecttypes/{cptName} for the clusterprojecttype test. This ensures that route regressions or parameter mismatches are caught immediately in tests.plugins/openchoreo-react/src/hooks/useProjectTypePermission.test.ts (1)
39-47: 🧹 Nitpick | 🔵 Trivial | ⚡ Quick winVerify the exact permission object in the mocked call.
Please also assert that
openchoreoProjectTypeCreatePermissionis sent tousePermission; checking onlyresourceRefomission leaves a regression gap.Proposed test hardening
import { renderHook } from '`@testing-library/react`'; +import { openchoreoProjectTypeCreatePermission } from '`@openchoreo/backstage-plugin-common`'; import { useProjectTypePermission } from './useProjectTypePermission'; @@ it('does not pass resourceRef to usePermission', () => { mockUsePermission.mockReturnValue({ allowed: true, loading: false }); renderHook(() => useProjectTypePermission()); + expect(mockUsePermission).toHaveBeenCalledWith( + expect.objectContaining({ + permission: openchoreoProjectTypeCreatePermission, + }), + ); expect(mockUsePermission).toHaveBeenCalledWith( expect.not.objectContaining({ resourceRef: expect.anything() }), ); });🤖 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 `@plugins/openchoreo-react/src/hooks/useProjectTypePermission.test.ts` around lines 39 - 47, The test in useProjectTypePermission.test.ts only verifies that resourceRef is absent from the usePermission call but does not verify that the correct permission object is being passed. Update the test to assert that mockUsePermission is called with openchoreoProjectTypeCreatePermission as an argument, in addition to the existing check that resourceRef is not included. This ensures the hook passes both the correct permission and excludes the resourceRef parameter.plugins/openchoreo-react/src/hooks/useClusterProjectTypePermission.test.ts (1)
39-47: 🧹 Nitpick | 🔵 Trivial | ⚡ Quick winAssert the permission constant in the hook call.
This test currently verifies only that
resourceRefis omitted. It should also assert thatopenchoreoClusterProjectTypeCreatePermissionis passed, otherwise a wrong permission constant would still pass.Proposed test hardening
import { renderHook } from '`@testing-library/react`'; +import { openchoreoClusterProjectTypeCreatePermission } from '`@openchoreo/backstage-plugin-common`'; import { useClusterProjectTypePermission } from './useClusterProjectTypePermission'; @@ it('does not pass resourceRef to usePermission', () => { mockUsePermission.mockReturnValue({ allowed: true, loading: false }); renderHook(() => useClusterProjectTypePermission()); + expect(mockUsePermission).toHaveBeenCalledWith( + expect.objectContaining({ + permission: openchoreoClusterProjectTypeCreatePermission, + }), + ); expect(mockUsePermission).toHaveBeenCalledWith( expect.not.objectContaining({ resourceRef: expect.anything() }), ); });🤖 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 `@plugins/openchoreo-react/src/hooks/useClusterProjectTypePermission.test.ts` around lines 39 - 47, The test for useClusterProjectTypePermission in the test file currently only verifies that resourceRef is not passed to mockUsePermission, but does not assert that the correct permission constant openchoreoClusterProjectTypeCreatePermission is actually being passed. Enhance the expect statement for the mockUsePermission call to verify both conditions: that resourceRef is absent AND that openchoreoClusterProjectTypeCreatePermission is present in the arguments passed to mockUsePermission, ensuring the hook calls the permission hook with the correct permission constant.plugins/openchoreo/src/components/ProjectTypeOverview/ProjectTypeOverviewCard.test.tsx (1)
97-103: 🧹 Nitpick | 🔵 TrivialWrap mock call assertions in
waitForfor explicit async safety.The title appears synchronously from
entity.kind, not from the async effect. Replace the title-based synchronization with explicit waits around the mock call assertions to prevent potential flakiness.Suggested patch
- await screen.findByText('ProjectType Details'); - expect(getResourceDefinition).toHaveBeenCalledWith( - 'projecttypes', - 'finance', - 'web-service', - ); + await waitFor(() => { + expect(getResourceDefinition).toHaveBeenCalledWith( + 'projecttypes', + 'finance', + 'web-service', + ); + });Also applies to: 109-115
🤖 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 `@plugins/openchoreo/src/components/ProjectTypeOverview/ProjectTypeOverviewCard.test.tsx` around lines 97 - 103, The mock call assertion for getResourceDefinition is not properly synchronized with its async execution. The current code uses screen.findByText('ProjectType Details') as a synchronization point, but since this title comes from a synchronous value (entity.kind), it doesn't reliably wait for the async effect that triggers the mock call. Wrap the expect(getResourceDefinition).toHaveBeenCalledWith(...) assertion inside a waitFor call to explicitly wait for the async operation to complete before checking the mock invocation. Apply this same fix to both test cases mentioned (lines 97-103 and lines 109-115).plugins/catalog-backend-module-openchoreo/src/processors/processors.test.ts (1)
1473-1499: 🧹 Nitpick | 🔵 Trivial | ⚡ Quick winClusterProjectType relation test should assert the reverse edge too.
This case only verifies
RELATION_INSTANCE_OF. AddRELATION_HAS_INSTANCE(and call count) like the namespaced ProjectType test, otherwise a one-way regression can slip through.Suggested assertion extension
it('targets the openchoreo-cluster namespace for a ClusterProjectType ref', async () => { @@ expect(emit).toHaveBeenCalledWith( processingResult.relation({ source: { kind: 'system', namespace: 'my-ns', name: 'proj-1' }, target: { kind: 'clusterprojecttype', namespace: 'openchoreo-cluster', name: 'global-project', }, type: RELATION_INSTANCE_OF, }), ); + expect(emit).toHaveBeenCalledWith( + processingResult.relation({ + source: { + kind: 'clusterprojecttype', + namespace: 'openchoreo-cluster', + name: 'global-project', + }, + target: { kind: 'system', namespace: 'my-ns', name: 'proj-1' }, + type: RELATION_HAS_INSTANCE, + }), + ); + expect(emit).toHaveBeenCalledTimes(2); });🤖 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 `@plugins/catalog-backend-module-openchoreo/src/processors/processors.test.ts` around lines 1473 - 1499, The ClusterProjectType relation test only verifies the RELATION_INSTANCE_OF direction but is missing the reverse edge assertion. Add an additional expect statement to verify that emit was also called with RELATION_HAS_INSTANCE (with source and target reversed compared to the RELATION_INSTANCE_OF call), and add a call count assertion to expect emit to have been called exactly twice. This matches the pattern used in the namespaced ProjectType test and prevents one-way relation regressions from slipping through.
🤖 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
`@packages/app/src/scaffolder/ProjectTypeYamlEditor/ProjectTypeYamlEditorExtension.tsx`:
- Around line 147-174: In the projectTypeYamlEditorValidation function, add
validation logic after the existing checks to ensure that parsed.spec.resources
contains a required Namespace template resource with id equal to
'cell-namespace' and metadata.name matching the expected namespace pattern. If
this required resource is missing or doesn't meet the criteria, add an
appropriate error message to the validation object. Apply the same validation
rule to the equivalent validator function in
ClusterProjectTypeYamlEditorExtension.tsx to maintain consistency between both
editors.
In `@packages/openchoreo-client-node/openapi/openchoreo-api.yaml`:
- Around line 94-95: Add all operation tags to the root-level tags list in the
OpenAPI specification file. The tags ClusterProjectTypes, ProjectTypes,
ProjectReleases, and ProjectReleaseBindings are referenced by operations
throughout the file but are missing from the root tags declaration, which causes
incomplete metadata for documentation generation, linting, and code generation.
Locate the root tags section near the top of the file and add entries for each
missing tag with appropriate name and description properties.
- Around line 4586-5156: The openchoreo-api.yaml file contains formatting
differences from the upstream openchoreo/openchoreo main branch, including quote
style variations (double quotes vs single quotes in examples) and minor
whitespace differences. Since this is a mirror file that must remain in exact
sync with upstream, re-sync or regenerate the file directly from the upstream
specification in the openchoreo/openchoreo repository to ensure byte-for-byte
consistency before merging.
In `@plugins/catalog-backend-module-openchoreo/src/processors/processors.test.ts`:
- Around line 699-703: The Domain targets in the processingResult.relation()
assertions are using namespace 'my-ns' instead of 'default', which creates a
mismatch with how Domain entities are actually managed. Update all test
assertions in the processors.test.ts file where Domain targets are specified
(those with kind: 'domain') to use namespace: 'default' instead of namespace:
'my-ns'. Additionally, ensure the ProjectTypeEntityProcessor implementation
itself follows the same pattern so that domain relations always reference
entities in the default namespace, maintaining consistency between the processor
logic and test expectations.
In
`@plugins/openchoreo/src/components/ProjectTypeOverview/ProjectTypeOverviewCard.tsx`:
- Around line 75-85: The useEffect hook used for fetching project type
definitions is missing critical dependencies in its dependency array. The
namespace value is derived from annotations[CHOREO_ANNOTATIONS.NAMESPACE] and
entity.metadata.namespace, and these values are used in the API request at line
88, but they are not included in the dependency array. Add both
annotations[CHOREO_ANNOTATIONS.NAMESPACE] and entity.metadata.namespace to the
useEffect dependency array so that the effect re-runs whenever the namespace
changes, ensuring the card displays the correct definition for the updated
namespace.
In
`@plugins/scaffolder-backend-module-openchoreo/src/actions/clusterProjectType.ts`:
- Around line 40-44: The ctx.logger.debug calls are serializing and logging the
entire ctx.input payload using JSON.stringify, which can leak sensitive
user-supplied configuration into logs. Replace the full input serialization with
a sanitized version that only logs non-sensitive fields or explicitly redacts
sensitive configuration data. Apply this redaction to both logging statements:
the one around line 40-44 in the debug call and the one around line 109-113.
Instead of logging JSON.stringify(ctx.input), extract and log only safe field
names or provide a redacted representation that masks any sensitive
configuration values.
In `@plugins/scaffolder-backend-module-openchoreo/src/actions/projectType.ts`:
- Around line 46-48: The code logs full user-supplied YAML payloads containing
sensitive configuration values by serializing ctx.input and apiBody directly in
the logger calls. Identify both logging locations in the file: the
ctx.logger.debug call that logs ctx.input (around line 46) and the similar
logging statement with apiBody (around line 122). Instead of logging the entire
objects with JSON.stringify, modify both logs to only include non-sensitive
information such as the action type or a simple request identifier, while
excluding the actual payload content that may contain template configuration
secrets.
---
Outside diff comments:
In `@packages/openchoreo-client-node/openapi/openchoreo-api.yaml`:
- Around line 7145-7197: The ProjectSpec schema lacks a required constraint on
the type field, making it optional in generated clients despite the intended
requirement that Projects must have a ProjectType linkage with a documented
fallback to the cluster-scoped default ClusterProjectType. Either add type to
the required list in the ProjectSpec schema definition to enforce it at the
schema level, or ensure downstream translators and services synthesize the
documented cluster default before emitting annotations and relations. Apply this
fix consistently across both schema definitions mentioned (ProjectSpec at the
starting point and the Project schema definition that also needs updating).
---
Nitpick comments:
In `@plugins/catalog-backend-module-openchoreo/src/processors/processors.test.ts`:
- Around line 1473-1499: The ClusterProjectType relation test only verifies the
RELATION_INSTANCE_OF direction but is missing the reverse edge assertion. Add an
additional expect statement to verify that emit was also called with
RELATION_HAS_INSTANCE (with source and target reversed compared to the
RELATION_INSTANCE_OF call), and add a call count assertion to expect emit to
have been called exactly twice. This matches the pattern used in the namespaced
ProjectType test and prevents one-way relation regressions from slipping
through.
In
`@plugins/openchoreo-backend/src/services/PlatformResourceService/PlatformResourceService.test.ts`:
- Around line 168-205: The tests for fetches projecttype via new API and fetches
clusterprojecttype via new API currently only verify the success flow but do not
verify that the correct client routes and parameters are being used. Add
toHaveBeenCalledWith assertions to the mockGET mock object after each service
call to verify that the correct endpoint paths are being called, such as
/projecttypes/{ptName} for the projecttype test and
/clusterprojecttypes/{cptName} for the clusterprojecttype test. This ensures
that route regressions or parameter mismatches are caught immediately in tests.
In `@plugins/openchoreo-react/src/hooks/useClusterProjectTypePermission.test.ts`:
- Around line 39-47: The test for useClusterProjectTypePermission in the test
file currently only verifies that resourceRef is not passed to
mockUsePermission, but does not assert that the correct permission constant
openchoreoClusterProjectTypeCreatePermission is actually being passed. Enhance
the expect statement for the mockUsePermission call to verify both conditions:
that resourceRef is absent AND that openchoreoClusterProjectTypeCreatePermission
is present in the arguments passed to mockUsePermission, ensuring the hook calls
the permission hook with the correct permission constant.
In `@plugins/openchoreo-react/src/hooks/useProjectTypePermission.test.ts`:
- Around line 39-47: The test in useProjectTypePermission.test.ts only verifies
that resourceRef is absent from the usePermission call but does not verify that
the correct permission object is being passed. Update the test to assert that
mockUsePermission is called with openchoreoProjectTypeCreatePermission as an
argument, in addition to the existing check that resourceRef is not included.
This ensures the hook passes both the correct permission and excludes the
resourceRef parameter.
In
`@plugins/openchoreo/src/components/ProjectTypeOverview/ProjectTypeOverviewCard.test.tsx`:
- Around line 97-103: The mock call assertion for getResourceDefinition is not
properly synchronized with its async execution. The current code uses
screen.findByText('ProjectType Details') as a synchronization point, but since
this title comes from a synchronous value (entity.kind), it doesn't reliably
wait for the async effect that triggers the mock call. Wrap the
expect(getResourceDefinition).toHaveBeenCalledWith(...) assertion inside a
waitFor call to explicitly wait for the async operation to complete before
checking the mock invocation. Apply this same fix to both test cases mentioned
(lines 97-103 and lines 109-115).
🪄 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: defaults
Review profile: CHILL
Plan: Pro
Run ID: 38a04dcf-f67a-4702-aab3-386fb30a4c00
⛔ Files ignored due to path filters (1)
packages/openchoreo-client-node/src/generated/openchoreo/types.tsis excluded by!**/generated/**
📒 Files selected for processing (69)
.changeset/projecttype-catalog-support.mdapp-config.production.yamlapp-config.yamlpackages/app/src/components/catalog/EntityLayoutWithDelete.tsxpackages/app/src/components/catalog/EntityPage.tsxpackages/app/src/components/catalog/OpenChoreoAboutCard.tsxpackages/app/src/components/catalog/useKindCreateConfig.tspackages/app/src/components/scaffolder/CustomTemplateListPage.tsxpackages/app/src/components/scaffolder/OpenChoreoScaffolderPage.tsxpackages/app/src/kindIcons.tspackages/app/src/scaffolder/ClusterProjectTypeYamlEditor/ClusterProjectTypeYamlEditorExtension.test.tsxpackages/app/src/scaffolder/ClusterProjectTypeYamlEditor/ClusterProjectTypeYamlEditorExtension.tsxpackages/app/src/scaffolder/ClusterProjectTypeYamlEditor/extensions.tspackages/app/src/scaffolder/ClusterProjectTypeYamlEditor/index.tspackages/app/src/scaffolder/ClusterProjectTypeYamlEditor/styles.tspackages/app/src/scaffolder/ProjectTypeYamlEditor/ProjectTypeYamlEditorExtension.test.tsxpackages/app/src/scaffolder/ProjectTypeYamlEditor/ProjectTypeYamlEditorExtension.tsxpackages/app/src/scaffolder/ProjectTypeYamlEditor/extensions.tspackages/app/src/scaffolder/ProjectTypeYamlEditor/index.tspackages/app/src/scaffolder/ProjectTypeYamlEditor/styles.tspackages/app/src/utils/kindUtils.tspackages/openchoreo-client-node/openapi-config.jsonpackages/openchoreo-client-node/openapi/openchoreo-api.yamlplugins/catalog-backend-module-openchoreo/src/index.tsplugins/catalog-backend-module-openchoreo/src/kinds/ClusterProjectTypeEntityV1alpha1.tsplugins/catalog-backend-module-openchoreo/src/kinds/ProjectTypeEntityV1alpha1.tsplugins/catalog-backend-module-openchoreo/src/kinds/index.tsplugins/catalog-backend-module-openchoreo/src/module.tsplugins/catalog-backend-module-openchoreo/src/processors/ClusterProjectTypeEntityProcessor.tsplugins/catalog-backend-module-openchoreo/src/processors/ProjectTypeEntityProcessor.tsplugins/catalog-backend-module-openchoreo/src/processors/SystemEntityProcessor.tsplugins/catalog-backend-module-openchoreo/src/processors/index.tsplugins/catalog-backend-module-openchoreo/src/processors/processors.test.tsplugins/catalog-backend-module-openchoreo/src/provider/EventDeltaApplier.test.tsplugins/catalog-backend-module-openchoreo/src/provider/EventDeltaApplier.tsplugins/catalog-backend-module-openchoreo/src/provider/OpenChoreoEntityProvider.tsplugins/catalog-backend-module-openchoreo/src/utils/entityTranslation.test.tsplugins/catalog-backend-module-openchoreo/src/utils/entityTranslation.tsplugins/openchoreo-backend/src/router.tsplugins/openchoreo-backend/src/services/PlatformResourceService/PlatformResourceService.test.tsplugins/openchoreo-backend/src/services/PlatformResourceService/PlatformResourceService.tsplugins/openchoreo-common/src/constants.tsplugins/openchoreo-common/src/index.tsplugins/openchoreo-common/src/permissions.test.tsplugins/openchoreo-common/src/permissions.tsplugins/openchoreo-react/src/hooks/useClusterProjectTypePermission.test.tsplugins/openchoreo-react/src/hooks/useClusterProjectTypePermission.tsplugins/openchoreo-react/src/hooks/useProjectTypePermission.test.tsplugins/openchoreo-react/src/hooks/useProjectTypePermission.tsplugins/openchoreo-react/src/hooks/useResourceDefinitionPermission.test.tsplugins/openchoreo-react/src/hooks/useResourceDefinitionPermission.tsplugins/openchoreo-react/src/index.tsplugins/openchoreo-react/src/utils/graphUtils.tsplugins/openchoreo/src/api/OpenChoreoClientApi.tsplugins/openchoreo/src/components/DeleteEntity/hooks/useEntityExistsCheck.tsplugins/openchoreo/src/components/ProjectTypeOverview/ProjectTypeOverviewCard.test.tsxplugins/openchoreo/src/components/ProjectTypeOverview/ProjectTypeOverviewCard.tsxplugins/openchoreo/src/components/ProjectTypeOverview/index.tsplugins/openchoreo/src/components/ResourceDefinition/utils.test.tsplugins/openchoreo/src/components/ResourceDefinition/utils.tsplugins/openchoreo/src/index.tsplugins/permission-backend-module-openchoreo-policy/src/rules/matchesCatalogEntityCapability.tsplugins/scaffolder-backend-module-openchoreo/src/actions/clusterProjectType.test.tsplugins/scaffolder-backend-module-openchoreo/src/actions/clusterProjectType.tsplugins/scaffolder-backend-module-openchoreo/src/actions/projectType.test.tsplugins/scaffolder-backend-module-openchoreo/src/actions/projectType.tsplugins/scaffolder-backend-module-openchoreo/src/module.tstemplates/create-openchoreo-clusterprojecttype/template.yamltemplates/create-openchoreo-projecttype/template.yaml
676c46d to
e000a6c
Compare
Sync the OpenChoreo API spec to core main (8340b423) and regenerate the TypeScript client. Brings in ProjectType / ClusterProjectType / ProjectTypeSpec / ProjectTypeRef types and the projecttype endpoints, plus Project.spec.type and sibling project-release endpoints landed since the last sync (0e735271). Signed-off-by: VajiraPrabuddhaka <vajiraprabuddhaka@gmail.com>
Add catalog support for the two new OpenChoreo project-type abstractions, mirroring the existing (Cluster)ResourceType ingestion path: - New ProjectType / ClusterProjectType entity kinds + translators. - Full-sync fetch of namespaced /projecttypes and cluster /clusterprojecttypes in OpenChoreoEntityProvider, with entity counts in the summary log. - Event-driven delta sync: subscribe to openchoreo.projecttype / openchoreo.clusterprojecttype and refresh via EventDeltaApplier. - Relation processors: ProjectType emits partOf/hasPart to its Domain; ClusterProjectType is cluster-scoped (no domain relation). - New PROJECT_TYPE / PROJECT_TYPE_KIND annotation constants. Unlike ResourceType, project types carry no scaffolder Template generation and no retainPolicy (deferred in core). Signed-off-by: VajiraPrabuddhaka <vajiraprabuddhaka@gmail.com>
Surface Project.spec.type on the System (Project) entity and emit the instanceOf / hasInstance relation pair to the referenced (Cluster)ProjectType, mirroring how Resources link to their (Cluster)ResourceType: - translateProjectToEntity stamps openchoreo.io/project-type and project-type-kind annotations from Project.spec.type. - SystemEntityProcessor emits instanceOf/hasInstance (cluster types target the openchoreo-cluster namespace), alongside the existing usesPipeline relation. Signed-off-by: VajiraPrabuddhaka <vajiraprabuddhaka@gmail.com>
e000a6c to
2bbc7f3
Compare
Give the two new project-type catalog kinds first-class entity pages, mirroring the (Cluster)ResourceType pages: - Backend: allow projecttypes / clusterprojecttypes through the generic platform-resource definition endpoint (router allowlist + PlatformResourceService GET/PUT/DELETE). - Frontend: ProjectTypeOverviewCard renders the parameters and environmentConfigs schemas, resource templates, and validation rules from the fetched CR; ResourceDefinition kind maps recognise the new kinds for the Definition tab. - App: projectTypePage / clusterProjectTypePage with Overview + Definition routes, wired into the EntitySwitch and kind display-name map. Signed-off-by: VajiraPrabuddhaka <vajiraprabuddhaka@gmail.com>
The entities were ingested into the catalog but the frontend kind registry had no entries for them, so the catalog kind picker / navigation, search filter, node graph, and delete wiring never surfaced them. - kindUtils: add projecttype / clusterprojecttype to kindDisplayNames, the "Platform Configuration" category (drives nav + kind picker), and the search filter kinds. - App.tsx: nav icons for the two kinds. - graphUtils: short + full node labels. - EntityLayoutWithDelete: include them in the delete-permission kind set. - OpenChoreoAboutCard: link a Project to its (Cluster)ProjectType from the project-type annotations. - useEntityExistsCheck: delete-flow display names. Signed-off-by: VajiraPrabuddhaka <vajiraprabuddhaka@gmail.com>
…it/delete
Wire create/update/delete permissions for ProjectType and ClusterProjectType,
mirroring the (Cluster)ResourceType pattern, so the Definition tab edit/delete
unlocks for users with the corresponding OpenChoreo authz capability:
- New openchoreo(Cluster)ProjectType{Create,Update,Delete}Permission defs,
registered in the openchoreoPermissions array and re-exported from the
package index.
- OPENCHOREO_PERMISSION_TO_ACTION entries mapping them to the core authz
actions projecttype:{create,update,delete} / clusterprojecttype:{...}.
- Catalog visibility: add the kinds to OPENCHOREO_MANAGED_ENTITY_KINDS and
CATALOG_KIND_TO_ACTION (view), plus the matching entity-level /
cluster-scoped entries in the matchesCatalogEntityCapability rule so they're
gated exactly like (Cluster)ResourceType.
- KIND_TO_PERMISSIONS in useResourceDefinitionPermission now covers
projecttype (resource-scoped) and clusterprojecttype (cluster-scoped).
Signed-off-by: VajiraPrabuddhaka <vajiraprabuddhaka@gmail.com>
…ards
Add the "Create (Cluster) Project Type" wizard flow, mirroring the
(Cluster)ResourceType creation pattern end to end:
- Scaffolder templates create-openchoreo-projecttype /
create-openchoreo-clusterprojecttype (registered in app-config + production),
a two-step form: metadata then a YAML editor.
- Custom field extensions ProjectTypeYamlEditor / ClusterProjectTypeYamlEditor
seeded with a valid ProjectTypeSpec default that includes the mandated
cell-namespace resource (${metadata.namespace}); registered in App.tsx.
- Scaffolder backend actions openchoreo:(cluster)projecttype-definition:create
that POST to the projecttype endpoints and immediately insert the entity into
the catalog; registered in the scaffolder module.
- Create-permission hooks use(Cluster)ProjectTypePermission, wired into
useKindCreateConfig so the catalog "Create Project Type" /
"Create Cluster Project Type" buttons appear and gate on the create permission.
- Export translate(Cluster)ProjectTypeToEntity from the catalog module for the
actions' immediate-insert path.
Signed-off-by: VajiraPrabuddhaka <vajiraprabuddhaka@gmail.com>
…latform Resources The two project-type wizard templates fell into the "Other Templates" catch-all on the create page because their spec.type values were not in PLATFORM_TYPES. Add ClusterProjectType / ProjectType to PLATFORM_TYPES (right after DeploymentPipeline, cluster-scoped before namespaced) so they render under Platform Resources, and gate the cards on the create permission via isTemplateDisabled, mirroring (Cluster)ResourceType. Signed-off-by: VajiraPrabuddhaka <vajiraprabuddhaka@gmail.com>
…port Signed-off-by: VajiraPrabuddhaka <vajiraprabuddhaka@gmail.com>
Add unit tests for the new ProjectType / ClusterProjectType functionality: - scaffolder backend actions (projectType, clusterProjectType) - ProjectTypeOverviewCard rendering and schema flattening - ProjectType / ClusterProjectType entity processors - ProjectType / ClusterProjectType YAML editor field extensions + validation - useProjectTypePermission / useClusterProjectTypePermission hooks - (Cluster)ProjectType permission definitions and authz action mapping - PlatformResourceService update/delete for (cluster)projecttypes Signed-off-by: VajiraPrabuddhaka <vajiraprabuddhaka@gmail.com>
2bbc7f3 to
aca9a7f
Compare
Purpose
OpenChoreo's project-release-lifecycle epic introduced two new platform-engineer abstractions in core —
ProjectType(namespaced) andClusterProjectType(cluster-scoped) — infrastructure templates that carry aparametersschema, anenvironmentConfigsschema, CELvalidations, and namespace-scopedresources(incl. the mandated cell namespace). AProjectnow references one via the new requiredspec.type.This PR brings these two kinds into Backstage end to end — catalog ingestion, entity pages, the Project→ProjectType relation, edit/delete permissions, and creation wizards — mirroring the existing
(Cluster)ResourceTypesupport so the experience is consistent.Approach
openchoreo-api.yamlto coremainand regenerate the TypeScript client (adds the(Cluster)ProjectTypetypes/endpoints andProject.spec.type).catalog-backend-module-openchoreo): newProjectType/ClusterProjectTypeentity kinds + translators; full-sync fetch of the namespaced and cluster endpoints; event-driven delta sync (openchoreo.projecttype/openchoreo.clusterprojecttype); relation processors (ProjectType→ DomainpartOf).Project.spec.typeasopenchoreo.io/project-type{,-kind}annotations and emitinstanceOf/hasInstancefromSystemEntityProcessor, exactly like Resource → ResourceType.openchoreo, app):ProjectTypeOverviewCard(parameters, environmentConfigs, resources, validations), Definition tab via the generic platform-resource endpoint, andEntityPage/ kind-registry / nav / graph wiring.openchoreo-common,openchoreo-react, policy): create/update/delete permissions + action mappings + catalog-visibility gating; the Definition tab edit/delete unlocks viauseResourceDefinitionPermission.scaffolder-backend-module-openchoreo, templates, app):create-openchoreo-(cluster)projecttypetemplates, YAML-editor field extensions seeded with a valid spec (incl. the mandated cell namespace), backend actions that POST + immediately insert into the catalog, and the catalog "Create …" buttons grouped under Platform Resources.Verified live against a local OpenChoreo (k3d): browsing, entity pages with relations, Definition-tab edit unlock, and template categorization. tsc + lint clean; unit tests added/updated across the catalog module, permission hook, platform-resource service, and ResourceDefinition utils.
Related Issues
Related openchoreo/openchoreo#3921
Screenshots
Project Overview

Catalog section
ClusterProjectType (ProjectType is also very similar)

ClusterProjectType crteation

Create from template section

Checklist
Summary by CodeRabbit
Release Notes
New Features
UI Enhancements