Skip to content

Comments

feat: auto-generate Edit Config page from Site CRD (#39)#79

Open
ian-flores wants to merge 11 commits intomainfrom
auto-generate-config-from-crd
Open

feat: auto-generate Edit Config page from Site CRD (#39)#79
ian-flores wants to merge 11 commits intomainfrom
auto-generate-config-from-crd

Conversation

@ian-flores
Copy link
Collaborator

Summary

Changes

  • Added CRDConfigPage that uses Go reflection to parse and render the Site CRD spec
  • Dynamically renders configuration fields based on the CRD structure
  • Organizes fields into logical sections: Basic Configuration, Product Configuration, and Advanced Configuration
  • Skips zero values and internal Kubernetes fields for cleaner display
  • Added comprehensive tests for the CRD config rendering

Testing

  • Added unit tests in flightdeck/html/crdconfig_test.go
  • Tests verify proper rendering of fields and categorization
  • Tests confirm zero values are correctly omitted

Benefits

  • Configuration page automatically adapts when Site CRD changes
  • No need to manually update UI code when adding/removing CRD fields
  • Consistent display of all CRD fields without manual maintenance
  • Better organization of configuration into logical sections

Fixes #39

- Add isCRDPresent() helper to check if CRDs exist before setting up controllers
- Conditionally setup Site and Flightdeck controllers only when CRDs exist
- Update flightdeck kube client to return empty Site when CRD doesn't exist
- Make Ready endpoint treat missing CRDs as non-fatal
- Add tests for no-CRD scenarios

Fixes #38
- Add CRDConfigPage that uses Go reflection to parse Site CRD spec
- Dynamically render configuration fields from CRD structure
- Organize fields into sections (Basic, Product, Advanced)
- Skip zero values and internal fields for cleaner display
- Add tests for CRD config rendering
- Replace hard-coded SiteConfigPage with dynamic CRDConfigPage

This allows the configuration page to automatically adapt when the Site CRD changes, eliminating the need to manually update the UI code.
@claude
Copy link

claude bot commented Feb 9, 2026

Claude finished @ian-flores's task —— View job


Reviewing PR

  • Read review guidelines
  • Analyze changed files
  • Create pending review
  • Add inline comments
  • Submit review

Review submitted with feedback on error handling, field categorization, and minor code improvements.

Copy link

@claude claude bot left a comment

Choose a reason for hiding this comment

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

Code Review

Nice implementation of auto-generated config from the Site CRD. The reflection-based approach is a good solution for keeping the UI in sync with CRD changes. Here's my feedback:

Important

flightdeck/internal/kube.go:119 - Error string matching is brittle

if strings.Contains(errStr, "the server could not find the requested resource") ||
    strings.Contains(errStr, "no matches for kind") {

These strings may change across Kubernetes versions. Consider using k8s.io/apimachinery/pkg/api/errors functions like errors.IsNotFound() or checking for specific API error types instead.

flightdeck/html/crdconfig.go:349-354 - Hardcoded field categorization
The productNames and advancedNames lists are hardcoded, which partially defeats the purpose of auto-generating from the CRD. When new fields are added, someone needs to remember to update these lists. Consider:

  1. Documenting this limitation
  2. Using struct tags in the CRD to annotate category
  3. Defaulting unknown fields to a sensible category

Suggestions

flightdeck/html/crdconfig.go:366-371 - No-op ReplaceAll calls

name = strings.ReplaceAll(name, "AWS", "AWS")
name = strings.ReplaceAll(name, "VPC", "VPC")

These are no-ops. If the intent is to preserve acronyms, this approach doesn't accomplish that since the code below still processes them character-by-character.

flightdeck/html/crdconfig.go:10-11 - Dot imports
Using dot imports makes it unclear where Node, Text, Class, Div, etc. come from. Consider using named imports unless dot imports are an established pattern in this codebase.

flightdeck/html/crdconfig.go:131 - Nested append

allFields := append(append(basicFields, productFields...), advancedFields...)

This works but could be clearer with explicit allocation or slices.Concat.

cmd/team-operator/main.go:168-172 - Log level for missing CRDs
The "Site CRD not found" message is at Info level. Consider Warn level so operators are more aware the controller isn't running.

flightdeck/internal/kube_test.go:68 - Incomplete happy path test
The "Site found - returns site" test case doesn't properly mock a successful response, so it doesn't actually verify the happy path.

flightdeck/html/crdconfig.go:400 & crdconfig_test.go:139 & kube_test.go:109 - Missing newlines at end of files.

Overall

The approach is sound and achieves the goal of reducing manual UI maintenance when the CRD changes. The tests cover the core functionality well. The main areas for improvement are around error handling robustness and the partially-hardcoded field categorization.

- Use apierrors.IsNotFound() instead of brittle string matching
- Remove no-op ReplaceAll calls in formatFieldName
- Use slices.Concat instead of nested append
- Document hardcoded field categorization lists
- Change missing CRD log level from Info to Warn
- Update tests to use real k8s API error types
- Add max-w-7xl layout wrapper matching homepage
- Render products as card sections instead of nested tables
- Use Posit design tokens for borders and backgrounds
- Switch to bottom-only borders for cleaner table appearance
- Render nested structs as indented sections, not subtables
apiextensionsv1.JSON fields (e.g., userSettings, vsCodeUserSettings)
were rendering as raw byte arrays. Add formatValue helper that
detects structs with Raw []byte fields and decodes them to strings.
- Pointer fields like *int now show their value instead of memory address
- Map values containing structs are recursively expanded instead of
  printing Go struct literals like {default 1 2560 0}
- Add deref helper for consistent pointer dereferencing
- Handle pointer fields in renderNestedStruct
Map values like userSettings contain apiextensionsv1.JSON structs
which were being recursively expanded, showing Raw byte arrays as
individual numbers. Now checks formatValue first to decode them.
@ian-flores
Copy link
Collaborator Author

Confirmed properly rendering in ganso01-staging and then reverted back to main.

Screenshot 2026-02-10 at 1 22 52 PM

@ian-flores ian-flores marked this pull request as ready for review February 10, 2026 21:25
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.

flightdeck should consume the SiteSpec Resource Definition and Auto-Generate the Edit-Config page

1 participant