Files
boc/backend/handlers/crm_v2.go
T

110 lines
3.1 KiB
Go
Raw Normal View History

// Package handlers provides HTTP handlers using the generic Store pattern.
// This replaces the old CRMHandler with a generic implementation.
package handlers
import (
"database/sql"
"encoding/json"
"net/http"
"github.com/go-chi/chi/v5"
"github.com/lib/pq"
"boc/models"
"boc/store"
)
// CRMHandlerV2 uses the generic Store for customers
type CRMHandlerV2 struct {
customers *store.Store[*models.Customer]
db *store.DB
}
// NewCRMHandlerV2 creates a new CRM handler using generic store
func NewCRMHandlerV2(db *store.DB) *CRMHandlerV2 {
cols := []string{"id", "name", "email", "phone", "company", "org_number", "status", "source", "tags", "assigned_to", "created_at", "updated_at"}
return &CRMHandlerV2{
customers: store.NewStore(db, "boc_customers", cols,
func(rows *sql.Rows) (*models.Customer, error) {
c := &models.Customer{}
err := c.ScanRow(rows)
return c, err
},
func(row *sql.Row) (*models.Customer, error) {
c := &models.Customer{}
err := c.ScanOneRow(row)
return c, err
},
),
db: db,
}
}
// ListCustomers handles GET /api/v1/crm/customers
func (h *CRMHandlerV2) ListCustomers(w http.ResponseWriter, r *http.Request) {
status := r.URL.Query().Get("status")
if status == "" {
status = "active"
}
customers, err := h.customers.List(r.Context(), "status = $1", status)
if err != nil {
writeError(w, http.StatusInternalServerError, "database error")
return
}
writeJSON(w, http.StatusOK, map[string]interface{}{
"customers": customers,
"total": len(customers),
})
}
// GetCustomer handles GET /api/v1/crm/customers/{id}
func (h *CRMHandlerV2) GetCustomer(w http.ResponseWriter, r *http.Request) {
id := chi.URLParam(r, "id")
customer, err := h.customers.Get(r.Context(), id)
if err != nil {
writeError(w, http.StatusNotFound, "customer not found")
return
}
writeJSON(w, http.StatusOK, customer)
}
// CreateCustomer handles POST /api/v1/crm/customers
func (h *CRMHandlerV2) CreateCustomer(w http.ResponseWriter, r *http.Request) {
var req models.Customer
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
writeError(w, http.StatusBadRequest, "invalid request")
return
}
var id string
err := h.db.QueryRowContext(r.Context(), `
INSERT INTO boc_customers (name, email, phone, company, org_number, status, source, tags)
VALUES ($1, $2, $3, $4, $5, $6, $7, $8)
RETURNING id
`, req.Name, req.Email, req.Phone, req.Company, req.OrgNumber, req.Status, req.Source, pq.Array(req.Tags)).Scan(&id)
if err != nil {
writeError(w, http.StatusInternalServerError, "failed to create customer")
return
}
writeJSON(w, http.StatusCreated, map[string]interface{}{
"id": id,
"message": "Customer created",
})
}
// DeleteCustomer handles DELETE /api/v1/crm/customers/{id}
func (h *CRMHandlerV2) DeleteCustomer(w http.ResponseWriter, r *http.Request) {
id := chi.URLParam(r, "id")
if err := h.customers.Delete(r.Context(), id); err != nil {
writeError(w, http.StatusInternalServerError, "failed to delete customer")
return
}
writeJSON(w, http.StatusOK, map[string]interface{}{
"message": "Customer deleted",
})
}