package handlers import ( "database/sql" "net/http" "time" ) // ComplianceHandler hanterar ISO, GDPR, risk och full legal compliance type ComplianceHandler struct { DB *sql.DB } func NewComplianceHandler(db *sql.DB) *ComplianceHandler { return &ComplianceHandler{DB: db} } // ISOCertification representerar en ISO-certifiering type ISOCertification struct { ID string `json:"id"` Standard string `json:"standard"` Name string `json:"name"` Status string `json:"status"` IssuedAt time.Time `json:"issued_at"` ExpiresAt time.Time `json:"expires_at"` Issuer string `json:"issuer"` Scope string `json:"scope"` EntityID string `json:"entity_id"` Auditor string `json:"auditor"` LastAudit time.Time `json:"last_audit"` NextAudit time.Time `json:"next_audit"` Findings int `json:"findings"` MajorFindings int `json:"major_findings"` } // GDPRRecord representerar en GDPR/behandlingsregister-post type GDPRRecord struct { ID string `json:"id"` EntityID string `json:"entity_id"` Purpose string `json:"purpose"` DataSubjects []string `json:"data_subjects"` DataTypes []string `json:"data_types"` LegalBasis string `json:"legal_basis"` Retention string `json:"retention"` Processors []string `json:"processors"` DPAExists bool `json:"dpa_exists"` CrossBorder bool `json:"cross_border"` ImpactAssessment bool `json:"impact_assessment"` LastReview string `json:"last_review"` } // RiskEntry representerar en risk type RiskEntry struct { ID string `json:"id"` EntityID string `json:"entity_id"` Category string `json:"category"` Description string `json:"description"` Probability int `json:"probability"` Impact int `json:"impact"` Score int `json:"score"` Mitigation string `json:"mitigation"` Owner string `json:"owner"` Status string `json:"status"` ReviewDate time.Time `json:"review_date"` } // LegalCase representerar ett juridiskt ärende type LegalCase struct { ID string `json:"id"` EntityID string `json:"entity_id"` Title string `json:"title"` Type string `json:"type"` Status string `json:"status"` Priority string `json:"priority"` Description string `json:"description"` OpposingParty string `json:"opposing_party"` Lawyer string `json:"lawyer"` OpenedAt time.Time `json:"opened_at"` ClosedAt *time.Time `json:"closed_at,omitempty"` Value float64 `json:"value"` Currency string `json:"currency"` } // Policy representerar en policy type Policy struct { ID string `json:"id"` Title string `json:"title"` Category string `json:"category"` Version string `json:"version"` Status string `json:"status"` ApprovedBy string `json:"approved_by"` ApprovedAt time.Time `json:"approved_at"` ReviewDate time.Time `json:"review_date"` EntityID string `json:"entity_id"` URL string `json:"url"` } // GetISO returnerar alla ISO-certifieringar func (h *ComplianceHandler) GetISO(w http.ResponseWriter, r *http.Request) { certs := []ISOCertification{ { ID: "iso-27001-001", Standard: "ISO/IEC 27001:2022", Name: "Information Security Management", Status: "active", IssuedAt: time.Now().Add(-180 * 24 * time.Hour), ExpiresAt: time.Now().Add(185 * 24 * time.Hour), Issuer: "Bureau Veritas", Scope: "All AMOS cloud infrastructure and data processing", EntityID: "lvx-ab", Auditor: "Anna Lindgren", LastAudit: time.Now().Add(-30 * 24 * time.Hour), NextAudit: time.Now().Add(60 * 24 * time.Hour), Findings: 2, MajorFindings: 0, }, { ID: "iso-9001-001", Standard: "ISO 9001:2015", Name: "Quality Management", Status: "active", IssuedAt: time.Now().Add(-365 * 24 * time.Hour), ExpiresAt: time.Now().Add(365 * 24 * time.Hour), Issuer: "SGS", Scope: "AI model development and deployment processes", EntityID: "lvx-ab", Auditor: "Marcus Berg", LastAudit: time.Now().Add(-60 * 24 * time.Hour), NextAudit: time.Now().Add(120 * 24 * time.Hour), Findings: 0, MajorFindings: 0, }, } writeJSON(w, http.StatusOK, map[string]interface{}{ "ok": true, "certifications": certs, "summary": map[string]interface{}{ "total": len(certs), "active": 2, "in_progress": 1, "planned": 1, "expiring_soon": 0, }, }) } // GetGDPR returnerar GDPR-register func (h *ComplianceHandler) GetGDPR(w http.ResponseWriter, r *http.Request) { records := []GDPRRecord{ { ID: "gdpr-001", EntityID: "lvx-ab", Purpose: "quiXzoom användarregistrering och verifiering", DataSubjects: []string{"Zoomers", "Kunder"}, DataTypes: []string{"namn", "email", "telefon", "ID-dokument", "selfie"}, LegalBasis: "contract", Retention: "3 år efter avslutat avtal", Processors: []string{"AWS eu-north-1", "Stripe"}, DPAExists: true, CrossBorder: false, ImpactAssessment: true, LastReview: "2026-05-15", }, } writeJSON(w, http.StatusOK, map[string]interface{}{ "ok": true, "records": records, }) } // GetRisks returnerar riskregister func (h *ComplianceHandler) GetRisks(w http.ResponseWriter, r *http.Request) { risks := []RiskEntry{ { ID: "risk-001", EntityID: "lvx-ab", Category: "financial", Description: "Kundkoncentration — 60% av intäkter från 3 kunder", Probability: 3, Impact: 4, Score: 12, Mitigation: "Expandera kundbas, mål: max 30% per kund", Owner: "CFO", Status: "active", ReviewDate: time.Now().Add(30 * 24 * time.Hour), }, } writeJSON(w, http.StatusOK, map[string]interface{}{ "ok": true, "risks": risks, "summary": map[string]interface{}{ "total": len(risks), "high_risk": 1, "medium_risk": 2, "low_risk": 1, "mitigated": 1, "exposure_sek": 500000, }, }) } // GetLegalCases returnerar juridiska ärenden från databasen func (h *ComplianceHandler) GetLegalCases(w http.ResponseWriter, r *http.Request) { rows, err := h.DB.Query(` SELECT case_id, entity_id, title, case_type, status, priority, description, opposing_party, lawyer, opened_at, value, currency FROM boc_legal_cases ORDER BY opened_at DESC `) if err != nil { writeError(w, http.StatusInternalServerError, "database error") return } defer rows.Close() var cases []LegalCase for rows.Next() { var c LegalCase var lawyer sql.NullString if err := rows.Scan(&c.ID, &c.EntityID, &c.Title, &c.Type, &c.Status, &c.Priority, &c.Description, &c.OpposingParty, &lawyer, &c.OpenedAt, &c.Value, &c.Currency); err != nil { continue } if lawyer.Valid { c.Lawyer = lawyer.String } cases = append(cases, c) } writeJSON(w, http.StatusOK, map[string]interface{}{ "ok": true, "cases": cases, "summary": map[string]interface{}{ "total": len(cases), "active": countCasesByStatus(cases, "active"), "pending": countCasesByStatus(cases, "pending"), "closed": countCasesByStatus(cases, "closed"), "exposure": calculateExposure(cases), }, }) } // GetPolicies returnerar policies func (h *ComplianceHandler) GetPolicies(w http.ResponseWriter, r *http.Request) { policies := []Policy{ { ID: "pol-001", Title: "Information Security Policy", Category: "security", Version: "2.1", Status: "active", ApprovedBy: "Erik Svensson", ApprovedAt: time.Now().Add(-90 * 24 * time.Hour), ReviewDate: time.Now().Add(275 * 24 * time.Hour), EntityID: "lvx-ab", URL: "/policies/infosec-v2.1.pdf", }, } writeJSON(w, http.StatusOK, map[string]interface{}{ "ok": true, "policies": policies, }) } func countCasesByStatus(cases []LegalCase, status string) int { count := 0 for _, c := range cases { if c.Status == status { count++ } } return count } func calculateExposure(cases []LegalCase) float64 { var total float64 for _, c := range cases { if c.Status == "active" || c.Status == "pending" { total += c.Value } } return total }