mirror of
https://github.com/SamyRai/turash.git
synced 2025-12-26 23:01:33 +00:00
Repository Structure:
- Move files from cluttered root directory into organized structure
- Create archive/ for archived data and scraper results
- Create bugulma/ for the complete application (frontend + backend)
- Create data/ for sample datasets and reference materials
- Create docs/ for comprehensive documentation structure
- Create scripts/ for utility scripts and API tools
Backend Implementation:
- Implement 3 missing backend endpoints identified in gap analysis:
* GET /api/v1/organizations/{id}/matching/direct - Direct symbiosis matches
* GET /api/v1/users/me/organizations - User organizations
* POST /api/v1/proposals/{id}/status - Update proposal status
- Add complete proposal domain model, repository, and service layers
- Create database migration for proposals table
- Fix CLI server command registration issue
API Documentation:
- Add comprehensive proposals.md API documentation
- Update README.md with Users and Proposals API sections
- Document all request/response formats, error codes, and business rules
Code Quality:
- Follow existing Go backend architecture patterns
- Add proper error handling and validation
- Match frontend expected response schemas
- Maintain clean separation of concerns (handler -> service -> repository)
171 lines
4.7 KiB
Go
171 lines
4.7 KiB
Go
package handler
|
|
|
|
import (
|
|
"net/http"
|
|
|
|
"bugulma/backend/internal/domain"
|
|
"bugulma/backend/internal/service"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
)
|
|
|
|
type SiteHandler struct {
|
|
siteService *service.SiteService
|
|
}
|
|
|
|
func NewSiteHandler(siteService *service.SiteService) *SiteHandler {
|
|
return &SiteHandler{siteService: siteService}
|
|
}
|
|
|
|
type CreateSiteRequest struct {
|
|
Name string `json:"name" binding:"required"`
|
|
Latitude float64 `json:"latitude" binding:"required"`
|
|
Longitude float64 `json:"longitude" binding:"required"`
|
|
SiteType domain.SiteType `json:"site_type"`
|
|
FloorAreaM2 float64 `json:"floor_area_m2"`
|
|
Ownership domain.Ownership `json:"ownership"`
|
|
OwnerOrganizationID string `json:"owner_organization_id" binding:"required"`
|
|
AvailableUtilities []string `json:"available_utilities"`
|
|
ParkingSpaces int `json:"parking_spaces"`
|
|
LoadingDocks int `json:"loading_docks"`
|
|
CraneCapacityTonnes float64 `json:"crane_capacity_tonnes"`
|
|
EnergyRating string `json:"energy_rating"`
|
|
}
|
|
|
|
func (h *SiteHandler) Create(c *gin.Context) {
|
|
var req CreateSiteRequest
|
|
if err := c.ShouldBindJSON(&req); err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
|
return
|
|
}
|
|
|
|
siteReq := service.CreateSiteRequest{
|
|
Name: req.Name,
|
|
Latitude: req.Latitude,
|
|
Longitude: req.Longitude,
|
|
SiteType: req.SiteType,
|
|
FloorAreaM2: req.FloorAreaM2,
|
|
Ownership: req.Ownership,
|
|
OwnerOrganizationID: req.OwnerOrganizationID,
|
|
AvailableUtilities: req.AvailableUtilities,
|
|
ParkingSpaces: req.ParkingSpaces,
|
|
LoadingDocks: req.LoadingDocks,
|
|
CraneCapacityTonnes: req.CraneCapacityTonnes,
|
|
EnergyRating: req.EnergyRating,
|
|
}
|
|
|
|
created, err := h.siteService.Create(c.Request.Context(), siteReq)
|
|
if err != nil {
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
|
return
|
|
}
|
|
|
|
c.JSON(http.StatusCreated, created)
|
|
}
|
|
|
|
func (h *SiteHandler) GetByID(c *gin.Context) {
|
|
id := c.Param("id")
|
|
|
|
site, err := h.siteService.GetByID(c.Request.Context(), id)
|
|
if err != nil {
|
|
c.JSON(http.StatusNotFound, gin.H{"error": "Site not found"})
|
|
return
|
|
}
|
|
|
|
c.JSON(http.StatusOK, site)
|
|
}
|
|
|
|
func (h *SiteHandler) GetByOrganization(c *gin.Context) {
|
|
organizationID := c.Param("organizationId")
|
|
|
|
sites, err := h.siteService.GetByOrganizationID(c.Request.Context(), organizationID)
|
|
if err != nil {
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
|
return
|
|
}
|
|
|
|
c.JSON(http.StatusOK, sites)
|
|
}
|
|
|
|
func (h *SiteHandler) GetNearby(c *gin.Context) {
|
|
var query struct {
|
|
Latitude float64 `form:"lat" binding:"required"`
|
|
Longitude float64 `form:"lng" binding:"required"`
|
|
RadiusKm float64 `form:"radius" binding:"required"`
|
|
}
|
|
|
|
if err := c.ShouldBindQuery(&query); err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
|
return
|
|
}
|
|
|
|
sites, err := h.siteService.GetNearby(c.Request.Context(), query.Latitude, query.Longitude, query.RadiusKm)
|
|
if err != nil {
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
|
return
|
|
}
|
|
|
|
c.JSON(http.StatusOK, sites)
|
|
}
|
|
|
|
func (h *SiteHandler) GetAll(c *gin.Context) {
|
|
sites, err := h.siteService.GetAll(c.Request.Context())
|
|
if err != nil {
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
|
return
|
|
}
|
|
|
|
c.JSON(http.StatusOK, sites)
|
|
}
|
|
|
|
func (h *SiteHandler) GetHeritageSites(c *gin.Context) {
|
|
locale := extractLocale(c)
|
|
sites, err := h.siteService.GetHeritageSites(c.Request.Context(), locale)
|
|
if err != nil {
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
|
return
|
|
}
|
|
|
|
c.JSON(http.StatusOK, sites)
|
|
}
|
|
|
|
func (h *SiteHandler) Update(c *gin.Context) {
|
|
id := c.Param("id")
|
|
|
|
var req CreateSiteRequest
|
|
if err := c.ShouldBindJSON(&req); err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
|
return
|
|
}
|
|
|
|
site, err := h.siteService.GetByID(c.Request.Context(), id)
|
|
if err != nil {
|
|
c.JSON(http.StatusNotFound, gin.H{"error": "Site not found"})
|
|
return
|
|
}
|
|
|
|
// Update fields
|
|
site.Name = req.Name
|
|
site.Latitude = req.Latitude
|
|
site.Longitude = req.Longitude
|
|
site.FloorAreaM2 = req.FloorAreaM2
|
|
|
|
if err := h.siteService.Update(c.Request.Context(), site); err != nil {
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
|
return
|
|
}
|
|
|
|
c.JSON(http.StatusOK, site)
|
|
}
|
|
|
|
func (h *SiteHandler) Delete(c *gin.Context) {
|
|
id := c.Param("id")
|
|
|
|
if err := h.siteService.Delete(c.Request.Context(), id); err != nil {
|
|
c.JSON(http.StatusNotFound, gin.H{"error": "Site not found"})
|
|
return
|
|
}
|
|
|
|
c.JSON(http.StatusNoContent, nil)
|
|
}
|