feat: manage fruits — full CRUD with images and synonyms (story #02)
Backend: domain structs, FruitRepository interface + pg implementation,
9 Echo v4 handlers (list/get/create/update/delete, image sub-resources),
migration 000002 (fruit_type ENUM, fruits, fruit_synonyms, fruit_images),
route-scoped BodyLimit("5M") for uploads, http.DetectContentType for serving.
Frontend: typed fetch API layer, Pinia setup-style fruitStore, FruitList
(paginated), FruitCreate, and FruitDetail (edit + synonyms editor + image
gallery). 25 backend unit tests + integration test; 18 frontend tests.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -6,30 +6,17 @@ import (
|
||||
"github.com/labstack/echo/v4/middleware"
|
||||
|
||||
"osdb/internal/handler"
|
||||
"osdb/internal/repository"
|
||||
)
|
||||
|
||||
// New creates and configures the Echo instance with all routes registered.
|
||||
// pool is stored on Echo's context so all handlers added by future stories
|
||||
// (#2 fruits, #4 publications, #7 thumbnails, #8 auth) can retrieve it via
|
||||
// c.Get("pool").(*pgxpool.Pool).
|
||||
//
|
||||
// Extension point: story #2, #4, #7, #8 route groups are added here.
|
||||
func New(pool *pgxpool.Pool) *echo.Echo {
|
||||
e := echo.New()
|
||||
e.HideBanner = true
|
||||
|
||||
// Global middleware
|
||||
e.Use(middleware.Logger())
|
||||
e.Use(middleware.Recover())
|
||||
|
||||
// Make pool available to all handlers via Echo context.
|
||||
e.Use(func(next echo.HandlerFunc) echo.HandlerFunc {
|
||||
return func(c echo.Context) error {
|
||||
c.Set("pool", pool)
|
||||
return next(c)
|
||||
}
|
||||
})
|
||||
|
||||
health := handler.NewHealthHandler()
|
||||
|
||||
// Root health — used by docker healthcheck + ops tooling
|
||||
@@ -39,7 +26,20 @@ func New(pool *pgxpool.Pool) *echo.Echo {
|
||||
api := e.Group("/api/v1")
|
||||
api.GET("/health", health.Health)
|
||||
|
||||
// Future story groups (fruits, publications, admin, auth) are added here.
|
||||
// Fruits (story #02)
|
||||
fruitRepo := repository.NewFruitRepo(pool)
|
||||
fruits := handler.NewFruitHandler(fruitRepo)
|
||||
|
||||
g := api.Group("/fruits")
|
||||
g.GET("", fruits.List)
|
||||
g.POST("", fruits.Create)
|
||||
g.GET("/:id", fruits.Get)
|
||||
g.PUT("/:id", fruits.Update)
|
||||
g.DELETE("/:id", fruits.Delete)
|
||||
g.GET("/:id/images", fruits.ListImages)
|
||||
g.POST("/:id/images", fruits.UploadImage, middleware.BodyLimit("5M"))
|
||||
g.GET("/:id/images/:imageId", fruits.ServeImage)
|
||||
g.DELETE("/:id/images/:imageId", fruits.DeleteImage)
|
||||
|
||||
return e
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user