package models import ( "time" "github.com/google/uuid" ) // Tenant represents a tenant in the multi-tenant system type Tenant struct { ID uuid.UUID `json:"id" gorm:"type:uuid;primary_key;default:uuid_generate_v4()"` Name string `json:"name" gorm:"not null"` Slug string `json:"slug" gorm:"unique;not null"` Description string `json:"description"` LogoURL string `json:"logo_url"` CreatedAt time.Time `json:"created_at"` UpdatedAt time.Time `json:"updated_at"` IsActive bool `json:"is_active" gorm:"default:true"` } // User represents a user in the system type User struct { ID uuid.UUID `json:"id" gorm:"type:uuid;primary_key;default:uuid_generate_v4()"` TenantID uuid.UUID `json:"tenant_id" gorm:"type:uuid;index"` Tenant Tenant `json:"tenant" gorm:"foreignKey:TenantID"` Email string `json:"email" gorm:"uniqueIndex;not null"` Username string `json:"username" gorm:"uniqueIndex"` FirstName string `json:"first_name"` LastName string `json:"last_name"` Phone string `json:"phone"` Role string `json:"role" gorm:"default:job_seeker"` // job_seeker, job_provider, admin PasswordHash string `json:"-"` // Never return password hash in JSON responses IsActive bool `json:"is_active" gorm:"default:true"` EmailVerified bool `json:"email_verified" gorm:"default:false"` CreatedAt time.Time `json:"created_at"` UpdatedAt time.Time `json:"updated_at"` LastLogin *time.Time `json:"last_login,omitempty"` // Associations OIDCIdentities []OIDCIdentity `json:"-" gorm:"foreignKey:UserID"` SocialIdentities []SocialIdentity `json:"-" gorm:"foreignKey:UserID"` Positions []JobPosition `json:"-" gorm:"foreignKey:UserID"` Applications []Application `json:"-" gorm:"foreignKey:UserID"` Resumes []Resume `json:"-" gorm:"foreignKey:UserID"` } // OIDCIdentity represents an OIDC authentication identity type OIDCIdentity struct { ID uuid.UUID `json:"id" gorm:"type:uuid;primary_key;default:uuid_generate_v4()"` UserID uuid.UUID `json:"user_id" gorm:"type:uuid;index"` User User `json:"-" gorm:"foreignKey:UserID"` ProviderName string `json:"provider_name"` ProviderSubject string `json:"provider_subject"` ProviderData string `json:"-" gorm:"type:jsonb"` // Store provider-specific user data as JSON CreatedAt time.Time `json:"created_at"` } // SocialIdentity represents a social media authentication identity type SocialIdentity struct { ID uuid.UUID `json:"id" gorm:"type:uuid;primary_key;default:uuid_generate_v4()"` UserID uuid.UUID `json:"user_id" gorm:"type:uuid;index"` User User `json:"user_id" gorm:"foreignKey:UserID"` ProviderName string `json:"provider_name"` ProviderUserID string `json:"provider_user_id"` AccessToken string `json:"-"` // Don't expose access token in JSON RefreshToken string `json:"-"` // Don't expose refresh token in JSON ExpiresAt *time.Time `json:"-"` // Don't expose expiration in JSON ProfileData string `json:"-" gorm:"type:jsonb"` // Store provider-specific profile data as JSON CreatedAt time.Time `json:"created_at"` } // JobPosition represents a job position type JobPosition struct { ID uuid.UUID `json:"id" gorm:"type:uuid;primary_key;default:uuid_generate_v4()"` TenantID uuid.UUID `json:"tenant_id" gorm:"type:uuid;index"` UserID uuid.UUID `json:"user_id" gorm:"type:uuid;index"` // Creator of the position User User `json:"user" gorm:"foreignKey:UserID"` Title string `json:"title" gorm:"not null"` Description string `json:"description" gorm:"not null"` Requirements string `json:"requirements"` Location string `json:"location"` EmploymentType string `json:"employment_type" gorm:"default:full_time"` // full_time, part_time, contract, internship SalaryMin *float64 `json:"salary_min"` SalaryMax *float64 `json:"salary_max"` ExperienceLevel string `json:"experience_level" gorm:"default:mid_level"` // entry_level, mid_level, senior_level, executive PostedAt time.Time `json:"posted_at"` ClosedAt *time.Time `json:"closed_at,omitempty"` Status string `json:"status" gorm:"default:open"` // open, closed, filled CreatedAt time.Time `json:"created_at"` UpdatedAt time.Time `json:"updated_at"` IsActive bool `json:"is_active" gorm:"default:true"` // Association Applications []Application `json:"-" gorm:"foreignKey:PositionID"` } // Resume represents a user's resume type Resume struct { ID uuid.UUID `json:"id" gorm:"type:uuid;primary_key;default:uuid_generate_v4()"` UserID uuid.UUID `json:"user_id" gorm:"type:uuid;index"` User User `json:"-" gorm:"foreignKey:UserID"` Title string `json:"title" gorm:"not null"` FilePath string `json:"file_path" gorm:"not null"` // Path to stored resume file FileType string `json:"file_type"` // MIME type FileSize int64 `json:"file_size"` // Size in bytes IsActive bool `json:"is_active" gorm:"default:true"` CreatedAt time.Time `json:"created_at"` UpdatedAt time.Time `json:"updated_at"` // Association Applications []Application `json:"-" gorm:"foreignKey:ResumeID"` } // Application represents a job application type Application struct { ID uuid.UUID `json:"id" gorm:"type:uuid;primary_key;default:uuid_generate_v4()"` PositionID uuid.UUID `json:"position_id" gorm:"type:uuid;index"` UserID uuid.UUID `json:"user_id" gorm:"type:uuid;index"` ResumeID *uuid.UUID `json:"resume_id" gorm:"type:uuid"` Resume *Resume `json:"resume,omitempty" gorm:"foreignKey:ResumeID"` Position JobPosition `json:"position" gorm:"foreignKey:PositionID"` User User `json:"user" gorm:"foreignKey:UserID"` CoverLetter string `json:"cover_letter"` Status string `json:"status" gorm:"default:pending"` // pending, reviewed, accepted, rejected AppliedAt time.Time `json:"applied_at"` ReviewedAt *time.Time `json:"reviewed_at,omitempty"` ReviewerUserID *uuid.UUID `json:"reviewer_user_id" gorm:"type:uuid"` ReviewerUser *User `json:"reviewer_user,omitempty" gorm:"foreignKey:ReviewerUserID"` Notes string `json:"notes"` CreatedAt time.Time `json:"created_at"` UpdatedAt time.Time `json:"updated_at"` } // ValidRole checks if a role is valid func ValidRole(role string) bool { switch role { case "job_seeker", "job_provider", "admin": return true default: return false } } // ValidEmploymentType checks if an employment type is valid func ValidEmploymentType(empType string) bool { switch empType { case "full_time", "part_time", "contract", "internship": return true default: return false } } // ValidExperienceLevel checks if an experience level is valid func ValidExperienceLevel(level string) bool { switch level { case "entry_level", "mid_level", "senior_level", "executive": return true default: return false } } // ValidStatus checks if a status is valid func ValidStatus(status string) bool { switch status { case "open", "closed", "filled", "pending", "reviewed", "accepted", "rejected": return true default: return false } }