Skip to content

feat: Project creation wizard driven by ProjectType / ClusterProjectType#653

Open
VajiraPrabuddhaka wants to merge 5 commits into
openchoreo:mainfrom
VajiraPrabuddhaka:feat/project-creation-ux-per-projecttype
Open

feat: Project creation wizard driven by ProjectType / ClusterProjectType#653
VajiraPrabuddhaka wants to merge 5 commits into
openchoreo:mainfrom
VajiraPrabuddhaka:feat/project-creation-ux-per-projecttype

Conversation

@VajiraPrabuddhaka

@VajiraPrabuddhaka VajiraPrabuddhaka commented Jun 23, 2026

Copy link
Copy Markdown
Contributor

Purpose

OpenChoreo's project-release-lifecycle epic (openchoreo/openchoreo#3564) made Project.spec.type (a ProjectTypeRef) and Project.spec.parameters first-class: a Project is now an instance of a ProjectType / ClusterProjectType, whose parameters schema configures it. The catalog already ingests both kinds and links Projects to their type (#645), but Project creation was untouched it was a single static create-openchoreo-project template with a fixed field set and no type/parameters.

This PR introduces the Project creation wizard starting from the template selection, and then metadata collection and Parameters collection and finally the creation.

Approach

  • Scaffolder action (openchoreo:project:create): accept optional typeKind / typeName / parameters; set spec.type + spec.parameters on the create request (preserving deploymentPipelineRef); thread the type into the immediate-catalog insert so the instanceOf → ProjectType relation appears at once. Back-compatible — when omitted, the API applies its default.
  • Catalog backend: new PtdToTemplateConverter generates one template-project-<name> scaffolder Template per (Cluster)ProjectType (annotation ptd-generated, spec.type: Project), with a Project Metadata section (namespace + project name + deployment pipeline) and a schema-driven Details section bound to the type's spec.parameters.openAPIV3Schema. The provider emits these on full sync and the EventDeltaApplier emits/removes them on projecttype/clusterprojecttype events. The list endpoint returns the parameters schema inline, so no extra /schema fetch is required.
  • Frontend (packages/app): a ProjectParametersField RJSF field extension; a ?view=projects browse view in CustomTemplateListPage with a "Project" landing nav-card and namespace scope picker; useKindCreateConfig routes the Projects catalog "Create Project" button to ?view=projects; a ProjectReview section in CustomReviewStep. The static create-openchoreo-project template and its app-config Locations are removed; the Namespace card's create action is repointed to ?view=projects.

Verified end-to-end on a live k3d cluster: created projects from rich-parameter, nested-object, namespaced, and no-parameter project types; spec.type (correct kind) and spec.parameters round-trip onto the Project CR.

Related Issues

Related openchoreo/openchoreo#3921

Checklist

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

Quick Demo

Screen.Recording.2026-06-23.at.18.24.53.mov

Summary by CodeRabbit

  • New Features

    • Project type-specific creation wizards that customize parameters based on project type definitions
    • New "Projects" browse view for discovering and launching project type-specific creation flows
    • Parameter schemas dynamically generated from project type specifications, enabling tailored workflows
  • Updates

    • Project creation now uses dynamically-generated templates derived from project type configurations instead of a static template

@github-actions

github-actions Bot commented Jun 23, 2026

Copy link
Copy Markdown

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

.changeset/project-creation-wizard.md

@coderabbitai

coderabbitai Bot commented Jun 23, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@VajiraPrabuddhaka, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 46 minutes and 38 seconds. Learn how PR review limits work.

Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable the review add-on in the billing tab to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file).

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based credits.

🚦 How do rate limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan refill rate.

For paid Pro and Pro+ PR reviews, CodeRabbit uses rolling per-developer review limits. Reviews become available again as older review attempts age out of the rolling limit window.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 0aab8853-4467-40b6-9c98-0bdf7aef145b

📥 Commits

Reviewing files that changed from the base of the PR and between 2f45e83 and ae5818c.

📒 Files selected for processing (24)
  • .changeset/project-creation-wizard.md
  • app-config.production.yaml
  • app-config.yaml
  • packages/app/src/components/catalog/useKindCreateConfig.ts
  • packages/app/src/components/scaffolder/CustomTemplateListPage.tsx
  • packages/app/src/components/scaffolder/OpenChoreoScaffolderPage.tsx
  • packages/app/src/scaffolder/CustomReviewState/CustomReviewStep.test.tsx
  • packages/app/src/scaffolder/CustomReviewState/CustomReviewStep.tsx
  • packages/app/src/scaffolder/ProjectParametersField/ProjectParametersField.test.tsx
  • packages/app/src/scaffolder/ProjectParametersField/ProjectParametersField.tsx
  • packages/app/src/scaffolder/ProjectParametersField/extensions.ts
  • packages/app/src/scaffolder/ProjectParametersField/index.ts
  • plugins/catalog-backend-module-openchoreo/src/converters/PtdToTemplateConverter.cluster.test.ts
  • plugins/catalog-backend-module-openchoreo/src/converters/PtdToTemplateConverter.test.ts
  • plugins/catalog-backend-module-openchoreo/src/converters/PtdToTemplateConverter.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.test.ts
  • plugins/catalog-backend-module-openchoreo/src/provider/OpenChoreoEntityProvider.ts
  • plugins/openchoreo-common/src/constants.ts
  • plugins/openchoreo/src/components/Namespaces/NamespaceProjectsCard/NamespaceProjectsCard.tsx
  • plugins/scaffolder-backend-module-openchoreo/src/actions/project.test.ts
  • plugins/scaffolder-backend-module-openchoreo/src/actions/project.ts
  • templates/create-openchoreo-project/template.yaml
📝 Walkthrough

Walkthrough

Introduces a per-ProjectType "Create Project" wizard: PtdToTemplateConverter generates Backstage scaffolder Template entities from ProjectType/ClusterProjectType CRDs, surfaced under a new ?view=projects browse view in CustomTemplateListPage. A new ProjectParametersField renders type-specific schemas. The openchoreo:project:create action gains typeKind, typeName, and parameters inputs. The static create-openchoreo-project template and its catalog registrations are removed.

Changes

Per-ProjectType Create Project Wizard

Layer / File(s) Summary
PtdToTemplateConverter types and conversion logic
plugins/openchoreo-common/src/constants.ts, plugins/catalog-backend-module-openchoreo/src/converters/PtdToTemplateConverter.ts, plugins/catalog-backend-module-openchoreo/src/converters/PtdToTemplateConverter.test.ts, plugins/catalog-backend-module-openchoreo/src/converters/PtdToTemplateConverter.cluster.test.ts
Adds PTD_NAME, PTD_DISPLAY_NAME, PTD_GENERATED, PTD_KIND to CHOREO_ANNOTATIONS. Implements PtdToTemplateConverter with convertPtdToTemplateEntity/convertClusterPtdToTemplateEntity entrypoints, buildTemplate, generateParameters (two-section schema), and generateSteps wiring openchoreo:project:create. Full test coverage for both scopes.
OpenChoreoEntityProvider and EventDeltaApplier PTD wiring
plugins/catalog-backend-module-openchoreo/src/provider/OpenChoreoEntityProvider.ts, plugins/catalog-backend-module-openchoreo/src/provider/OpenChoreoEntityProvider.test.ts, plugins/catalog-backend-module-openchoreo/src/provider/EventDeltaApplier.ts, plugins/catalog-backend-module-openchoreo/src/provider/EventDeltaApplier.test.ts
OpenChoreoEntityProvider initializes ptdConverter, adds toProjectTypeCRD/stampManagedByLocation helpers, and generates Template entities during full sync for both scoped ProjectTypes. EventDeltaApplier gains ptdConverter, builder helpers, and updated refreshProjectType/refreshClusterProjectType to upsert/remove derived Templates alongside their ProjectType entities on delta events.
ProjectParametersField scaffolder field extension
packages/app/src/scaffolder/ProjectParametersField/ProjectParametersField.tsx, packages/app/src/scaffolder/ProjectParametersField/extensions.ts, packages/app/src/scaffolder/ProjectParametersField/index.ts, packages/app/src/scaffolder/ProjectParametersField/ProjectParametersField.test.tsx, packages/app/src/components/scaffolder/OpenChoreoScaffolderPage.tsx
New ProjectParametersField wraps RjsfForm reading ptdSchema from uiSchema['ui:options'], with empty-state handling when no properties exist. Exported as ProjectParametersFieldExtension and registered in OpenChoreoScaffolderPage's ScaffolderFieldExtensions.
openchoreo:project:create action extension
plugins/scaffolder-backend-module-openchoreo/src/actions/project.ts, plugins/scaffolder-backend-module-openchoreo/src/actions/project.test.ts
Adds optional typeKind (enum), typeName, and parameters to the action input schema. Refactors handler to conditionally include spec.type and spec.parameters in the POST body and passes type info to translateProjectToEntity. Legacy callers omitting these fields continue to work.
CustomTemplateListPage projects view
packages/app/src/components/scaffolder/CustomTemplateListPage.tsx, packages/app/src/components/catalog/useKindCreateConfig.ts, plugins/openchoreo/src/components/Namespaces/NamespaceProjectsCard/NamespaceProjectsCard.tsx
Adds isProjectsView (view=projects), projectGroups filtered by PTD_GENERATED/spec.type=Project, navigateToProjectsView, a Project landing card, ProjectTemplateCard, and renderProjectsView(). Updates APPLICATION_TYPES/KNOWN_CARD_TYPES, namespace picker conditions, and the main view switch. Updates useKindCreateConfig system createPath and NamespaceProjectsCard onClick to use the new route.
CustomReviewStep project review
packages/app/src/scaffolder/CustomReviewState/CustomReviewStep.tsx, packages/app/src/scaffolder/CustomReviewState/CustomReviewStep.test.tsx
Adds ProjectReview component rendering "Project Metadata" and "Parameters" tables. Extends detectTemplateType to return 'project' when project_name is present. Wires CustomReviewStep to render ProjectReview for the new type.
Static template removal and config cleanup
templates/create-openchoreo-project/template.yaml, app-config.yaml, app-config.production.yaml, .changeset/project-creation-wizard.md
Removes the static create-openchoreo-project template file, its catalog.locations entries in both config files (replaced with comments), and adds the changeset entry.

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant CustomTemplateListPage
  participant OpenChoreoEntityProvider
  participant PtdToTemplateConverter
  participant EventDeltaApplier
  participant CatalogService
  participant ScaffolderBackend

  rect rgba(70, 130, 180, 0.5)
    note over OpenChoreoEntityProvider,CatalogService: Full Sync / Delta Event
    OpenChoreoEntityProvider->>PtdToTemplateConverter: convertPtdToTemplateEntity(crd, namespace)
    PtdToTemplateConverter-->>OpenChoreoEntityProvider: Template entity (openchoreo:project:create step)
    OpenChoreoEntityProvider->>OpenChoreoEntityProvider: stampManagedByLocation(template)
    OpenChoreoEntityProvider->>CatalogService: upsert ProjectType + Template entities
    EventDeltaApplier->>PtdToTemplateConverter: buildProjectTypeTemplateEntity(delta event)
    PtdToTemplateConverter-->>EventDeltaApplier: Template entity
    EventDeltaApplier->>CatalogService: upsert/remove ProjectType + Template on event
  end

  rect rgba(60, 179, 113, 0.5)
    note over User,ScaffolderBackend: User Creates a Project
    User->>CustomTemplateListPage: navigates to ?view=projects
    CustomTemplateListPage->>CustomTemplateListPage: filter projectGroups by PTD_GENERATED + spec.type=Project
    CustomTemplateListPage-->>User: renders ProjectTemplateCard list
    User->>CustomTemplateListPage: selects a project type template
    CustomTemplateListPage->>ScaffolderBackend: open wizard (ProjectParametersField renders ptdSchema)
    User->>ScaffolderBackend: submits form
    ScaffolderBackend->>ScaffolderBackend: openchoreo:project:create(typeKind, typeName, parameters)
    ScaffolderBackend-->>User: created project entity ref link
  end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

  • openchoreo/backstage-plugins#614: Modifies the same createProjectAction in plugins/scaffolder-backend-module-openchoreo/src/actions/project.ts, with overlapping changes to input schema and request body construction.
  • openchoreo/backstage-plugins#621: Touches the same OpenChoreoScaffolderPage.tsx where this PR adds ProjectParametersFieldExtension to the ScaffolderFieldExtensions set.
  • openchoreo/backstage-plugins#645: Extends the same EventDeltaApplier.ts logic for ProjectType/ClusterProjectType reconciliation that this PR also modifies to add PTD-derived Template generation.

Suggested reviewers

  • sameerajayasoma
  • stefinie123
  • Mirage20
  • kaviththiranga

Poem

🐇 A hop through the catalog, templates anew,
No static YAML — the wizard's live too!
Per-ProjectType cards bloom in the browse,
ptdSchema fields render, the form takes a bow.
EventDeltaApplier stamps each new tree,
The rabbit declares: dynamic is free! 🌿

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 57.14% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Description check ❓ Inconclusive The PR description is comprehensive, covering Purpose, Approach, and Related Issues. However, several template sections (Goals, User stories, Release note, Documentation, Training, Certification, Marketing, Automation tests, Security checks, Samples, Migrations, Test environment, and Learning) are missing or incomplete. Expand the description to include Goals, User stories, Release note, Documentation, and at least a summary of test coverage and security verification. Consider whether other sections (Training, Certification, Marketing, Migrations) apply to this PR.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately and concisely summarizes the main change: introducing a project creation wizard driven by ProjectType and ClusterProjectType, which is the central feature of this PR.
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.

✏️ 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.

Extend the openchoreo:project:create action with optional typeKind /
typeName / parameters inputs so a Project can be created as an instance of
a (Cluster)ProjectType, mirroring openchoreo:resource:create. When provided,
spec.type and spec.parameters are set on the create request (deploymentPipelineRef
is preserved); when omitted, the request is unchanged and the OpenChoreo API
applies its {ClusterProjectType, default} default, keeping the legacy path working.

The immediate-catalog insert now threads projectTypeName / projectTypeKind into
translateProjectToEntity so the instanceOf -> ProjectType relation appears
immediately instead of after the next sync.

Signed-off-by: VajiraPrabuddhaka <vajiraprabuddhaka@gmail.com>
Mirror the ResourceType -> Template path for ProjectTypes so each
(Cluster)ProjectType produces a per-type Project-creation wizard. Adds
PtdToTemplateConverter (template-project-<name>, spec.type: Project, PTD_*
annotations) with a Project Metadata section (namespace + project name +
deployment pipeline) and a schema-driven Details section bound to the type's
spec.parameters.openAPIV3Schema via the ProjectParametersField. The generated
template wires openchoreo:project:create with the type's kind/name.

The OpenChoreoEntityProvider emits these templates during full sync for both
namespaced ProjectTypes and cluster-scoped ClusterProjectTypes, and the
EventDeltaApplier emits/removes them on projecttype/clusterprojecttype events.
Unlike the Resource family, the (Cluster)ProjectType list returns the full
parameters schema inline, so no extra /schema fetch is needed.

Adds PTD_* annotation constants and unit tests for the converter (namespaced +
cluster) and the event delta paths.

Signed-off-by: VajiraPrabuddhaka <vajiraprabuddhaka@gmail.com>
Wire the frontend so "Create Project" mirrors "Create Resource":

- ProjectParametersField scaffolder field extension (thin RJSF wrapper over
  the type's ptdSchema), registered in OpenChoreoScaffolderPage.
- CustomTemplateListPage gains a ?view=projects browse view listing the
  PTD_GENERATED per-type templates, a "Project" landing nav-card, and the
  namespace scope picker; 'Project' is treated as a meta-card type.
- useKindCreateConfig routes the Projects catalog (kind=system) "Create
  Project" button to ?view=projects instead of the static template.
- CustomReviewStep gets a ProjectReview section and a 'project' branch in
  detectTemplateType (keyed on the top-level project_name field).
- Remove the static create-openchoreo-project template and its app-config /
  app-config.production Locations; repoint the Namespace card's
  "Create a new project" action to ?view=projects.

Signed-off-by: VajiraPrabuddhaka <vajiraprabuddhaka@gmail.com>
@VajiraPrabuddhaka VajiraPrabuddhaka force-pushed the feat/project-creation-ux-per-projecttype branch from 5ba7779 to 0f2eca7 Compare June 23, 2026 10:04
@codecov

codecov Bot commented Jun 23, 2026

Copy link
Copy Markdown

- EventDeltaApplier: assert projecttype/clusterprojecttype events upsert
  both the type entity and its generated template-project-<name> Template
- OpenChoreoEntityProvider: full-sync now fixtures ProjectType /
  ClusterProjectType and asserts the per-type project templates are emitted
- ProjectParametersField: cover schema-driven render, formData seeding,
  onChange propagation, and the no-parameters empty-state
- CustomReviewStep: cover the ProjectReview section and the 'project'
  detectTemplateType branch (metadata + flattened parameters)

Signed-off-by: VajiraPrabuddhaka <vajiraprabuddhaka@gmail.com>
Signed-off-by: VajiraPrabuddhaka <vajiraprabuddhaka@gmail.com>
@VajiraPrabuddhaka

Copy link
Copy Markdown
Contributor Author

@coderabbitai full-review

@coderabbitai

coderabbitai Bot commented Jun 23, 2026

Copy link
Copy Markdown

@VajiraPrabuddhaka Sure, I'll redo the full review of this PR now.

✅ Action performed

Full review finished.

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.

1 participant