Files
honeyDueAPI/MIGRATION_STATUS.md
Trey t 6dac34e373 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>
2025-12-16 13:52:08 -06:00

171 lines
4.9 KiB
Markdown

# Phase 4: Gin to Echo Handler Migration Status
## Completed Files
### ✅ auth_handler.go
- **Status**: Fully migrated
- **Methods migrated**: 13 methods
- Login, Register, Logout, CurrentUser, UpdateProfile
- VerifyEmail, ResendVerification
- ForgotPassword, VerifyResetCode, ResetPassword
- AppleSignIn, GoogleSignIn
- **Key changes applied**:
- Import changed from gin to echo
- Added validator import
- All handlers return error
- c.Bind + c.Validate pattern implemented
- c.MustGet → c.Get
- gin.H → map[string]interface{}
- c.Request.Context() → c.Request().Context()
- All c.JSON calls use `return`
## Remaining Files to Migrate
### 🔧 residence_handler.go
- **Status**: Partially migrated (needs cleanup)
- **Methods**: 13 methods
- **Issue**: Sed-based automated migration created syntax errors
- **Next steps**: Manual cleanup needed
### ⏳ task_handler.go
- **Methods**: ~17 methods
- **Complexity**: High (multipart form handling for completions)
- **Special considerations**:
- Has multipart/form-data handling in CreateCompletion
- Multiple lookup endpoints (categories, priorities, frequencies)
### ⏳ contractor_handler.go
- **Methods**: 8 methods
- **Complexity**: Medium
### ⏳ document_handler.go
- **Methods**: 8 methods
- **Complexity**: High (multipart form handling)
- **Special considerations**: File upload in CreateDocument
### ⏳ notification_handler.go
- **Methods**: 9 methods
- **Complexity**: Medium
- **Special considerations**: Query parameters for pagination
### ⏳ subscription_handler.go
- **Status**: Unknown
- **Estimated complexity**: Medium
### ⏳ upload_handler.go
- **Methods**: 4 methods
- **Complexity**: Medium
- **Special considerations**: c.FormFile handling, c.DefaultQuery
### ⏳ user_handler.go
- **Methods**: 3 methods
- **Complexity**: Low
### ⏳ media_handler.go
- **Status**: Unknown
- **Estimated complexity**: Medium
### ⏳ static_data_handler.go
- **Methods**: Unknown
- **Complexity**: Low (likely just lookups)
### ⏳ task_template_handler.go
- **Status**: Unknown
- **Estimated complexity**: Medium
### ⏳ tracking_handler.go
- **Status**: Unknown
- **Estimated complexity**: Low
### ⏳ subscription_webhook_handler.go
- **Status**: Unknown
- **Estimated complexity**: Medium-High (webhook handling)
## Migration Pattern
All handlers must follow these transformations:
```go
// BEFORE (Gin)
func (h *Handler) Method(c *gin.Context) {
user := c.MustGet(middleware.AuthUserKey).(*models.User)
var req requests.SomeRequest
if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(400, gin.H{"error": err.Error()})
return
}
result, err := h.service.DoSomething(&req)
if err != nil {
c.JSON(500, gin.H{"error": err.Error()})
return
}
c.JSON(200, result)
}
// AFTER (Echo)
func (h *Handler) Method(c echo.Context) error {
user := c.Get(middleware.AuthUserKey).(*models.User)
var req requests.SomeRequest
if err := c.Bind(&req); err != nil {
return c.JSON(400, map[string]interface{}{"error": err.Error()})
}
if err := c.Validate(&req); err != nil {
return c.JSON(400, validator.FormatValidationErrors(err))
}
result, err := h.service.DoSomething(&req)
if err != nil {
return c.JSON(500, map[string]interface{}{"error": err.Error()})
}
return c.JSON(200, result)
}
```
## Critical Context Changes
| Gin | Echo |
|-----|------|
| `c.MustGet()` | `c.Get()` |
| `c.ShouldBindJSON()` | `c.Bind()` + `c.Validate()` |
| `c.JSON(status, data)` | `return c.JSON(status, data)` |
| `c.Query("key")` | `c.QueryParam("key")` |
| `c.DefaultQuery("k", "v")` | Manual: `if v := c.QueryParam("k"); v != "" { } else { v = "default" }` |
| `c.PostForm("field")` | `c.FormValue("field")` |
| `c.GetHeader("X-...")` | `c.Request().Header.Get("X-...")` |
| `c.Request.Context()` | `c.Request().Context()` |
| `c.Status(code)` | `return c.NoContent(code)` |
| `gin.H{...}` | `map[string]interface{}{...}` |
## Multipart Form Handling
For handlers with file uploads (document_handler, task_handler):
```go
// Request parsing
c.Request.ParseMultipartForm(32 << 20) // Same
c.PostForm("field") c.FormValue("field")
c.FormFile("file") // Same
```
## Next Steps
1. Clean up residence_handler.go manually
2. Migrate contractor_handler.go (simpler, good template)
3. Migrate smaller files: user_handler.go, upload_handler.go, notification_handler.go
4. Migrate complex files: task_handler.go, document_handler.go
5. Migrate remaining files
6. Test compilation
7. Update route registration (if not already done in Phase 3)
## Automation Lessons Learned
- Sed-based bulk replacements are error-prone for complex Go code
- Better approach: Manual migration with copy-paste for repetitive patterns
- Python script provided in migrate_handlers.py (not yet tested)
- Best approach: Methodical manual migration with validation at each step