Files
osdb-1-claude-opusplan/backend/internal/handler/admin_handler.go
T
juliaandClaude Sonnet 4.6 649c9687ac feat: fruit overview with thumbnails and card layout (story #07)
- Auto-crop thumbnails on image upload (Go stdlib, no external deps):
  find non-background bounding box, pad 5px, scale to ≤300px, encode JPEG
- Add thumbnail_data BYTEA column to fruit_images and publication_fruit_images
- New GET /api/v1/fruits/:id/images/:imageId/thumbnail endpoint (fallback to full data)
- New GET /api/v1/publications/:id/fruit-images/:imgId/thumbnail endpoint
- New POST /api/v1/admin/backfill-thumbnails to retroactively generate thumbnails
- ListFruits response now includes synonyms and thumbnail_url per fruit
- Replace FruitList table with responsive FruitCard grid (thumbnail + name + OSDB ID + type + synonyms)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-19 09:02:14 +02:00

45 lines
1.1 KiB
Go

package handler
import (
"context"
"net/http"
"github.com/labstack/echo/v4"
)
type FruitBackfiller interface {
BackfillThumbnails(ctx context.Context) (int, error)
}
type PubBackfiller interface {
BackfillThumbnails(ctx context.Context) (int, error)
}
type AdminHandler struct {
fruitRepo FruitBackfiller
pubRepo PubBackfiller
}
func NewAdminHandler(fruitRepo FruitBackfiller, pubRepo PubBackfiller) *AdminHandler {
return &AdminHandler{fruitRepo: fruitRepo, pubRepo: pubRepo}
}
func (h *AdminHandler) BackfillThumbnails(c echo.Context) error {
ctx := c.Request().Context()
fruitCount, err := h.fruitRepo.BackfillThumbnails(ctx)
if err != nil {
return c.JSON(http.StatusInternalServerError, map[string]string{"error": "backfill failed: " + err.Error()})
}
pubCount, err := h.pubRepo.BackfillThumbnails(ctx)
if err != nil {
return c.JSON(http.StatusInternalServerError, map[string]string{"error": "backfill failed: " + err.Error()})
}
return c.JSON(http.StatusOK, map[string]int{
"fruit_images_processed": fruitCount,
"pub_fruit_images_processed": pubCount,
})
}