package handlers import ( "database/sql" "net/http" "time" "github.com/go-chi/chi/v5" ) // LandvexHandler hanterar Landvex bolagskontroll type LandvexHandler struct { DB *sql.DB } // NewLandvexHandler skapar en ny handler func NewLandvexHandler(db *sql.DB) *LandvexHandler { return &LandvexHandler{DB: db} } // Entity representerar en juridisk enhet type Entity struct { ID string `json:"id"` Name string `json:"name"` Type string `json:"type"` OrgNumber string `json:"org_number"` Country string `json:"country"` City string `json:"city"` Address string `json:"address"` Status string `json:"status"` FoundedAt time.Time `json:"founded_at"` ParentID *string `json:"parent_id,omitempty"` Ownership float64 `json:"ownership_percent"` CEO string `json:"ceo"` BoardMembers []Person `json:"board_members"` Employees int `json:"employees"` Revenue float64 `json:"revenue"` Currency string `json:"currency"` TaxStatus string `json:"tax_status"` ComplianceStatus string `json:"compliance_status"` } // Person representerar en person type Person struct { ID string `json:"id"` Name string `json:"name"` Role string `json:"role"` Email string `json:"email"` Phone string `json:"phone"` Nationality string `json:"nationality"` Since string `json:"since"` } // Document representerar ett dokument type Document struct { ID string `json:"id"` Title string `json:"title"` Type string `json:"type"` EntityID string `json:"entity_id"` Status string `json:"status"` CreatedAt time.Time `json:"created_at"` ExpiresAt *time.Time `json:"expires_at,omitempty"` SignedBy []string `json:"signed_by"` URL string `json:"url"` } // ComplianceItem representerar ett compliance-krav type ComplianceItem struct { ID string `json:"id"` EntityID string `json:"entity_id"` Title string `json:"title"` Type string `json:"type"` Status string `json:"status"` DueDate time.Time `json:"due_date"` CompletedAt *time.Time `json:"completed_at,omitempty"` Responsible string `json:"responsible"` Priority string `json:"priority"` } // GetEntities returnerar alla Landvex-enheter från databasen func (h *LandvexHandler) GetEntities(w http.ResponseWriter, r *http.Request) { rows, err := h.DB.Query(` SELECT entity_id, name, jurisdiction, entity_type, status FROM boc_landvex_entities WHERE status = 'active' ORDER BY name `) if err != nil { writeError(w, http.StatusInternalServerError, "database error") return } defer rows.Close() var entities []Entity for rows.Next() { var e Entity if err := rows.Scan(&e.ID, &e.Name, &e.Country, &e.Type, &e.Status); err != nil { continue } entities = append(entities, e) } writeJSON(w, http.StatusOK, map[string]interface{}{ "ok": true, "entities": entities, }) } // GetEntity returnerar en specifik enhet func (h *LandvexHandler) GetEntity(w http.ResponseWriter, r *http.Request) { entityID := chi.URLParam(r, "id") var e Entity err := h.DB.QueryRow(` SELECT entity_id, name, jurisdiction, entity_type, status FROM boc_landvex_entities WHERE entity_id = $1 `, entityID).Scan(&e.ID, &e.Name, &e.Country, &e.Type, &e.Status) if err != nil { writeError(w, http.StatusNotFound, "entity not found") return } writeJSON(w, http.StatusOK, map[string]interface{}{ "ok": true, "entity": e, }) } // GetDocuments returnerar alla dokument func (h *LandvexHandler) GetDocuments(w http.ResponseWriter, r *http.Request) { documents := []Document{ { ID: "doc-001", Title: "Styrelseprotokoll 2026-01-15", Type: "board_minutes", EntityID: "lvx-ab", Status: "signed", CreatedAt: time.Now().Add(-180 * 24 * time.Hour), SignedBy: []string{"Erik Svensson", "Johan Berglund"}, URL: "/docs/board-2026-01-15.pdf", }, } writeJSON(w, http.StatusOK, map[string]interface{}{ "ok": true, "documents": documents, }) } // GetCompliance returnerar compliance-krav från databasen func (h *LandvexHandler) GetCompliance(w http.ResponseWriter, r *http.Request) { rows, err := h.DB.Query(` SELECT id, entity_id, category, title, status, due_date, completed_at, notes FROM boc_landvex_compliance ORDER BY due_date ASC `) if err != nil { writeError(w, http.StatusInternalServerError, "database error") return } defer rows.Close() var items []ComplianceItem for rows.Next() { var c ComplianceItem var notes sql.NullString if err := rows.Scan(&c.ID, &c.EntityID, &c.Type, &c.Title, &c.Status, &c.DueDate, &c.CompletedAt, ¬es); err != nil { continue } items = append(items, c) } writeJSON(w, http.StatusOK, map[string]interface{}{ "ok": true, "compliance_items": items, "summary": map[string]interface{}{ "total": len(items), "pending": countByStatus(items, "pending"), "overdue": countByStatus(items, "overdue"), "completed": countByStatus(items, "completed"), "this_quarter": len(items), }, }) } // GetOwnership returnerar ägarstruktur från databasen func (h *LandvexHandler) GetOwnership(w http.ResponseWriter, r *http.Request) { rows, err := h.DB.Query(` SELECT e.entity_id, e.name, e.jurisdiction, e.entity_type, o.owner_name, o.ownership_percent, o.parent_entity_id FROM boc_landvex_entities e LEFT JOIN boc_landvex_ownership o ON e.entity_id = o.entity_id WHERE e.status = 'active' ORDER BY e.name `) if err != nil { writeError(w, http.StatusInternalServerError, "database error") return } defer rows.Close() var entities []map[string]interface{} for rows.Next() { var entityID, name, jurisdiction, entityType, ownerName string var ownership float64 var parentID sql.NullString if err := rows.Scan(&entityID, &name, &jurisdiction, &entityType, &ownerName, &ownership, &parentID); err != nil { continue } entities = append(entities, map[string]interface{}{ "id": entityID, "name": name, "jurisdiction": jurisdiction, "type": entityType, "owner": ownerName, "ownership": ownership, }) } writeJSON(w, http.StatusOK, map[string]interface{}{ "ok": true, "ownership": map[string]interface{}{ "structure": "linear", "ultimate_beneficial_owner": map[string]interface{}{ "name": "Erik Svensson", "nationality": "SE", "ownership": 100, }, "entities": entities, }, }) } func countByStatus(items []ComplianceItem, status string) int { count := 0 for _, item := range items { if item.Status == status { count++ } } return count } func strPtr(s string) *string { return &s }