package models import ( "encoding/json" "github.com/sujit-baniya/fiber-boilerplate/app" "gorm.io/gorm" ) // LandingSession representa una sesión de generación de landing page. // Cada sesión tiene un token único que se usa como URL pública de preview. type LandingSession struct { gorm.Model Token string `json:"token" gorm:"column:token;uniqueIndex;not null"` UserName string `json:"user_name" gorm:"column:user_name"` UserEmail string `json:"user_email" gorm:"column:user_email"` UserPhone string `json:"user_phone" gorm:"column:user_phone"` UserCompany string `json:"user_company" gorm:"column:user_company"` UserJob string `json:"user_job" gorm:"column:user_job"` UserWebsite string `json:"user_website" gorm:"column:user_website"` UserAddress string `json:"user_address" gorm:"column:user_address"` SocialMedia string `json:"social_media" gorm:"column:social_media"` LogoUrl string `json:"logo_url" gorm:"column:logo_url"` // Historial de mensajes almacenado como JSON AnswersJSON string `json:"-" gorm:"column:answers_json;type:text"` HTMLContent string `json:"html_content,omitempty" gorm:"column:html_content;type:text"` // status: in_progress | generated | paid | expired Status string `json:"status" gorm:"column:status;default:'in_progress'"` BoldLinkID string `json:"bold_link_id" gorm:"column:bold_link_id"` BoldPaid bool `json:"bold_paid" gorm:"column:bold_paid;default:false"` BoldPaymentID string `json:"bold_payment_id" gorm:"column:bold_payment_id"` PriceCOP int64 `json:"price_cop" gorm:"column:price_cop;default:49900"` VcardIncluded bool `json:"vcard_included" gorm:"column:vcard_included;default:false"` } func (LandingSession) TableName() string { return "landing_sessions" } // LandingMessage es un mensaje del chat (serializado en AnswersJSON). type LandingMessage struct { Role string `json:"role"` // "assistant" | "user" Content string `json:"content"` } // GetAnswers deserializa el historial de mensajes. func (s *LandingSession) GetAnswers() []LandingMessage { var msgs []LandingMessage if s.AnswersJSON == "" { return msgs } _ = json.Unmarshal([]byte(s.AnswersJSON), &msgs) return msgs } // SetAnswers serializa el historial de mensajes. func (s *LandingSession) SetAnswers(msgs []LandingMessage) { b, _ := json.Marshal(msgs) s.AnswersJSON = string(b) } // ─── CRUD ───────────────────────────────────────────────────────────────────── func CreateLandingSession(token, firstQuestion string) (*LandingSession, error) { msgs := []LandingMessage{{Role: "assistant", Content: firstQuestion}} b, _ := json.Marshal(msgs) s := &LandingSession{ Token: token, Status: "in_progress", AnswersJSON: string(b), } if err := app.Http.Database.DB.Create(s).Error; err != nil { return nil, err } return s, nil } func GetLandingSessionByToken(token string) (*LandingSession, error) { var s LandingSession if err := app.Http.Database.DB.Where("token = ?", token).First(&s).Error; err != nil { return nil, err } return &s, nil } func UpdateLandingSession(s *LandingSession) error { return app.Http.Database.DB.Save(s).Error } // GetAllLandingSessions devuelve sesiones paginadas para el panel admin. func GetAllLandingSessions(limit, offset int, status string) ([]LandingSession, int64, error) { var items []LandingSession var total int64 q := app.Http.Database.DB.Model(&LandingSession{}) if status != "" { q = q.Where("status = ?", status) } if err := q.Count(&total).Error; err != nil { return nil, 0, err } if err := q.Order("created_at DESC").Limit(limit).Offset(offset).Find(&items).Error; err != nil { return nil, 0, err } return items, total, nil }