Migrate from Gin to Echo framework and add comprehensive integration tests
Major changes: - Migrate all handlers from Gin to Echo framework - Add new apperrors, echohelpers, and validator packages - Update middleware for Echo compatibility - Add ArchivedHandler to task categorization chain (archived tasks go to cancelled_tasks column) - Add 6 new integration tests: - RecurringTaskLifecycle: NextDueDate advancement for weekly/monthly tasks - MultiUserSharing: Complex sharing with user removal - TaskStateTransitions: All state transitions and kanban column changes - DateBoundaryEdgeCases: Threshold boundary testing - CascadeOperations: Residence deletion cascade effects - MultiUserOperations: Shared residence collaboration - Add single-purpose repository functions for kanban columns (GetOverdueTasks, GetDueSoonTasks, etc.) - Fix RemoveUser route param mismatch (userId -> user_id) - Fix determineExpectedColumn helper to correctly prioritize in_progress over overdue 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -3,7 +3,7 @@ package middleware
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/labstack/echo/v4"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -22,21 +22,23 @@ const (
|
||||
// or a UTC offset (e.g., "-08:00", "+05:30").
|
||||
//
|
||||
// If no timezone is provided or it's invalid, UTC is used as the default.
|
||||
func TimezoneMiddleware() gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
tzName := c.GetHeader(TimezoneHeader)
|
||||
loc := parseTimezone(tzName)
|
||||
func TimezoneMiddleware() echo.MiddlewareFunc {
|
||||
return func(next echo.HandlerFunc) echo.HandlerFunc {
|
||||
return func(c echo.Context) error {
|
||||
tzName := c.Request().Header.Get(TimezoneHeader)
|
||||
loc := parseTimezone(tzName)
|
||||
|
||||
// Store the location and the current time in that timezone
|
||||
c.Set(TimezoneKey, loc)
|
||||
// Store the location and the current time in that timezone
|
||||
c.Set(TimezoneKey, loc)
|
||||
|
||||
// Calculate "now" in the user's timezone, then get start of day
|
||||
// For date comparisons, we want to compare against the START of the user's current day
|
||||
userNow := time.Now().In(loc)
|
||||
startOfDay := time.Date(userNow.Year(), userNow.Month(), userNow.Day(), 0, 0, 0, 0, loc)
|
||||
c.Set(UserNowKey, startOfDay)
|
||||
// Calculate "now" in the user's timezone, then get start of day
|
||||
// For date comparisons, we want to compare against the START of the user's current day
|
||||
userNow := time.Now().In(loc)
|
||||
startOfDay := time.Date(userNow.Year(), userNow.Month(), userNow.Day(), 0, 0, 0, 0, loc)
|
||||
c.Set(UserNowKey, startOfDay)
|
||||
|
||||
c.Next()
|
||||
return next(c)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -76,22 +78,22 @@ func parseTimezone(tz string) *time.Location {
|
||||
return time.UTC
|
||||
}
|
||||
|
||||
// GetUserTimezone retrieves the user's timezone from the Gin context.
|
||||
// GetUserTimezone retrieves the user's timezone from the Echo context.
|
||||
// Returns UTC if not set.
|
||||
func GetUserTimezone(c *gin.Context) *time.Location {
|
||||
loc, exists := c.Get(TimezoneKey)
|
||||
if !exists {
|
||||
func GetUserTimezone(c echo.Context) *time.Location {
|
||||
loc := c.Get(TimezoneKey)
|
||||
if loc == nil {
|
||||
return time.UTC
|
||||
}
|
||||
return loc.(*time.Location)
|
||||
}
|
||||
|
||||
// GetUserNow retrieves the timezone-aware "now" time from the Gin context.
|
||||
// GetUserNow retrieves the timezone-aware "now" time from the Echo context.
|
||||
// This represents the start of the current day in the user's timezone.
|
||||
// Returns time.Now().UTC() if not set.
|
||||
func GetUserNow(c *gin.Context) time.Time {
|
||||
now, exists := c.Get(UserNowKey)
|
||||
if !exists {
|
||||
func GetUserNow(c echo.Context) time.Time {
|
||||
now := c.Get(UserNowKey)
|
||||
if now == nil {
|
||||
return time.Now().UTC()
|
||||
}
|
||||
return now.(time.Time)
|
||||
|
||||
Reference in New Issue
Block a user