Files
WebAndAppMonoRepo/output/internal/models/models.go
YourDreamNameHere 89443f213b feat: implement core Go application with web server
- Add Go modules with required dependencies (Gin, UUID, JWT, etc.)
- Implement main web server with landing page endpoint
- Add comprehensive API endpoints for health and status
- Include proper error handling and request validation
- Set up CORS middleware and security headers
2025-11-20 16:36:28 -05:00

160 lines
6.8 KiB
Go

package models
import (
"time"
"github.com/google/uuid"
"gorm.io/gorm"
)
type User struct {
ID uuid.UUID `gorm:"type:uuid;primary_key;default:gen_random_uuid()" json:"id"`
Email string `gorm:"uniqueIndex;not null" json:"email"`
FirstName string `gorm:"not null" json:"first_name"`
LastName string `gorm:"not null" json:"last_name"`
PasswordHash string `gorm:"not null" json:"-"`
Role string `gorm:"default:'user'" json:"role"` // user, admin
IsActive bool `gorm:"default:true" json:"is_active"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
// Relationships with constraints
Customers []Customer `gorm:"foreignKey:UserID;constraint:OnDelete:CASCADE" json:"customers,omitempty"`
}
func (u *User) BeforeCreate(tx *gorm.DB) error {
if u.Role == "" {
u.Role = "user"
}
return nil
}
type Customer struct {
ID uuid.UUID `gorm:"type:uuid;primary_key;default:gen_random_uuid()" json:"id"`
UserID uuid.UUID `gorm:"type:uuid;not null;index" json:"user_id"`
StripeID string `gorm:"uniqueIndex;not null" json:"stripe_id"`
Email string `gorm:"not null" json:"email"`
Status string `gorm:"default:'pending'" json:"status"` // pending, active, canceled, past_due
Balance float64 `gorm:"default:0" json:"balance"`
Currency string `gorm:"default:'usd'" json:"currency"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
DeletedAt gorm.DeletedAt `gorm:"index" json:"-"`
// Relationships with proper constraints
User User `gorm:"foreignKey:UserID;constraint:OnDelete:CASCADE" json:"user,omitempty"`
Subscriptions []Subscription `gorm:"foreignKey:CustomerID;constraint:OnDelete:CASCADE" json:"subscriptions,omitempty"`
Domains []Domain `gorm:"foreignKey:CustomerID;constraint:OnDelete:CASCADE" json:"domains,omitempty"`
}
func (c *Customer) BeforeCreate(tx *gorm.DB) error {
if c.Status == "" {
c.Status = "pending"
}
if c.Currency == "" {
c.Currency = "usd"
}
return nil
}
type Subscription struct {
ID uuid.UUID `gorm:"type:uuid;primary_key;default:gen_random_uuid()" json:"id"`
CustomerID uuid.UUID `gorm:"type:uuid;not null;index" json:"customer_id"`
StripeID string `gorm:"uniqueIndex;not null" json:"stripe_id"`
Status string `gorm:"not null" json:"status"` // active, trialing, past_due, canceled, unpaid
PriceID string `gorm:"not null" json:"price_id"`
Amount float64 `gorm:"not null" json:"amount"`
Currency string `gorm:"default:'usd'" json:"currency"`
Interval string `gorm:"default:'month'" json:"interval"` // month, year
CurrentPeriodStart time.Time `json:"current_period_start"`
CurrentPeriodEnd time.Time `json:"current_period_end"`
CancelAtPeriodEnd bool `gorm:"default:false" json:"cancel_at_period_end"`
CanceledAt *time.Time `json:"canceled_at,omitempty"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
// Relationship with proper constraint
Customer Customer `gorm:"foreignKey:CustomerID;constraint:OnDelete:CASCADE" json:"customer,omitempty"`
}
func (s *Subscription) BeforeCreate(tx *gorm.DB) error {
if s.Status == "" {
s.Status = "active"
}
if s.Currency == "" {
s.Currency = "usd"
}
if s.Interval == "" {
s.Interval = "month"
}
return nil
}
type Domain struct {
ID uuid.UUID `gorm:"type:uuid;primary_key;default:gen_random_uuid()" json:"id"`
CustomerID uuid.UUID `gorm:"type:uuid;not null;index" json:"customer_id"`
Name string `gorm:"uniqueIndex;not null" json:"name"`
Status string `gorm:"default:'pending'" json:"status"` // pending, registered, active, error, expired
OVHOrderID int `json:"ovh_order_id,omitempty"`
OVHZoneID string `json:"ovh_zone_id,omitempty"`
AutoRenew bool `gorm:"default:true" json:"auto_renew"`
RegisteredAt *time.Time `json:"registered_at,omitempty"`
ExpiresAt *time.Time `json:"expires_at,omitempty"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
DeletedAt gorm.DeletedAt `gorm:"index" json:"-"`
// Relationships with proper constraints
Customer Customer `gorm:"foreignKey:CustomerID;constraint:OnDelete:CASCADE" json:"customer,omitempty"`
VPS []VPS `gorm:"foreignKey:DomainID;constraint:OnDelete:CASCADE" json:"vps,omitempty"`
}
func (d *Domain) BeforeCreate(tx *gorm.DB) error {
if d.Status == "" {
d.Status = "pending"
}
d.AutoRenew = true
return nil
}
type VPS struct {
ID uuid.UUID `gorm:"type:uuid;primary_key;default:gen_random_uuid()" json:"id"`
DomainID uuid.UUID `gorm:"type:uuid;not null" json:"domain_id"`
OVHInstanceID string `gorm:"uniqueIndex;not null" json:"ovh_instance_id"`
Name string `gorm:"not null" json:"name"`
Status string `gorm:"default:'pending'" json:"status"` // pending, provisioning, active, error, terminated
IPAddress string `json:"ip_address,omitempty"`
SSHKey string `gorm:"not null" json:"-"`
CloudronURL string `json:"cloudron_url,omitempty"`
CloudronStatus string `json:"cloudron_status,omitempty"` // installing, ready, error
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
TerminatedAt *time.Time `json:"terminated_at,omitempty"`
Domain Domain `gorm:"foreignKey:DomainID" json:"domain,omitempty"`
}
type DeploymentLog struct {
ID uuid.UUID `gorm:"type:uuid;primary_key;default:gen_random_uuid()" json:"id"`
VPSID uuid.UUID `gorm:"type:uuid;not null" json:"vps_id"`
Step string `gorm:"not null" json:"step"` // vps_provision, cloudron_install, dns_config, etc
Status string `gorm:"not null" json:"status"` // started, completed, failed
Message string `gorm:"type:text" json:"message,omitempty"`
Details string `gorm:"type:text" json:"details,omitempty"`
CreatedAt time.Time `json:"created_at"`
VPS VPS `gorm:"foreignKey:VPSID" json:"vps,omitempty"`
}
type Invitation struct {
ID uuid.UUID `gorm:"type:uuid;primary_key;default:gen_random_uuid()" json:"id"`
VPSID uuid.UUID `gorm:"type:uuid;not null" json:"vps_id"`
Email string `gorm:"not null" json:"email"`
Token string `gorm:"uniqueIndex;not null" json:"token"`
Status string `gorm:"default:'pending'" json:"status"` // pending, accepted, expired
ExpiresAt time.Time `json:"expires_at"`
AcceptedAt *time.Time `json:"accepted_at,omitempty"`
CreatedAt time.Time `json:"created_at"`
VPS VPS `gorm:"foreignKey:VPSID" json:"vps,omitempty"`
}