Feat default surface routing + fix startup hang (#4)
Some checks failed
CI/CD / detect-changes (pull_request) Successful in 4s
CI/CD / test-frontend (pull_request) Successful in 4s
CI/CD / test-go-pg (pull_request) Failing after 2m18s
CI/CD / test-sqlite (pull_request) Successful in 2m40s
CI/CD / build-and-deploy (pull_request) Has been skipped

Default surface routing (v0.2.1):
- `/` redirects to configurable default surface with fallback chain:
  configured → first enabled extension surface → /admin
- Auto-sets default_surface on first extension surface install
- Admin settings UI: Default Surface dropdown
- disabledRedirect() and extension surface disabled redirect now go to
  /admin instead of / to prevent redirect loops

Fix Gin route param conflict causing backend startup hang:
- Team package settings routes used `:pkgId` while sibling routes used
  `:id` — Gin's radix tree entered infinite loop on conflicting param
  names. Unified to `:id`.

Docker entrypoint hardening:
- Health check timeout 10s → 60s
- Stale backend process cleanup on restart
- Crash detection (exit early if backend dies)

Roadmap direction updates:
- v0.3.0: Notes surface (Obsidian-style) replaces Editor surface
- v0.4.0: MVP (was v0.5.0) — chat moved to post-MVP
- No built-in auto-install — explicit install only

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-03-26 19:38:02 +00:00
parent a36be83aaf
commit 70678cb352
9 changed files with 169 additions and 40 deletions

View File

@@ -478,9 +478,9 @@ func main() {
// Team package settings — cascade overrides (v0.2.0)
teamPkgSettingsH := handlers.NewTeamPackageSettingsHandler(stores)
teamScoped.GET("/packages/:pkgId/settings", teamPkgSettingsH.GetTeamPackageSettings)
teamScoped.PUT("/packages/:pkgId/settings", teamPkgSettingsH.UpdateTeamPackageSettings)
teamScoped.DELETE("/packages/:pkgId/settings", teamPkgSettingsH.DeleteTeamPackageSettings)
teamScoped.GET("/packages/:id/settings", teamPkgSettingsH.GetTeamPackageSettings)
teamScoped.PUT("/packages/:id/settings", teamPkgSettingsH.UpdateTeamPackageSettings)
teamScoped.DELETE("/packages/:id/settings", teamPkgSettingsH.DeleteTeamPackageSettings)
// Team audit log (team admins only — RequireTeamAdmin on group)
teamScoped.GET("/audit", teams.ListTeamAuditLog)
@@ -683,10 +683,8 @@ func main() {
pages.SetVersion(Version)
pageEngine := pages.New(cfg, stores)
// Root redirect → default surface (admin for now, configurable in v0.2.0)
base.GET("/", func(c *gin.Context) {
c.Redirect(http.StatusTemporaryRedirect, cfg.BasePath+"/admin")
})
// Root redirect → configurable default surface (v0.2.1)
base.GET("/", pageEngine.DefaultSurfaceRedirect())
// Login page — no auth required
base.GET("/login", pageEngine.RenderLogin())