LCOV - code coverage report
Current view: top level - adapter/http/controller - i18n_handler.go Coverage Total Hit
Test: coverage.lcov Lines: 0.0 % 58 0
Test Date: 2026-04-14 06:42:22 Functions: - 0 0

            Line data    Source code
       1              : package controller
       2              : 
       3              : import (
       4              :         "net/http"
       5              :         "os"
       6              :         "sort"
       7              : 
       8              :         "github.com/gin-gonic/gin"
       9              :         "golang.org/x/text/language"
      10              :         "golang.org/x/text/language/display"
      11              : 
      12              :         "resume/internal/adapter/http/middleware"
      13              :         repo "resume/internal/domain/repository"
      14              :         vo "resume/internal/domain/valueobject/i18n"
      15              :         uci18n "resume/internal/usecase/i18n"
      16              : )
      17              : 
      18              : // I18nHandler は i18n 関連エンドポイントのハンドラです。
      19              : type I18nHandler struct {
      20              :         uc   uci18n.Usecase
      21              :         repo repo.DictionaryRepository
      22              : }
      23              : 
      24              : // NewI18nHandler は I18nHandler を生成します。
      25              : func NewI18nHandler(
      26              :         uc uci18n.Usecase,
      27              :         repo repo.DictionaryRepository,
      28            0 : ) *I18nHandler {
      29            0 :         return &I18nHandler{
      30            0 :                 uc:   uc,
      31            0 :                 repo: repo,
      32            0 :         }
      33            0 : }
      34              : 
      35              : // GetBundle は prefix で辞書をまとめて返します。
      36              : // GET /i18n/bundle?prefix=ui.page.profile.
      37              : // lang はミドルウェアで決まったものを使用。
      38              : // レスポンスは { "key": "value", ... } のフラットなマップとします。
      39            0 : func (h *I18nHandler) GetBundle(c *gin.Context) {
      40            0 :         loc := vo.NewLocale(middleware.From(c))
      41            0 :         prefix := c.Query("prefix")
      42            0 : 
      43            0 :         out, err := h.uc.ListBundle(c.Request.Context(), uci18n.ListBundleInput{
      44            0 :                 Locale: loc,
      45            0 :                 Prefix: prefix,
      46            0 :         })
      47            0 :         if err != nil {
      48            0 :                 c.JSON(http.StatusInternalServerError, gin.H{"error": gin.H{
      49            0 :                         "code": "i18n_bundle_failed", "message": err.Error(),
      50            0 :                 }})
      51            0 :                 return
      52            0 :         }
      53              :         // locale はレスポンスには含めず、辞書だけを返す
      54            0 :         c.JSON(http.StatusOK, out.Data) // or out.Bundle など、実際のフィールド名に合わせて
      55              : }
      56              : 
      57              : // Reload は辞書を再読込し、キャッシュを差し替えます。
      58              : // POST /i18n/reload(通常は local か管理者のみ)
      59            0 : func (h *I18nHandler) Reload(c *gin.Context) {
      60            0 :         if os.Getenv("APP_ENV") != "local" {
      61            0 :                 c.Status(http.StatusForbidden)
      62            0 :                 return
      63            0 :         }
      64            0 :         if err := h.uc.Reload(c.Request.Context()); err != nil {
      65            0 :                 c.JSON(http.StatusInternalServerError, gin.H{"error": gin.H{
      66            0 :                         "code": "i18n_reload_failed", "message": err.Error(),
      67            0 :                 }})
      68            0 :                 return
      69            0 :         }
      70            0 :         c.Status(http.StatusNoContent)
      71              : }
      72              : 
      73              : // ListLocales は利用可能なロケールの一覧を返します。
      74              : // GET /i18n/locales
      75            0 : func (h *I18nHandler) ListLocales(c *gin.Context) {
      76            0 :         all, err := h.repo.LoadAll()
      77            0 :         if err != nil {
      78            0 :                 c.JSON(http.StatusInternalServerError, gin.H{"error": gin.H{
      79            0 :                         "code": "i18n_list_failed", "message": err.Error(),
      80            0 :                 }})
      81            0 :                 return
      82            0 :         }
      83            0 :         type item struct {
      84            0 :                 Code  string `json:"code"`
      85            0 :                 Label string `json:"label"`
      86            0 :         }
      87            0 :         list := make([]item, 0, len(all))
      88            0 :         for loc := range all {
      89            0 :                 code := loc.Code()
      90            0 :                 lbl := labelFor(code)
      91            0 :                 list = append(list, item{Code: code, Label: lbl})
      92            0 :         }
      93            0 :         sort.Slice(list, func(i, j int) bool { return list[i].Code < list[j].Code })
      94            0 :         c.JSON(http.StatusOK, gin.H{"locales": list})
      95              : }
      96              : 
      97            0 : func labelFor(code string) string {
      98            0 :         if tag, err := language.Parse(code); err == nil {
      99            0 :                 return display.Self.Name(tag) // 例: ja → 日本語, en → English
     100            0 :         }
     101            0 :         return code
     102              : }
        

Generated by: LCOV version 2.3.1-1