Skip to content

[FEAT] Web UI Base#4

Merged
bbengfort merged 1 commit intomainfrom
webui
Apr 1, 2026
Merged

[FEAT] Web UI Base#4
bbengfort merged 1 commit intomainfrom
webui

Conversation

@bbengfort
Copy link
Copy Markdown
Contributor

@bbengfort bbengfort commented Apr 1, 2026

Scope of changes

Implements a web user interface for the status service.

Estimated PR Size:

  • Tiny
  • Small
  • Medium
  • Large
  • Huge

Acceptance criteria

This PR will be merged without review.

Author checklist

  • I have manually tested the change and/or added automation in the form of unit tests or integration tests
  • I have updated the dependencies list
  • I have added new test fixtures as needed to support added tests
  • I have added or updated the documentation
  • I have run go generate to update generated code

Note

Medium Risk
Introduces new HTTP routes and a custom Gin HTML renderer backed by embedded assets, which could affect request routing and error-page rendering if templates or paths are misconfigured.

Overview
Adds a foundational web UI: the server now initializes a custom Gin HTMLRender, serves embedded static assets at /static, and exposes an unauthenticated / route (Index) that renders pages/index.html.

Introduces a new pkg/web package that embeds static/ and templates/, builds page/partial templates with shared includes, and provides common template helpers (e.g., static, titlecase, datetime) with unit tests.

Updates server error handlers to use the new template paths (errors/404.html, errors/405.html, errors/500.html) and extends scene.Scene with ForPage to tag the current page in template context.

Written by Cursor Bugbot for commit f61377e. Configure here.

@bbengfort bbengfort merged commit 3687321 into main Apr 1, 2026
4 of 5 checks passed
@bbengfort bbengfort deleted the webui branch April 1, 2026 23:24
Copy link
Copy Markdown

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 3 potential issues.

Fix All in Cursor

Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

)

func (s *Server) Index(c *gin.Context) {
Span(c, "ui.index")
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Span return values discarded, trace never completed

Medium Severity

The Span function returns (context.Context, trace.Span) but in Index, both return values are discarded. The existing usage in status.go captures the span and calls defer span.End(). Without ending the span, the OpenTelemetry trace is never completed or exported, causing observability data loss for the index page.

Fix in Cursor Fix in Web


func static(path string) string {
return filepath.Join("/static", path)
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Using filepath.Join for URL paths is incorrect

Low Severity

The static template function uses filepath.Join to construct URL paths, but filepath.Join uses OS-specific separators. On Windows, this produces backslash-separated paths (e.g., \static\favicon.ico) in HTML output, which browsers cannot resolve. The path.Join from the path package always uses forward slashes and is correct for URL construction.

Fix in Cursor Fix in Web

// Any file matching one of these patterns will be a partial template and will be
// available to render as a template but with no includes or other template files.
partials = []string{"partials/*.html", "partials/*/*.html"}
)
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Missing maintenance template causes nil panic

High Severity

The new template rendering system is wired up in setupRoutes, but the embedded templates/errors/ directory only contains 404.html, 405.html, and 500.html. The pre-existing Maintenance() handler references "errors/maintenance/index.html", which doesn't exist. When maintenance mode is active and an HTML response is negotiated, r.templates["errors/maintenance/index.html"] returns nil, and gin will panic with a nil pointer dereference trying to execute the template.

Additional Locations (1)
Fix in Cursor Fix in Web

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