Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 49 additions & 0 deletions backend/api/api.gen.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion backend/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
"github.com/Lumos-Programming/profile-system-backend/api"
"github.com/Lumos-Programming/profile-system-backend/pkg/config"
"github.com/Lumos-Programming/profile-system-backend/pkg/handler"
"github.com/Lumos-Programming/profile-system-backend/pkg/service"
"github.com/gin-gonic/gin"
"github.com/golang-jwt/jwt/v5"
"google.golang.org/api/option"
Expand Down Expand Up @@ -65,7 +66,8 @@ func main() {
}

func setupAPIServer(client *firestore.Client, cfg *config.Config) *gin.Engine {
h := handler.NewHandler(client, cfg.LINE)
membersSvc := service.NewMembersService(client)
h := handler.NewHandler(client, cfg.LINE, membersSvc)
router := gin.Default()
router.Use(func(c *gin.Context) {
c.Header("Access-Control-Allow-Origin", "http://localhost:3000")
Expand Down
7 changes: 5 additions & 2 deletions backend/pkg/handler/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"cloud.google.com/go/firestore"
"github.com/Lumos-Programming/profile-system-backend/api"
"github.com/Lumos-Programming/profile-system-backend/pkg/config"
"github.com/Lumos-Programming/profile-system-backend/pkg/service"
"github.com/gin-gonic/gin"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
Expand All @@ -26,15 +27,17 @@ type Handler struct {
fs *firestore.Client
httpClient *http.Client
lineCfg config.LINE
membersSvc *service.MembersService
}

func NewHandler(f *firestore.Client, lineCfg config.LINE) *Handler {
func NewHandler(f *firestore.Client, lineCfg config.LINE, membersSvc *service.MembersService) *Handler {
return &Handler{
fs: f,
httpClient: &http.Client{
Timeout: 10 * time.Second,
},
lineCfg: lineCfg,
lineCfg: lineCfg,
membersSvc: membersSvc,
}
}

Expand Down
30 changes: 30 additions & 0 deletions backend/pkg/handler/members.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"net/http"

api "github.com/Lumos-Programming/profile-system-backend/api"
"github.com/Lumos-Programming/profile-system-backend/pkg/service"
"github.com/gin-gonic/gin"
"google.golang.org/api/iterator"
"google.golang.org/grpc/codes"
Expand Down Expand Up @@ -171,6 +172,35 @@ func (h *Handler) GetApiMembersId(c *gin.Context, id string) {
// if v == nil {
// return []string{}
// }

// PostApiMembers は新しいメンバーを登録する。
func (h *Handler) PostApiMembers(c *gin.Context) {
ctx := c.Request.Context()

// --- ① リクエストボディをパース ---
var req api.MemberCreate
if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}

// --- ② api.MemberCreate を service.Member に変換 ---
member := service.MemberFromAPICreate(req)

// --- ③ Service層に登録を依頼 ---
id, err := h.membersSvc.Register(ctx, member)
if err != nil {
slog.Error("failed to register member", "error", err)
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}

// --- ④ 成功レスポンス ---
c.JSON(http.StatusCreated, api.MemberCreateResponse{
Id: id,
Message: "メンバーを登録しました",
})
}
// if a, ok := v.([]any); ok {
// out := make([]string, 0, len(a))
// for _, x := range a {
Expand Down
29 changes: 29 additions & 0 deletions backend/pkg/service/members.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package service

import (
"context"

"cloud.google.com/go/firestore"
)

// MembersService は Firestore の "members" コレクションに対する操作を提供する。
type MembersService struct {
fs *firestore.Client
}

// NewMembersService は MembersService を生成する。
func NewMembersService(fs *firestore.Client) *MembersService {
return &MembersService{fs: fs}
}

// Register は Member を Firestore の "members" コレクションに登録する。
// 戻り値はドキュメントIDとエラー。
func (s *MembersService) Register(ctx context.Context, m Member) (string, error) {
doc := s.fs.Collection("members").NewDoc()
m.Id = doc.ID // Firestore のドキュメント ID を id フィールドにも保持
_, err := doc.Set(ctx, m)
if err != nil {
return "", err
}
return doc.ID, nil
}
88 changes: 88 additions & 0 deletions backend/pkg/service/model.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
package service

import api "github.com/Lumos-Programming/profile-system-backend/api"

// Member は Firestore に保存するメンバー情報の構造体。
// firestore タグで Firestore フィールド名を明示する。
type Member struct {
Accounts struct {
Discord bool `firestore:"discord"`
Github bool `firestore:"github"`
Line bool `firestore:"line"`
} `firestore:"accounts"`
Avatar *string `firestore:"avatar,omitempty"`
Bio string `firestore:"bio"`
Department string `firestore:"department"`
Id string `firestore:"id"`
Links []struct {
Title string `firestore:"title"`
Url string `firestore:"url"`
} `firestore:"links"`
Name string `firestore:"name"`
Nickname string `firestore:"nickname"`
Roles []string `firestore:"roles"`
Year string `firestore:"year"`
}

// ToSummary は Member を API レスポンス用の MemberSummary に変換する。
func (m *Member) ToSummary() api.MemberSummary {
return api.MemberSummary{
Id: m.Id,
Name: m.Name,
Nickname: m.Nickname,
Roles: m.Roles,
Avatar: m.Avatar,
}
}

// ToDetail は Member を API レスポンス用の MemberDetail に変換する。
func (m *Member) ToDetail() api.MemberDetail {
detail := api.MemberDetail{
Id: m.Id,
Name: m.Name,
Nickname: m.Nickname,
Department: m.Department,
Year: m.Year,
Bio: m.Bio,
Avatar: m.Avatar,
Roles: m.Roles,
}
detail.Accounts.Discord = m.Accounts.Discord
detail.Accounts.Github = m.Accounts.Github
detail.Accounts.Line = m.Accounts.Line

for _, l := range m.Links {
detail.Links = append(detail.Links, struct {
Title string `json:"title"`
Url string `json:"url"`
}{Title: l.Title, Url: l.Url})
}

return detail
}

// MemberFromAPICreate は api.MemberCreate を Member に変換する。
func MemberFromAPICreate(req api.MemberCreate) Member {
m := Member{
Name: req.Name,
Nickname: req.Nickname,
Department: req.Department,
Year: req.Year,
Bio: req.Bio,
Roles: req.Roles,
Avatar: req.Avatar,
}
m.Accounts.Discord = req.Accounts.Discord
m.Accounts.Github = req.Accounts.Github
m.Accounts.Line = req.Accounts.Line

if req.Links != nil {
for _, l := range *req.Links {
m.Links = append(m.Links, struct {
Title string `firestore:"title"`
Url string `firestore:"url"`
}{Title: l.Title, Url: l.Url})
}
}
return m
}
Loading