Skip to content

feat: add catalog support, entity pages, and creation wizards for ProjectType / ClusterProjectType#645

Merged
VajiraPrabuddhaka merged 10 commits into
openchoreo:mainfrom
VajiraPrabuddhaka:feat/projecttype-catalog-support
Jun 23, 2026
Merged

feat: add catalog support, entity pages, and creation wizards for ProjectType / ClusterProjectType#645
VajiraPrabuddhaka merged 10 commits into
openchoreo:mainfrom
VajiraPrabuddhaka:feat/projecttype-catalog-support

Conversation

@VajiraPrabuddhaka

@VajiraPrabuddhaka VajiraPrabuddhaka commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

Purpose

OpenChoreo's project-release-lifecycle epic introduced two new platform-engineer abstractions in core — ProjectType (namespaced) and ClusterProjectType (cluster-scoped) — infrastructure templates that carry a parameters schema, an environmentConfigs schema, CEL validations, and namespace-scoped resources (incl. the mandated cell namespace). A Project now references one via the new required spec.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)ResourceType support so the experience is consistent.

Approach

  • API client: re-sync openchoreo-api.yaml to core main and regenerate the TypeScript client (adds the (Cluster)ProjectType types/endpoints and Project.spec.type).
  • Catalog ingestion (catalog-backend-module-openchoreo): new ProjectType / ClusterProjectType entity kinds + translators; full-sync fetch of the namespaced and cluster endpoints; event-driven delta sync (openchoreo.projecttype / openchoreo.clusterprojecttype); relation processors (ProjectType → Domain partOf).
  • Project linkage: surface Project.spec.type as openchoreo.io/project-type{,-kind} annotations and emit instanceOf / hasInstance from SystemEntityProcessor, exactly like Resource → ResourceType.
  • Entity pages (openchoreo, app): ProjectTypeOverviewCard (parameters, environmentConfigs, resources, validations), Definition tab via the generic platform-resource endpoint, and EntityPage / kind-registry / nav / graph wiring.
  • Permissions (openchoreo-common, openchoreo-react, policy): create/update/delete permissions + action mappings + catalog-visibility gating; the Definition tab edit/delete unlocks via useResourceDefinitionPermission.
  • Creation wizards (scaffolder-backend-module-openchoreo, templates, app): create-openchoreo-(cluster)projecttype templates, 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
image

Catalog section

image

ClusterProjectType (ProjectType is also very similar)
image

image image

ClusterProjectType crteation
image

image

Create from template section
image

Checklist

  • Tests added or updated (unit, integration, etc.)
  • Samples updated (if applicable)

Summary by CodeRabbit

Release Notes

  • New Features

    • Added catalog support for ProjectType and ClusterProjectType, including dedicated overview pages, schema/validation views, Definition tab, and CRUD scaffolder wizards under “Platform Resources”
    • Wired Projects to link to their associated type(s) via instance relationships
    • Added backend ingestion, sync, and permission support for both resource kinds
  • UI Enhancements

    • Updated catalog icons, graph labels, and About card type links
    • Added YAML editor fields with inline validation for ProjectType and ClusterProjectType creation

@coderabbitai

coderabbitai Bot commented Jun 22, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Adds complete Backstage catalog support for OpenChoreo ProjectType (namespaced) and ClusterProjectType (cluster-scoped) resource definitions. The implementation spans OpenAPI contract updates, Backstage entity type definitions, catalog ingestion via processors and providers, backend platform resource handlers, permission framework integration, React permission hooks and UI components, scaffolder YAML editor extensions, scaffolder backend actions for resource creation, and template definitions for guided wizard workflows.

Changes

ProjectType & ClusterProjectType Catalog Support

Layer / File(s) Summary
OpenAPI spec, annotations, and permission definitions
packages/openchoreo-client-node/openapi/openchoreo-api.yaml, packages/openchoreo-client-node/openapi-config.json, plugins/openchoreo-common/src/constants.ts, plugins/openchoreo-common/src/permissions.ts, plugins/openchoreo-common/src/permissions.test.ts, plugins/openchoreo-common/src/index.ts
OpenAPI spec gains new ClusterProjectType and ProjectType CRUD endpoints, schema subresources, ProjectRelease/ProjectReleaseBinding endpoints, and extended ProjectSpec/ProjectStatus models with type references and latest-release tracking. CHOREO_ANNOTATIONS exports PROJECT_TYPE and PROJECT_TYPE_KIND. Defines six new CRUD permissions and wires them into openchoreoPermissions, OPENCHOREO_PERMISSION_TO_ACTION, OPENCHOREO_MANAGED_ENTITY_KINDS, and CATALOG_KIND_TO_ACTION for authorization.
Entity interfaces, translation functions, and module exports
plugins/catalog-backend-module-openchoreo/src/kinds/ClusterProjectTypeEntityV1alpha1.ts, plugins/catalog-backend-module-openchoreo/src/kinds/ProjectTypeEntityV1alpha1.ts, plugins/catalog-backend-module-openchoreo/src/kinds/index.ts, plugins/catalog-backend-module-openchoreo/src/utils/entityTranslation.ts, plugins/catalog-backend-module-openchoreo/src/utils/entityTranslation.test.ts, plugins/catalog-backend-module-openchoreo/src/index.ts
Defines ClusterProjectTypeEntityV1alpha1 and ProjectTypeEntityV1alpha1 Backstage entity interfaces with appropriate spec shapes. Adds legacy and new-API translation functions to convert OpenChoreo CR shapes into Backstage entities with managed-by and origin annotations. Extends translateProjectToEntity to stamp PROJECT_TYPE and PROJECT_TYPE_KIND annotations onto System entities. Exports all translators from module entrypoint.
Catalog processors, SystemEntityProcessor relations, and provider ingestion
plugins/catalog-backend-module-openchoreo/src/processors/ClusterProjectTypeEntityProcessor.ts, plugins/catalog-backend-module-openchoreo/src/processors/ProjectTypeEntityProcessor.ts, plugins/catalog-backend-module-openchoreo/src/processors/SystemEntityProcessor.ts, plugins/catalog-backend-module-openchoreo/src/processors/index.ts, plugins/catalog-backend-module-openchoreo/src/module.ts, plugins/catalog-backend-module-openchoreo/src/provider/EventDeltaApplier.ts, plugins/catalog-backend-module-openchoreo/src/provider/OpenChoreoEntityProvider.ts, plugins/catalog-backend-module-openchoreo/src/processors/processors.test.ts, plugins/catalog-backend-module-openchoreo/src/provider/EventDeltaApplier.test.ts
Adds ClusterProjectTypeEntityProcessor and ProjectTypeEntityProcessor for kind validation and pass-through processing. Refactors SystemEntityProcessor to emit RELATION_INSTANCE_OF/RELATION_HAS_INSTANCE relations between System entities and their referenced ProjectType/ClusterProjectType. Extends OpenChoreoEntityProvider with full-sync per-namespace steps for ProjectTypes and cluster-scoped steps for ClusterProjectTypes. Adds EventDeltaApplier fetch helpers and refresh handlers for webhook-driven incremental updates.
PlatformResourceService handlers, router kinds, and permission policy
plugins/openchoreo-backend/src/services/PlatformResourceService/PlatformResourceService.ts, plugins/openchoreo-backend/src/services/PlatformResourceService/PlatformResourceService.test.ts, plugins/openchoreo-backend/src/router.ts, plugins/permission-backend-module-openchoreo-policy/src/rules/matchesCatalogEntityCapability.ts
Registers projecttypes and clusterprojecttypes in ResourceKind union, NEW_API_KINDS routing set, and RESOURCE_KIND_TO_CRD_KIND mappings. Adds GET/PUT/DELETE switch cases handling namespace-scoped and cluster-scoped endpoint routing. Updates router CLUSTER_SCOPED_KINDS and VALID_PLATFORM_RESOURCE_KINDS union. Wires projecttype/clusterprojecttype into permission policy KIND_TO_ENTITY_LEVEL and CLUSTER_SCOPED_KINDS for capability path validation.
React permission hooks, kind utilities, graph labels, and icons
plugins/openchoreo-react/src/hooks/useProjectTypePermission.ts, plugins/openchoreo-react/src/hooks/useClusterProjectTypePermission.ts, plugins/openchoreo-react/src/hooks/useResourceDefinitionPermission.ts, plugins/openchoreo-react/src/utils/graphUtils.ts, plugins/openchoreo-react/src/index.ts, packages/app/src/utils/kindUtils.ts, packages/app/src/kindIcons.ts, plugins/openchoreo/src/api/OpenChoreoClientApi.ts
Adds useProjectTypePermission (organization-level) and useClusterProjectTypePermission (cluster-level) hooks wrapping permission checks. Extends useResourceDefinitionPermission with projecttype (resource-scoped) and clusterprojecttype (cluster-scoped) entries. Updates kindDisplayNames, kindCategories, allSearchFilterKinds, KIND_LABEL_PREFIXES, KIND_FULL_LABELS, KIND_ICONS, and CLUSTER_SCOPED_RESOURCE_KINDS for consistent catalog UI presentation.
ProjectTypeOverviewCard, entity page routing, AboutCard, and supporting utilities
plugins/openchoreo/src/components/ProjectTypeOverview/ProjectTypeOverviewCard.tsx, plugins/openchoreo/src/components/ProjectTypeOverview/index.ts, plugins/openchoreo/src/index.ts, packages/app/src/components/catalog/EntityPage.tsx, packages/app/src/components/catalog/OpenChoreoAboutCard.tsx, packages/app/src/components/catalog/EntityLayoutWithDelete.tsx, plugins/openchoreo/src/components/DeleteEntity/hooks/useEntityExistsCheck.ts, plugins/openchoreo/src/components/ResourceDefinition/utils.ts, plugins/openchoreo/src/components/ResourceDefinition/utils.test.ts, plugins/openchoreo/src/components/ProjectTypeOverview/ProjectTypeOverviewCard.test.tsx
Implements ProjectTypeOverviewCard with resource definition fetching, schema property extraction and flattening, section renderers for Parameters/EnvironmentConfigs/Resources/Validations, and cluster-scoped namespace computation. Adds projectTypePage and clusterProjectTypePage entity page layouts with overview, graph, about, and definition routes. Updates OpenChoreoAboutCard to render linked project-type references from System entity metadata annotations. Extends supporting kind lookup maps and resource definition utilities.
Scaffolder YAML editor field extensions and template list integration
packages/app/src/scaffolder/ProjectTypeYamlEditor/*, packages/app/src/scaffolder/ClusterProjectTypeYamlEditor/*, packages/app/src/components/scaffolder/OpenChoreoScaffolderPage.tsx, packages/app/src/components/scaffolder/CustomTemplateListPage.tsx, packages/app/src/components/catalog/useKindCreateConfig.ts
Implements ProjectTypeYamlEditorExtension and ClusterProjectTypeYamlEditorExtension with default YAML templates including required apiVersion/kind, metadata, and spec placeholders. Auto-generates initial YAML from form data while protecting user edits via ref tracking. Validates YAML on input change and surfaces parse errors inline. Registers both as Backstage scaffolder field extensions. Integrates into OpenChoreoScaffolderPage field extension list and CustomTemplateListPage with permission-gated disable logic. Updates useKindCreateConfig to route both kinds to their respective permission hooks.
Scaffolder backend actions, templates, and configuration
plugins/scaffolder-backend-module-openchoreo/src/actions/projectType.ts, plugins/scaffolder-backend-module-openchoreo/src/actions/clusterProjectType.ts, plugins/scaffolder-backend-module-openchoreo/src/actions/clusterProjectType.test.ts, plugins/scaffolder-backend-module-openchoreo/src/actions/projectType.test.ts, plugins/scaffolder-backend-module-openchoreo/src/module.ts, templates/create-openchoreo-projecttype/template.yaml, templates/create-openchoreo-clusterprojecttype/template.yaml, app-config.yaml, app-config.production.yaml, .changeset/projecttype-catalog-support.md
Adds createProjectTypeDefinitionAction and createClusterProjectTypeDefinitionAction backend action factories. Each parses and validates YAML input, reads configuration for OpenChoreo base URL and auth enablement, conditionally requires user token from secrets, POSTs to the appropriate endpoint, asserts API response, and immediately inserts the translated entity into Backstage catalog (logging insertion failures without failing the action). Registers both actions in the scaffolder module. Introduces Template YAML definitions with form decorators for user-token injection, parameter schemas for naming and YAML input, and scaffolder step wiring. Adds catalog location entries in both dev and production configs.

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
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~75 minutes

Possibly related PRs

  • openchoreo/backstage-plugins#485: Extends PlatformResourceService CRUD test coverage for projecttypes and clusterprojecttypes, directly testing the new handler implementations added in this PR.
  • openchoreo/backstage-plugins#609: Modifies CustomTemplateListPage.tsx to drive template card enable/disable behavior, intersecting with this PR's additions of projecttype/clusterprojecttype permission-gated scaffolder template controls.
  • openchoreo/backstage-plugins#621: Introduces underlying NFS/scaffolder page component changes on which this PR's YAML editor field extensions and OpenChoreoScaffolderPage.tsx wiring build.

Suggested reviewers

  • sameerajayasoma
  • stefinie123
  • kaviththiranga
  • Mirage20

Poem

🐰 A new kind hops into the catalog today,
ProjectType and ClusterProjectType, hip-hip-hooray!
With schemas and processors, permissions to display,
The scaffolder wizard makes creation full of cheer!
Relations are emitted, the graph grows near and far—
This rabbit's so proud of the features in this PR! ✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 71.43% 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 and specifically summarizes the main changes: adding Backstage catalog support, entity pages, and creation wizards for ProjectType and ClusterProjectType.
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.
Description check ✅ Passed The PR description includes all critical sections: Purpose, Goals/Approach, User stories (implicit in the feature scope), Release notes, and Screenshots. However, several optional sections from the template are missing.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

@github-actions

github-actions Bot commented Jun 22, 2026

Copy link
Copy Markdown

Changeset detected — the following file(s) will be released with this PR:

.changeset/projecttype-catalog-support.md

@VajiraPrabuddhaka VajiraPrabuddhaka force-pushed the feat/projecttype-catalog-support branch from 5bd6895 to eb1be4f Compare June 22, 2026 05:22
@VajiraPrabuddhaka VajiraPrabuddhaka force-pushed the feat/projecttype-catalog-support branch 2 times, most recently from 79742bf to 676c46d Compare June 22, 2026 09:34
@VajiraPrabuddhaka VajiraPrabuddhaka marked this pull request as ready for review June 22, 2026 10:14
@VajiraPrabuddhaka

Copy link
Copy Markdown
Contributor Author

@coderabbitai full-review

@coderabbitai

coderabbitai Bot commented Jun 22, 2026

Copy link
Copy Markdown

@VajiraPrabuddhaka Sure, I'll redo the entire review of the PR now!

✅ Action performed

Full review finished.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

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 | 🟠 Major

Resolve the Project.spec.type required/default contract.

Project still only requires metadata, and ProjectSpec has no required list, so generated clients will model spec.type as optional. That conflicts with the PR objective that Projects now have a required ProjectType linkage; the documented ClusterProjectType/default fallback is also prose-only, while the nested kind default is ProjectType. Either require spec.type in 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 win

Assert 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}). Add toHaveBeenCalledWith checks 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 win

Verify the exact permission object in the mocked call.

Please also assert that openchoreoProjectTypeCreatePermission is sent to usePermission; checking only resourceRef omission 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 win

Assert the permission constant in the hook call.

This test currently verifies only that resourceRef is omitted. It should also assert that openchoreoClusterProjectTypeCreatePermission is 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 | 🔵 Trivial

Wrap mock call assertions in waitFor for 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 win

ClusterProjectType relation test should assert the reverse edge too.

This case only verifies RELATION_INSTANCE_OF. Add RELATION_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

📥 Commits

Reviewing files that changed from the base of the PR and between 99d8175 and 676c46d.

⛔ Files ignored due to path filters (1)
  • packages/openchoreo-client-node/src/generated/openchoreo/types.ts is excluded by !**/generated/**
📒 Files selected for processing (69)
  • .changeset/projecttype-catalog-support.md
  • app-config.production.yaml
  • app-config.yaml
  • packages/app/src/components/catalog/EntityLayoutWithDelete.tsx
  • packages/app/src/components/catalog/EntityPage.tsx
  • packages/app/src/components/catalog/OpenChoreoAboutCard.tsx
  • packages/app/src/components/catalog/useKindCreateConfig.ts
  • packages/app/src/components/scaffolder/CustomTemplateListPage.tsx
  • packages/app/src/components/scaffolder/OpenChoreoScaffolderPage.tsx
  • packages/app/src/kindIcons.ts
  • packages/app/src/scaffolder/ClusterProjectTypeYamlEditor/ClusterProjectTypeYamlEditorExtension.test.tsx
  • packages/app/src/scaffolder/ClusterProjectTypeYamlEditor/ClusterProjectTypeYamlEditorExtension.tsx
  • packages/app/src/scaffolder/ClusterProjectTypeYamlEditor/extensions.ts
  • packages/app/src/scaffolder/ClusterProjectTypeYamlEditor/index.ts
  • packages/app/src/scaffolder/ClusterProjectTypeYamlEditor/styles.ts
  • packages/app/src/scaffolder/ProjectTypeYamlEditor/ProjectTypeYamlEditorExtension.test.tsx
  • packages/app/src/scaffolder/ProjectTypeYamlEditor/ProjectTypeYamlEditorExtension.tsx
  • packages/app/src/scaffolder/ProjectTypeYamlEditor/extensions.ts
  • packages/app/src/scaffolder/ProjectTypeYamlEditor/index.ts
  • packages/app/src/scaffolder/ProjectTypeYamlEditor/styles.ts
  • packages/app/src/utils/kindUtils.ts
  • packages/openchoreo-client-node/openapi-config.json
  • packages/openchoreo-client-node/openapi/openchoreo-api.yaml
  • plugins/catalog-backend-module-openchoreo/src/index.ts
  • plugins/catalog-backend-module-openchoreo/src/kinds/ClusterProjectTypeEntityV1alpha1.ts
  • plugins/catalog-backend-module-openchoreo/src/kinds/ProjectTypeEntityV1alpha1.ts
  • plugins/catalog-backend-module-openchoreo/src/kinds/index.ts
  • plugins/catalog-backend-module-openchoreo/src/module.ts
  • plugins/catalog-backend-module-openchoreo/src/processors/ClusterProjectTypeEntityProcessor.ts
  • plugins/catalog-backend-module-openchoreo/src/processors/ProjectTypeEntityProcessor.ts
  • plugins/catalog-backend-module-openchoreo/src/processors/SystemEntityProcessor.ts
  • plugins/catalog-backend-module-openchoreo/src/processors/index.ts
  • plugins/catalog-backend-module-openchoreo/src/processors/processors.test.ts
  • plugins/catalog-backend-module-openchoreo/src/provider/EventDeltaApplier.test.ts
  • plugins/catalog-backend-module-openchoreo/src/provider/EventDeltaApplier.ts
  • plugins/catalog-backend-module-openchoreo/src/provider/OpenChoreoEntityProvider.ts
  • plugins/catalog-backend-module-openchoreo/src/utils/entityTranslation.test.ts
  • plugins/catalog-backend-module-openchoreo/src/utils/entityTranslation.ts
  • plugins/openchoreo-backend/src/router.ts
  • plugins/openchoreo-backend/src/services/PlatformResourceService/PlatformResourceService.test.ts
  • plugins/openchoreo-backend/src/services/PlatformResourceService/PlatformResourceService.ts
  • plugins/openchoreo-common/src/constants.ts
  • plugins/openchoreo-common/src/index.ts
  • plugins/openchoreo-common/src/permissions.test.ts
  • plugins/openchoreo-common/src/permissions.ts
  • plugins/openchoreo-react/src/hooks/useClusterProjectTypePermission.test.ts
  • plugins/openchoreo-react/src/hooks/useClusterProjectTypePermission.ts
  • plugins/openchoreo-react/src/hooks/useProjectTypePermission.test.ts
  • plugins/openchoreo-react/src/hooks/useProjectTypePermission.ts
  • plugins/openchoreo-react/src/hooks/useResourceDefinitionPermission.test.ts
  • plugins/openchoreo-react/src/hooks/useResourceDefinitionPermission.ts
  • plugins/openchoreo-react/src/index.ts
  • plugins/openchoreo-react/src/utils/graphUtils.ts
  • plugins/openchoreo/src/api/OpenChoreoClientApi.ts
  • plugins/openchoreo/src/components/DeleteEntity/hooks/useEntityExistsCheck.ts
  • plugins/openchoreo/src/components/ProjectTypeOverview/ProjectTypeOverviewCard.test.tsx
  • plugins/openchoreo/src/components/ProjectTypeOverview/ProjectTypeOverviewCard.tsx
  • plugins/openchoreo/src/components/ProjectTypeOverview/index.ts
  • plugins/openchoreo/src/components/ResourceDefinition/utils.test.ts
  • plugins/openchoreo/src/components/ResourceDefinition/utils.ts
  • plugins/openchoreo/src/index.ts
  • plugins/permission-backend-module-openchoreo-policy/src/rules/matchesCatalogEntityCapability.ts
  • plugins/scaffolder-backend-module-openchoreo/src/actions/clusterProjectType.test.ts
  • plugins/scaffolder-backend-module-openchoreo/src/actions/clusterProjectType.ts
  • plugins/scaffolder-backend-module-openchoreo/src/actions/projectType.test.ts
  • plugins/scaffolder-backend-module-openchoreo/src/actions/projectType.ts
  • plugins/scaffolder-backend-module-openchoreo/src/module.ts
  • templates/create-openchoreo-clusterprojecttype/template.yaml
  • templates/create-openchoreo-projecttype/template.yaml

Comment thread packages/openchoreo-client-node/openapi/openchoreo-api.yaml
Comment thread packages/openchoreo-client-node/openapi/openchoreo-api.yaml
Comment thread plugins/openchoreo/src/components/ProjectTypeOverview/ProjectTypeOverviewCard.tsx Outdated
Comment thread plugins/scaffolder-backend-module-openchoreo/src/actions/clusterProjectType.ts Outdated
@VajiraPrabuddhaka VajiraPrabuddhaka force-pushed the feat/projecttype-catalog-support branch from 676c46d to e000a6c Compare June 22, 2026 17:03
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>
@VajiraPrabuddhaka VajiraPrabuddhaka force-pushed the feat/projecttype-catalog-support branch from e000a6c to 2bbc7f3 Compare June 22, 2026 17:12
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>
@VajiraPrabuddhaka VajiraPrabuddhaka force-pushed the feat/projecttype-catalog-support branch from 2bbc7f3 to aca9a7f Compare June 22, 2026 17:22
@VajiraPrabuddhaka VajiraPrabuddhaka merged commit 2f45e83 into openchoreo:main Jun 23, 2026
9 checks passed
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.

3 participants