Release v0.4.0 #27

Merged
Mike Bros merged 34 commits from release/v0.4.0 into main 2026-02-18 22:56:40 +00:00
Contributor

Release v0.4.0 — Phase 4: Polish & Refinements

Changes

Code Quality & Architecture (20 tasks)

  • OP#182–#186, #234, #236–#238, #241: Comprehensive test coverage (auth, services, handlers, security, validation, transactions)
  • OP#187: Transaction boundaries for complex operations
  • OP#188: Refactored oversized service & handler files
  • OP#189: Structured error handling & consistent HTTP responses
  • OP#190: Structured logging with slog
  • OP#191: Session secret enforcement & security hardening
  • OP#192: Dead code cleanup
  • OP#193: CI pipeline hardening
  • OP#194: Service layer interface extraction
  • OP#195: Querier interface for database layer
  • OP#197: Input validation layer

Features & Enhancements (6 tasks)

  • OP#147: Styled error pages (404, 403, 500, 401, 400)
  • OP#148: Toast notifications & confirmation modals
  • OP#150: 9 additional builtin themes
  • OP#168: Configurable navbar & footer settings
  • OP#386: Ordering support in dashboard diff detection
  • OP#387: Dismissed items redesign (array → join table)

Documentation (3 tasks)

  • OP#146: Mobile responsiveness audit & standards
  • OP#196: Git branch hygiene & conventions
  • OP#198: Project standards wiki

Checklist

  • All 39 version tasks closed in Gravity PM
  • Tests passing (go test -race -count=1 ./...)
  • Vet passing (go vet ./...)
  • Version file matches Gravity PM version (manifest.json → 0.4.0)

References

Version: v0.4.0 — Phase 4: Polish (Gravity PM ID: 13)
Release task: OP#1054

## Release v0.4.0 — Phase 4: Polish & Refinements ### Changes **Code Quality & Architecture (20 tasks)** - OP#182–#186, #234, #236–#238, #241: Comprehensive test coverage (auth, services, handlers, security, validation, transactions) - OP#187: Transaction boundaries for complex operations - OP#188: Refactored oversized service & handler files - OP#189: Structured error handling & consistent HTTP responses - OP#190: Structured logging with slog - OP#191: Session secret enforcement & security hardening - OP#192: Dead code cleanup - OP#193: CI pipeline hardening - OP#194: Service layer interface extraction - OP#195: Querier interface for database layer - OP#197: Input validation layer **Features & Enhancements (6 tasks)** - OP#147: Styled error pages (404, 403, 500, 401, 400) - OP#148: Toast notifications & confirmation modals - OP#150: 9 additional builtin themes - OP#168: Configurable navbar & footer settings - OP#386: Ordering support in dashboard diff detection - OP#387: Dismissed items redesign (array → join table) **Documentation (3 tasks)** - OP#146: Mobile responsiveness audit & standards - OP#196: Git branch hygiene & conventions - OP#198: Project standards wiki ### Checklist - [x] All 39 version tasks closed in Gravity PM - [x] Tests passing (`go test -race -count=1 ./...`) - [x] Vet passing (`go vet ./...`) - [x] Version file matches Gravity PM version (manifest.json → 0.4.0) ### References Version: v0.4.0 — Phase 4: Polish (Gravity PM ID: 13) Release task: OP#1054
Add testify and pgxmock/v4 as test dependencies. Create internal/testutil
package with context builders, HTTP test helpers, and database mock setup.
Includes 8 demonstration tests validating the helper functions.

- testutil.TestUser() / TestAdmin() — create users with sensible defaults
- testutil.NewRequest() / PostForm() — HTTP test request builders
- testutil.RequestWithUser() / ContextWithUser() — context injection
- testutil.NewMockPool() — pgxmock pool with automatic cleanup
- testutil.DefaultSettings() — AppSettings with common test defaults
- testutil.HTMXRequest() — mark requests as HTMX

Closes GP#182

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace concrete service types in handler structs with interfaces
(DashboardServicer, ThemeServicer, ImportServicer, EmailServicer,
StatusChecker). Services are now injected via constructors and wired
in main.go. Includes compile-time interface satisfaction checks and
updated existing tests to use mock implementations.

Closes GP#194

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Create database.Querier and database.DB interfaces that abstract the
pgx query and transaction surface. Refactor all services to accept these
interfaces instead of *pgxpool.Pool directly, enabling transparent
transaction support and easier testing.

- DashboardService, ImportService, EmailService accept database.DB
- ThemeService accepts database.Querier (no transactions needed)
- SeedThemes accepts database.Querier
- handlers.DBTX aliased to database.Querier
- SQL audit: all queries use parameterized placeholders
- N+1 patterns documented (assembleDashboard)
- sqlc evaluation: defer adoption (current scale doesn't warrant it)

Closes GP#195

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Configure slog with JSON handler in main.go, add RequestLogger middleware
for HTTP request logging, and convert all log.Printf/Println/Fatalf calls
to structured slog.Error/Warn/Info with key-value pairs across 22 files.

Closes GP#190

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Introduces serverError, badRequest, notFound, forbidden, and unauthorized
helpers that handle both htmx (toast) and standard (http.Error) paths.
Replaces all raw http.Error calls across 11 handler files.

Closes GP#189

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Require SESSION_SECRET at startup (fail-fast unless DEV_AUTH=true)
- Add double-submit cookie CSRF protection on all state-changing requests
- Add per-IP rate limiting on auth endpoints (login, callback, setup)
- Add startup warnings for insecure configuration (short secret, dev auth)
- Auto-inject CSRF tokens via JS for both htmx and regular forms

Closes GP#191

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add WithTx and WithTxResult[T] helpers for consistent transaction handling
- Wrap SoftDeleteDashboard in transaction (was 3 separate queries without tx)
- Add pgxmock-based tests for commit and rollback paths
- Core operations (Clone, Import, Reorder, Move) already transactional from #195

Closes GP#187

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add requireField, parseFormUUID, validateURL, validateEnum helpers
- Validate section name required on create/update
- Validate item title required, URL format on create/update
- Validate OIDC fields required when enabled (admin auth)
- Validate SMTP host required when enabled (admin SMTP)
- Validate theme display name required on update
- Add ParseForm to ProfileUpdate for consistency
- 14 validation tests covering all helpers and htmx paths

Closes GP#197

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Split user_dashboards.go (1108 lines) into 3 files:
- user_dashboards.go (682) — CRUD, management, settings
- user_sharing.go (250) — shares, notifications, email
- user_diff.go (200) — diff/merge operations

Split crud.go (892 lines) into 5 entity files:
- crud.go (67) — shared helpers, settings
- crud_pages.go (62) — pages CRUD
- crud_sections.go (95) — sections CRUD
- crud_items.go (235) — items CRUD
- crud_dashboards.go (463) — dashboards CRUD

Pure reorganization — no functional changes.

Closes GP#188

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Remove empty placeholder dirs (components/dashboard/, components/sharing/)
- Remove dead assets/ package (embed lives in root embed.go)
- Add Tailwind safelist for Go-returned CSS classes (NotifIconColor)
- Document group visibility filtering design in loadSections

Closes GP#192

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Test job now depends on lint (needs: lint)
- Coverage profile generated and summary displayed in CI log
- Minimum coverage threshold enforced (15%, configurable via env)
- templ generate freshness check catches stale generated files

Closes GP#193

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Session: sign/verify round-trip, tamper detection, wrong secret rejection,
  session ID format/uniqueness, cookie format validation
- OIDC: isAdmin group/role matching, parseStringArray edge cases
- Manager: nil-provider fallback handlers (login→/setup, callback→503, logout→/)
- Middleware: isPublicPath coverage for all route categories

Closes GP#183

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Diff: tagsStr, field-level item comparison, new/changed/removed/dismissed
  item collection logic tested with in-memory data structures
- Theme: CSSVarsMap with valid/nil/empty/invalid JSON, all builtin themes
  verified for 19 CSS vars and JSON round-trip
- Seed: builtin themes validated for light/dark mix and unique names

Closes GP#184

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Dashboard Index: redirects to /setup when not configured, 404 for non-root
- StatusRefresh: valid/invalid UUID, wrong method
- UserSectionDelete: happy path end-to-end, auth guard
- LoginPage: OIDC delegation vs login page render

Closes GP#185

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Table-driven tests for isAcceptedStatus covering defaults, explicit
ranges, case insensitivity, whitespace, and edge cases. HTTP check
tests via httptest for success, errors, custom accepted codes,
connection refused, and redirects. Per-item interval enforcement.

Closes GP#186

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add session secret enforcement tests (valid secret succeeds, error
message includes DEV_AUTH hint). Expand CSRF tests with PUT method
coverage, unique token generation, cross-session rejection, and
empty context fallback. Completes coverage for GP#191 security work.

Closes GP#234

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add whitespace-only field rejection, SQL injection attempt on UUID
parser, javascript: scheme rejection, enum error message content
check, and handler integration test proving validation failures
return 400 not 500.

Closes GP#236

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Proves atomicity for ReorderSections, ReorderItems, MoveItemToSection,
CloneDashboard, and ImportDashyConfigTo. Each operation has success
(commit verified) and rollback (mid-failure proves zero partial state)
tests. Uses pgxmock to simulate failures at specific query points.

Closes GP#237

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add serverError with extra attrs, htmx body leak prevention,
and badRequest message preservation tests. Verifies internal
error details never reach the client in either standard or htmx paths.

Closes GP#238

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Migrate from UUID[] column on dashboards to a
dashboard_dismissed_items join table with proper foreign keys and
CASCADE deletes. Update all SELECT/RETURNING queries, diff logic,
dismiss/clear operations, and test mocks.

Migration 00016 creates the table, migrates data, drops the column.

Closes GP#387

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Detect sort_order changes at page, section, and item levels between
cloned dashboards and their sources. Reorder operations now bump
dashboard version to trigger diff detection. Adds OrderChange model,
detectOrderChanges logic, and DiffPage template section.

Closes GP#386

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace simple footer_text field with rich JSONB-backed navbar and
footer configuration. Navbar supports show/hide for logo, title, search,
notifications, and user menu. Footer supports modular components (text,
links, icon links) with optional branding toggle. Null config = full
defaults for backward compatibility.

Closes GP#168

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Model tests for NavbarConfig/FooterConfig nil defaults, explicit values,
element filtering, and AppSettings JSON round-trip. Template tests for
footer component rendering (text, link, icon), branding toggle, and
header navbar config visibility controls.

Closes GP#241

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Self-contained error page template with gradient code display, themed
fallback colors, navigation actions. Replace all http.NotFound calls
with custom notFound that renders styled pages for standard requests
while preserving HTMX toast behavior. Adds forbidden and unauthorized
HTMX handling.

Closes GP#147

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add Dracula, Nord, Gruvbox Dark, Gruvbox Light, Solarized Dark,
Solarized Light, Tokyo Night, One Dark, and Rosé Pine theme
definitions to the builtin themes list for seeding on startup.

Closes GP#150

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Responsive audit covering all 26 templ components with ratings
- Mobile standards document with breakpoint strategy, layout patterns,
  and component checklist
- Created follow-up epic GP#1059 with 5 implementation tasks in v0.4.1

Closes GP#146

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Create index page and 8 standards documents covering testing, error
handling, database patterns, service layer, handler patterns, logging,
security, and git/branch conventions. All patterns extracted from the
actual codebase.

Closes GP#198

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Deleted 27 merged feature branches from remote
- Deleted 28 merged local branches (features + release/v0.3.1)
- Updated branch naming conventions with all prefix types

Closes GP#196

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
chore(release): bump version to 0.4.0
Some checks failed
CI / validate-branch (pull_request) Successful in 0s
CI / validate-release-pr (pull_request) Successful in 4s
CI / security (pull_request) Successful in 1m14s
CI / lint (pull_request) Failing after 1m14s
CI / test (pull_request) Has been skipped
CI / build (pull_request) Successful in 1m46s
54d3e5a66e
Refs GP#1054

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
fix(release): apply gofumpt and goimports formatting
All checks were successful
CI / validate-branch (pull_request) Successful in 1s
CI / validate-release-pr (pull_request) Successful in 5s
CI / security (pull_request) Successful in 45s
CI / build (pull_request) Successful in 1m54s
CI / lint (pull_request) Successful in 2m47s
CI / test (pull_request) Successful in 1m51s
ef51216b3d
Fix import ordering, column alignment, and naked returns flagged by
CI formatting checks.

Refs GP#1054

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Mike Bros deleted branch release/v0.4.0 2026-02-18 22:56:40 +00:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
mike/gashy!27
No description provided.