mirror of
https://github.com/yyhuni/xingrin.git
synced 2026-01-31 11:46:16 +08:00
- Add DTOs for user, organization, target, engine, pagination, and response handling - Implement repository layer for user, organization, target, and engine entities - Implement service layer with business logic for all core modules - Implement HTTP handlers for user, organization, target, and engine endpoints - Add complete CRUD API routes with soft delete support for organizations and targets - Add environment configuration file with database, Redis, and logging settings - Add docker-compose.dev.yml for PostgreSQL and Redis development dependencies - Add comprehensive README.md with migration progress, API endpoints, and tech stack - Update main.go to wire repositories, services, and handlers with dependency injection - Update config.go to support .env file loading with environment variable priority - Update database.go to initialize all repositories and services
162 lines
3.8 KiB
Go
162 lines
3.8 KiB
Go
package handler
|
|
|
|
import (
|
|
"errors"
|
|
"strconv"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
"github.com/xingrin/go-backend/internal/dto"
|
|
"github.com/xingrin/go-backend/internal/service"
|
|
)
|
|
|
|
// OrganizationHandler handles organization endpoints
|
|
type OrganizationHandler struct {
|
|
svc *service.OrganizationService
|
|
}
|
|
|
|
// NewOrganizationHandler creates a new organization handler
|
|
func NewOrganizationHandler(svc *service.OrganizationService) *OrganizationHandler {
|
|
return &OrganizationHandler{svc: svc}
|
|
}
|
|
|
|
// Create creates a new organization
|
|
// POST /api/organizations
|
|
func (h *OrganizationHandler) Create(c *gin.Context) {
|
|
var req dto.CreateOrganizationRequest
|
|
if err := c.ShouldBindJSON(&req); err != nil {
|
|
dto.BadRequest(c, "Invalid request body")
|
|
return
|
|
}
|
|
|
|
org, err := h.svc.Create(&req)
|
|
if err != nil {
|
|
if errors.Is(err, service.ErrOrganizationExists) {
|
|
dto.BadRequest(c, "Organization name already exists")
|
|
return
|
|
}
|
|
dto.InternalError(c, "Failed to create organization")
|
|
return
|
|
}
|
|
|
|
dto.Created(c, dto.OrganizationResponse{
|
|
ID: org.ID,
|
|
Name: org.Name,
|
|
Description: org.Description,
|
|
CreatedAt: org.CreatedAt,
|
|
})
|
|
}
|
|
|
|
// List returns paginated organizations
|
|
// GET /api/organizations
|
|
func (h *OrganizationHandler) List(c *gin.Context) {
|
|
var query dto.PaginationQuery
|
|
if err := c.ShouldBindQuery(&query); err != nil {
|
|
dto.BadRequest(c, "Invalid query parameters")
|
|
return
|
|
}
|
|
|
|
orgs, total, err := h.svc.List(&query)
|
|
if err != nil {
|
|
dto.InternalError(c, "Failed to list organizations")
|
|
return
|
|
}
|
|
|
|
var resp []dto.OrganizationResponse
|
|
for _, o := range orgs {
|
|
resp = append(resp, dto.OrganizationResponse{
|
|
ID: o.ID,
|
|
Name: o.Name,
|
|
Description: o.Description,
|
|
CreatedAt: o.CreatedAt,
|
|
})
|
|
}
|
|
|
|
dto.Paginated(c, resp, total, query.GetPage(), query.GetPageSize())
|
|
}
|
|
|
|
// GetByID returns an organization by ID
|
|
// GET /api/organizations/:id
|
|
func (h *OrganizationHandler) GetByID(c *gin.Context) {
|
|
id, err := strconv.Atoi(c.Param("id"))
|
|
if err != nil {
|
|
dto.BadRequest(c, "Invalid organization ID")
|
|
return
|
|
}
|
|
|
|
org, err := h.svc.GetByID(id)
|
|
if err != nil {
|
|
if errors.Is(err, service.ErrOrganizationNotFound) {
|
|
dto.NotFound(c, "Organization not found")
|
|
return
|
|
}
|
|
dto.InternalError(c, "Failed to get organization")
|
|
return
|
|
}
|
|
|
|
dto.Success(c, dto.OrganizationResponse{
|
|
ID: org.ID,
|
|
Name: org.Name,
|
|
Description: org.Description,
|
|
CreatedAt: org.CreatedAt,
|
|
})
|
|
}
|
|
|
|
// Update updates an organization
|
|
// PUT /api/organizations/:id
|
|
func (h *OrganizationHandler) Update(c *gin.Context) {
|
|
id, err := strconv.Atoi(c.Param("id"))
|
|
if err != nil {
|
|
dto.BadRequest(c, "Invalid organization ID")
|
|
return
|
|
}
|
|
|
|
var req dto.UpdateOrganizationRequest
|
|
if err := c.ShouldBindJSON(&req); err != nil {
|
|
dto.BadRequest(c, "Invalid request body")
|
|
return
|
|
}
|
|
|
|
org, err := h.svc.Update(id, &req)
|
|
if err != nil {
|
|
if errors.Is(err, service.ErrOrganizationNotFound) {
|
|
dto.NotFound(c, "Organization not found")
|
|
return
|
|
}
|
|
if errors.Is(err, service.ErrOrganizationExists) {
|
|
dto.BadRequest(c, "Organization name already exists")
|
|
return
|
|
}
|
|
dto.InternalError(c, "Failed to update organization")
|
|
return
|
|
}
|
|
|
|
dto.Success(c, dto.OrganizationResponse{
|
|
ID: org.ID,
|
|
Name: org.Name,
|
|
Description: org.Description,
|
|
CreatedAt: org.CreatedAt,
|
|
})
|
|
}
|
|
|
|
// Delete soft deletes an organization
|
|
// DELETE /api/organizations/:id
|
|
func (h *OrganizationHandler) Delete(c *gin.Context) {
|
|
id, err := strconv.Atoi(c.Param("id"))
|
|
if err != nil {
|
|
dto.BadRequest(c, "Invalid organization ID")
|
|
return
|
|
}
|
|
|
|
err = h.svc.Delete(id)
|
|
if err != nil {
|
|
if errors.Is(err, service.ErrOrganizationNotFound) {
|
|
dto.NotFound(c, "Organization not found")
|
|
return
|
|
}
|
|
dto.InternalError(c, "Failed to delete organization")
|
|
return
|
|
}
|
|
|
|
dto.NoContent(c)
|
|
}
|