186 lines
5.0 KiB
Go
186 lines
5.0 KiB
Go
|
|
package handlers
|
||
|
|
|
||
|
|
import (
|
||
|
|
"encoding/json"
|
||
|
|
"log"
|
||
|
|
"net/http"
|
||
|
|
|
||
|
|
"github.com/patel-mann/poll-system/app/internal/models"
|
||
|
|
)
|
||
|
|
|
||
|
|
// ValidatedAddress represents a validated address with coordinates
|
||
|
|
type ValidatedAddress struct {
|
||
|
|
AddressID int `json:"address_id"`
|
||
|
|
Address string `json:"address"`
|
||
|
|
Longitude float64 `json:"longitude"`
|
||
|
|
Latitude float64 `json:"latitude"`
|
||
|
|
HouseNumber string `json:"house_number"`
|
||
|
|
StreetName string `json:"street_name"`
|
||
|
|
StreetType string `json:"street_type"`
|
||
|
|
Quadrant string `json:"street_quadrant"`
|
||
|
|
UpdatedAt string `json:"updated_at"`
|
||
|
|
}
|
||
|
|
|
||
|
|
// GetValidatedAddressesHandler returns all validated addresses with their coordinates as JSON
|
||
|
|
func GetValidatedAddressesHandler(w http.ResponseWriter, r *http.Request) {
|
||
|
|
// Only allow GET requests
|
||
|
|
if r.Method != http.MethodGet {
|
||
|
|
http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
|
||
|
|
return
|
||
|
|
}
|
||
|
|
|
||
|
|
// Optional: Check if user is authenticated (depending on your auth system)
|
||
|
|
// _, authenticated := models.GetCurrentUserName(r)
|
||
|
|
// if !authenticated {
|
||
|
|
// http.Error(w, "Unauthorized", http.StatusUnauthorized)
|
||
|
|
// return
|
||
|
|
// }
|
||
|
|
|
||
|
|
// Query validated addresses from database
|
||
|
|
addresses, err := fetchValidatedAddresses()
|
||
|
|
if err != nil {
|
||
|
|
log.Printf("Error fetching validated addresses: %v", err)
|
||
|
|
http.Error(w, "Internal server error", http.StatusInternalServerError)
|
||
|
|
return
|
||
|
|
}
|
||
|
|
|
||
|
|
// Set response headers for JSON
|
||
|
|
w.Header().Set("Content-Type", "application/json")
|
||
|
|
w.Header().Set("Access-Control-Allow-Origin", "*") // Adjust based on your CORS policy
|
||
|
|
|
||
|
|
// Encode and send JSON response
|
||
|
|
if err := json.NewEncoder(w).Encode(addresses); err != nil {
|
||
|
|
log.Printf("Error encoding JSON response: %v", err)
|
||
|
|
http.Error(w, "Error encoding response", http.StatusInternalServerError)
|
||
|
|
return
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
log.Printf("Successfully returned %d validated addresses", addresses)
|
||
|
|
}
|
||
|
|
|
||
|
|
// fetchValidatedAddresses retrieves all validated addresses from the database
|
||
|
|
func fetchValidatedAddresses() ([]ValidatedAddress, error) {
|
||
|
|
query := `
|
||
|
|
SELECT
|
||
|
|
address_id,
|
||
|
|
address,
|
||
|
|
longitude,
|
||
|
|
latitude,
|
||
|
|
COALESCE(house_number, '') as house_number,
|
||
|
|
COALESCE(street_name, '') as street_name,
|
||
|
|
COALESCE(street_type, '') as street_type,
|
||
|
|
COALESCE(street_quadrant, '') as street_quadrant,
|
||
|
|
updated_at::text
|
||
|
|
FROM address_database
|
||
|
|
WHERE visited_validated = true
|
||
|
|
AND longitude IS NOT NULL
|
||
|
|
AND latitude IS NOT NULL
|
||
|
|
AND longitude != 0
|
||
|
|
AND latitude != 0
|
||
|
|
ORDER BY updated_at DESC
|
||
|
|
`
|
||
|
|
|
||
|
|
rows, err := models.DB.Query(query)
|
||
|
|
if err != nil {
|
||
|
|
return nil, err
|
||
|
|
}
|
||
|
|
defer rows.Close()
|
||
|
|
|
||
|
|
var addresses []ValidatedAddress
|
||
|
|
for rows.Next() {
|
||
|
|
var addr ValidatedAddress
|
||
|
|
err := rows.Scan(
|
||
|
|
&addr.AddressID,
|
||
|
|
&addr.Address,
|
||
|
|
&addr.Longitude,
|
||
|
|
&addr.Latitude,
|
||
|
|
&addr.HouseNumber,
|
||
|
|
&addr.StreetName,
|
||
|
|
&addr.StreetType,
|
||
|
|
&addr.Quadrant,
|
||
|
|
&addr.UpdatedAt,
|
||
|
|
)
|
||
|
|
if err != nil {
|
||
|
|
log.Printf("Error scanning address row: %v", err)
|
||
|
|
continue
|
||
|
|
}
|
||
|
|
addresses = append(addresses, addr)
|
||
|
|
}
|
||
|
|
|
||
|
|
if err = rows.Err(); err != nil {
|
||
|
|
return nil, err
|
||
|
|
}
|
||
|
|
|
||
|
|
return addresses, nil
|
||
|
|
}
|
||
|
|
|
||
|
|
// GetValidatedAddressesStatsHandler returns statistics about validated addresses
|
||
|
|
func GetValidatedAddressesStatsHandler(w http.ResponseWriter, r *http.Request) {
|
||
|
|
if r.Method != http.MethodGet {
|
||
|
|
http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
|
||
|
|
return
|
||
|
|
}
|
||
|
|
|
||
|
|
stats, err := getValidatedAddressesStats()
|
||
|
|
if err != nil {
|
||
|
|
log.Printf("Error fetching address stats: %v", err)
|
||
|
|
http.Error(w, "Internal server error", http.StatusInternalServerError)
|
||
|
|
return
|
||
|
|
}
|
||
|
|
|
||
|
|
w.Header().Set("Content-Type", "application/json")
|
||
|
|
json.NewEncoder(w).Encode(stats)
|
||
|
|
}
|
||
|
|
|
||
|
|
// AddressStats represents statistics about addresses
|
||
|
|
type AddressStats struct {
|
||
|
|
TotalValidated int `json:"total_validated"`
|
||
|
|
TotalAddresses int `json:"total_addresses"`
|
||
|
|
ValidatedWithCoords int `json:"validated_with_coords"`
|
||
|
|
RecentlyValidated int `json:"recently_validated_24h"`
|
||
|
|
}
|
||
|
|
|
||
|
|
// getValidatedAddressesStats gets statistics about validated addresses
|
||
|
|
func getValidatedAddressesStats() (AddressStats, error) {
|
||
|
|
var stats AddressStats
|
||
|
|
|
||
|
|
// Get total validated count
|
||
|
|
err := models.DB.QueryRow("SELECT COUNT(*) FROM address_database WHERE visited_validated = true").
|
||
|
|
Scan(&stats.TotalValidated)
|
||
|
|
if err != nil {
|
||
|
|
return stats, err
|
||
|
|
}
|
||
|
|
|
||
|
|
// Get total addresses count
|
||
|
|
err = models.DB.QueryRow("SELECT COUNT(*) FROM address_database").
|
||
|
|
Scan(&stats.TotalAddresses)
|
||
|
|
if err != nil {
|
||
|
|
return stats, err
|
||
|
|
}
|
||
|
|
|
||
|
|
// Get validated with coordinates count
|
||
|
|
err = models.DB.QueryRow(`
|
||
|
|
SELECT COUNT(*) FROM address_database
|
||
|
|
WHERE visited_validated = true
|
||
|
|
AND longitude IS NOT NULL
|
||
|
|
AND latitude IS NOT NULL
|
||
|
|
AND longitude != 0
|
||
|
|
AND latitude != 0
|
||
|
|
`).Scan(&stats.ValidatedWithCoords)
|
||
|
|
if err != nil {
|
||
|
|
return stats, err
|
||
|
|
}
|
||
|
|
|
||
|
|
// Get recently validated (last 24 hours)
|
||
|
|
err = models.DB.QueryRow(`
|
||
|
|
SELECT COUNT(*) FROM address_database
|
||
|
|
WHERE visited_validated = true
|
||
|
|
AND updated_at > NOW() - INTERVAL '24 hours'
|
||
|
|
`).Scan(&stats.RecentlyValidated)
|
||
|
|
if err != nil {
|
||
|
|
return stats, err
|
||
|
|
}
|
||
|
|
|
||
|
|
return stats, nil
|
||
|
|
}
|