package handlers import ( "context" "net/http" "time" "github.com/breakpilot/consent-service/internal/middleware" "github.com/breakpilot/consent-service/internal/models" "github.com/gin-gonic/gin" "github.com/google/uuid" ) // ======================================== // GDPR / DATA SUBJECT RIGHTS // ======================================== // GetMyData returns all data we have about the user func (h *Handler) GetMyData(c *gin.Context) { userID, err := middleware.GetUserID(c) if err != nil || userID == uuid.Nil { c.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid user"}) return } ctx := context.Background() ipAddress := middleware.GetClientIP(c) userAgent := middleware.GetUserAgent(c) // Get user info var user models.User err = h.db.Pool.QueryRow(ctx, ` SELECT id, external_id, email, role, created_at, updated_at FROM users WHERE id = $1 `, userID).Scan(&user.ID, &user.ExternalID, &user.Email, &user.Role, &user.CreatedAt, &user.UpdatedAt) // Get consents consentRows, _ := h.db.Pool.Query(ctx, ` SELECT uc.consented, uc.consented_at, ld.type, ld.name, dv.version FROM user_consents uc JOIN document_versions dv ON uc.document_version_id = dv.id JOIN legal_documents ld ON dv.document_id = ld.id WHERE uc.user_id = $1 `, userID) defer consentRows.Close() var consents []map[string]interface{} for consentRows.Next() { var consented bool var consentedAt time.Time var docType, docName, version string consentRows.Scan(&consented, &consentedAt, &docType, &docName, &version) consents = append(consents, map[string]interface{}{ "document_type": docType, "document_name": docName, "version": version, "consented": consented, "consented_at": consentedAt, }) } // Get cookie consents cookieRows, _ := h.db.Pool.Query(ctx, ` SELECT cat.name, cc.consented, cc.updated_at FROM cookie_consents cc JOIN cookie_categories cat ON cc.category_id = cat.id WHERE cc.user_id = $1 `, userID) defer cookieRows.Close() var cookieConsents []map[string]interface{} for cookieRows.Next() { var name string var consented bool var updatedAt time.Time cookieRows.Scan(&name, &consented, &updatedAt) cookieConsents = append(cookieConsents, map[string]interface{}{ "category": name, "consented": consented, "updated_at": updatedAt, }) } // Log data access h.logAudit(ctx, &userID, "data_access", "user", &userID, nil, ipAddress, userAgent) c.JSON(http.StatusOK, gin.H{ "user": map[string]interface{}{ "id": user.ID, "email": user.Email, "created_at": user.CreatedAt, }, "consents": consents, "cookie_consents": cookieConsents, "exported_at": time.Now(), }) } // RequestDataExport creates a data export request func (h *Handler) RequestDataExport(c *gin.Context) { userID, err := middleware.GetUserID(c) if err != nil || userID == uuid.Nil { c.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid user"}) return } ctx := context.Background() ipAddress := middleware.GetClientIP(c) userAgent := middleware.GetUserAgent(c) var requestID uuid.UUID err = h.db.Pool.QueryRow(ctx, ` INSERT INTO data_export_requests (user_id, status) VALUES ($1, 'pending') RETURNING id `, userID).Scan(&requestID) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to create export request"}) return } // Log to audit trail h.logAudit(ctx, &userID, "data_export_requested", "export_request", &requestID, nil, ipAddress, userAgent) c.JSON(http.StatusAccepted, gin.H{ "message": "Export request created. You will be notified when ready.", "request_id": requestID, }) } // RequestDataDeletion creates a data deletion request func (h *Handler) RequestDataDeletion(c *gin.Context) { userID, err := middleware.GetUserID(c) if err != nil || userID == uuid.Nil { c.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid user"}) return } var req struct { Reason string `json:"reason"` } c.ShouldBindJSON(&req) ctx := context.Background() ipAddress := middleware.GetClientIP(c) userAgent := middleware.GetUserAgent(c) var requestID uuid.UUID err = h.db.Pool.QueryRow(ctx, ` INSERT INTO data_deletion_requests (user_id, status, reason) VALUES ($1, 'pending', $2) RETURNING id `, userID, req.Reason).Scan(&requestID) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to create deletion request"}) return } // Log to audit trail h.logAudit(ctx, &userID, "data_deletion_requested", "deletion_request", &requestID, nil, ipAddress, userAgent) c.JSON(http.StatusAccepted, gin.H{ "message": "Deletion request created. We will process your request within 30 days.", "request_id": requestID, }) }