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)
107 lines
3.0 KiB
Go
107 lines
3.0 KiB
Go
package handler
|
|
|
|
import (
|
|
"bugulma/backend/internal/service"
|
|
"net/http"
|
|
"strconv"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
)
|
|
|
|
// GeospatialHandler handles geospatial queries
|
|
type GeospatialHandler struct {
|
|
service *service.GeospatialService
|
|
}
|
|
|
|
// NewGeospatialHandler creates a new geospatial handler
|
|
func NewGeospatialHandler(service *service.GeospatialService) *GeospatialHandler {
|
|
return &GeospatialHandler{service: service}
|
|
}
|
|
|
|
// FindNearbySites finds sites within a radius
|
|
// @Summary Find nearby sites
|
|
// @Tags geospatial
|
|
// @Produce json
|
|
// @Param lat query float64 true "Latitude"
|
|
// @Param lng query float64 true "Longitude"
|
|
// @Param radius query float64 false "Radius in kilometers" default(5.0)
|
|
// @Param limit query int false "Maximum results" default(50)
|
|
// @Success 200 {array} service.SpatialResult
|
|
// @Router /api/geospatial/nearby-sites [get]
|
|
func (h *GeospatialHandler) FindNearbySites(c *gin.Context) {
|
|
latStr := c.Query("lat")
|
|
lngStr := c.Query("lng")
|
|
radiusStr := c.DefaultQuery("radius", "5.0")
|
|
limitStr := c.DefaultQuery("limit", "50")
|
|
|
|
lat, err := strconv.ParseFloat(latStr, 64)
|
|
if err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid latitude"})
|
|
return
|
|
}
|
|
|
|
lng, err := strconv.ParseFloat(lngStr, 64)
|
|
if err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid longitude"})
|
|
return
|
|
}
|
|
|
|
radius, _ := strconv.ParseFloat(radiusStr, 64)
|
|
limit, _ := strconv.Atoi(limitStr)
|
|
|
|
query := service.SpatialQuery{
|
|
CenterLat: lat,
|
|
CenterLng: lng,
|
|
RadiusKm: radius,
|
|
MaxResults: limit,
|
|
}
|
|
|
|
results, err := h.service.FindNearbySites(c.Request.Context(), query)
|
|
if err != nil {
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
|
return
|
|
}
|
|
|
|
c.JSON(http.StatusOK, results)
|
|
}
|
|
|
|
// GetSpatialStatistics returns spatial statistics
|
|
// @Summary Get spatial statistics
|
|
// @Tags geospatial
|
|
// @Produce json
|
|
// @Success 200 {object} map[string]interface{}
|
|
// @Router /api/geospatial/statistics [get]
|
|
func (h *GeospatialHandler) GetSpatialStatistics(c *gin.Context) {
|
|
stats, err := h.service.GetSpatialStatistics(c.Request.Context())
|
|
if err != nil {
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
|
return
|
|
}
|
|
|
|
c.JSON(http.StatusOK, stats)
|
|
}
|
|
|
|
// GetSpatialClusters finds spatial clusters of sites
|
|
// @Summary Get spatial clusters
|
|
// @Tags geospatial
|
|
// @Produce json
|
|
// @Param min_points query int false "Minimum points per cluster" default(3)
|
|
// @Param radius_km query float64 false "Cluster radius in km" default(1.0)
|
|
// @Success 200 {array} service.SpatialCluster
|
|
// @Router /api/geospatial/clusters [get]
|
|
func (h *GeospatialHandler) GetSpatialClusters(c *gin.Context) {
|
|
minPointsStr := c.DefaultQuery("min_points", "3")
|
|
radiusStr := c.DefaultQuery("radius_km", "1.0")
|
|
|
|
minPoints, _ := strconv.Atoi(minPointsStr)
|
|
radius, _ := strconv.ParseFloat(radiusStr, 64)
|
|
|
|
clusters, err := h.service.FindSpatialClusters(c.Request.Context(), minPoints, radius)
|
|
if err != nil {
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
|
return
|
|
}
|
|
|
|
c.JSON(http.StatusOK, clusters)
|
|
}
|