models

package
v1.0.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 23, 2026 License: MIT Imports: 2 Imported by: 0

README

models

Shared GORM database models for portfolio services.

Schema Domains

portfolio.*
  • ProfileStorageFile (avatar, resume)
  • WorkExperience
  • Certification
  • Skill
  • PortfolioProjectStorageFile, Skill (many-to-many via project_technologies)
miniatures.*
  • MiniatureThemeMiniatureProject[], StorageFile (cover)
  • MiniatureProjectMiniatureTheme, MiniatureFile[], MiniatureProjectTechnique[], MiniatureProjectPaint[]
  • MiniatureFileStorageFile
  • MiniatureTechnique (cl_techniques catalog)
  • MiniaturePaint (cl_paints catalog)
  • MiniatureProjectTechniqueMiniatureTechnique (junction)
  • MiniatureProjectPaintMiniaturePaint (junction)
storage.*
  • StorageFile - File metadata for MinIO storage
messaging.*
  • ContactMessage - Contact form submissions with status tracking
  • Recipient - Email recipients for notifications
  • DeliveryAttempt - Email delivery tracking
auth.*
  • User - User accounts
  • ActionLog - Audit log entries

Usage

import "github.com/adeptry-app/go-common/models"

// Load profile with associated files
var profile models.Profile
db.Preload("AvatarFile").Preload("ResumeFile").First(&profile)

// Load miniature project with all associations
var project models.MiniatureProject
db.Preload("Theme").Preload("MiniatureFiles.File").Preload("Techniques.Technique").First(&project)

Documentation

Index

Constants

View Source
const (
	EmailTypeContactForm       = "contact_form"
	EmailTypeEmailVerification = "email_verification"
	EmailTypePasswordReset     = "password_reset"
	EmailType2FACode           = "2fa_code"
)

Email type constants

View Source
const (
	EmailStatusPending = "pending"
	EmailStatusQueued  = "queued"
	EmailStatusSent    = "sent"
	EmailStatusFailed  = "failed"
)

Email status constants

View Source
const (
	MessageStatusPending = EmailStatusPending
	MessageStatusQueued  = EmailStatusQueued
	MessageStatusSent    = EmailStatusSent
	MessageStatusFailed  = EmailStatusFailed
)

Deprecated: Use EmailStatus* constants. Will be removed in v1.0.

View Source
const (
	DeliveryStatusSuccess = "success"
	DeliveryStatusFailed  = "failed"
	DeliveryStatusPending = "pending"
)

DeliveryAttemptStatus constants

Variables

This section is empty.

Functions

func ValidEmailStatus

func ValidEmailStatus(s string) bool

ValidEmailStatus reports whether s is a known email status value.

Types

type Certification

type Certification struct {
	ID            int64     `json:"id" gorm:"primaryKey"`
	Name          string    `json:"name" binding:"required"`
	Issuer        string    `json:"issuer" binding:"required"`
	IssueDate     string    `json:"issueDate" gorm:"column:issue_date" binding:"required"`
	ExpiryDate    *string   `json:"expiryDate,omitempty" gorm:"column:expiry_date"`
	CredentialID  string    `json:"credentialId,omitempty" gorm:"column:credential_id"`
	CredentialURL string    `json:"credentialUrl,omitempty" gorm:"column:credential_url"`
	CreatedAt     time.Time `json:"createdAt" gorm:"column:created_at"`
	UpdatedAt     time.Time `json:"updatedAt" gorm:"column:updated_at"`
}

func (Certification) TableName

func (Certification) TableName() string

type ContactMessage deprecated

type ContactMessage = Email

Deprecated: Use Email directly. Will be removed in v1.0.

type ContactMessageCreate

type ContactMessageCreate struct {
	Name     string `json:"name" binding:"required,max=255"`
	Email    string `json:"email" binding:"required,email,max=255"`
	Subject  string `json:"subject" binding:"required,max=500"`
	Message  string `json:"message" binding:"required,max=10000"`
	Honeypot string `json:"website" swaggerignore:"true"`
}

ContactMessageCreate is the DTO for creating a new contact message (public endpoint)

func (*ContactMessageCreate) IsSpam

func (c *ContactMessageCreate) IsSpam() bool

IsSpam checks if the honeypot field is filled (indicates bot submission)

type ContactMessageEvent deprecated

type ContactMessageEvent = EmailEvent

Deprecated: Use EmailEvent directly. Will be removed in v1.0.

type DeliveryAttempt

type DeliveryAttempt struct {
	ID             int64     `json:"id" gorm:"primaryKey"`
	MessageID      int64     `json:"messageId" gorm:"column:message_id;index"`
	RecipientEmail string    `json:"recipientEmail" gorm:"column:recipient_email"`
	Status         string    `json:"status" gorm:"column:status"`
	ErrorCode      *string   `json:"errorCode,omitempty" gorm:"column:error_code"`
	ErrorMessage   *string   `json:"errorMessage,omitempty" gorm:"column:error_message"`
	AttemptedAt    time.Time `json:"attemptedAt" gorm:"column:attempted_at"`
}

DeliveryAttempt represents an email delivery attempt for a contact message

func (DeliveryAttempt) TableName

func (DeliveryAttempt) TableName() string

type Email

type Email struct {
	ID             int64      `json:"id" gorm:"primaryKey"`
	Type           string     `json:"type" gorm:"column:type;default:contact_form"`
	Name           *string    `json:"name,omitempty" gorm:"column:name"`
	SenderEmail    *string    `json:"senderEmail,omitempty" gorm:"column:email"`
	RecipientEmail *string    `json:"recipientEmail,omitempty" gorm:"column:recipient_email"`
	Subject        string     `json:"subject" gorm:"column:subject"`
	Message        string     `json:"message" gorm:"column:message"`
	Honeypot       string     `json:"-" gorm:"column:honeypot"`
	Status         string     `json:"status" gorm:"column:status;default:pending"`
	Attempts       int        `json:"attempts" gorm:"column:attempts;default:0"`
	LastError      *string    `json:"lastError,omitempty" gorm:"column:last_error"`
	CreatedAt      time.Time  `json:"createdAt" gorm:"column:created_at"`
	UpdatedAt      time.Time  `json:"updatedAt" gorm:"column:updated_at"`
	SentAt         *time.Time `json:"sentAt,omitempty" gorm:"column:sent_at"`
}

Email represents an email record in the messaging system. Used for contact form submissions, auth verification, password reset, and 2FA emails.

func (Email) TableName

func (Email) TableName() string

type EmailEvent

type EmailEvent struct {
	EmailID int64 `json:"emailId"`
}

EmailEvent is the message published to the queue for processing

type Image

type Image struct {
	ID      int64  `json:"id"`
	URL     string `json:"url"`
	Caption string `json:"caption"`
}

Image is the simplified view for frontend

type MiniatureFile

type MiniatureFile struct {
	ID                 int64        `json:"id" gorm:"primaryKey"`
	MiniatureProjectID int64        `json:"miniatureProjectId" gorm:"column:miniature_project_id"`
	FileID             int64        `json:"fileId" gorm:"column:file_id"`
	Caption            string       `json:"caption"`
	DisplayOrder       int          `json:"displayOrder,omitempty" gorm:"column:display_order"`
	File               *StorageFile `json:"file,omitempty" gorm:"foreignKey:FileID"`
	CreatedAt          time.Time    `json:"createdAt" gorm:"column:created_at"`
}

func (MiniatureFile) TableName

func (MiniatureFile) TableName() string

type MiniaturePaint

type MiniaturePaint struct {
	ID           int64  `json:"id" gorm:"primaryKey"`
	Name         string `json:"name" binding:"required"`
	Manufacturer string `json:"manufacturer" binding:"required"`
	// ColorHex is the hexadecimal color code in #RRGGBB or #RGB format (e.g., #FF5733, #F00)
	ColorHex *string `json:"colorHex,omitempty" gorm:"column:color_hex" binding:"omitempty,hexcolor"`
	// PaintType categorizes the paint (Base, Layer, Shade, Wash, Contrast, Dry, Technical, Metallic, Air, Primer, Edge, Glaze, Ink)
	// Database enforces these values via CHECK constraint
	PaintType *string   `json:"paintType,omitempty" gorm:"column:paint_type"`
	CreatedAt time.Time `json:"createdAt" gorm:"column:created_at"`
	UpdatedAt time.Time `json:"updatedAt" gorm:"column:updated_at"`
}

MiniaturePaint represents a paint in the master paint list (cl_paints table). This model is used for managing the paint catalog with CRUD operations. Paints are categorized by type and identified by the combination of name and manufacturer.

func (MiniaturePaint) TableName

func (MiniaturePaint) TableName() string

type MiniatureProject

type MiniatureProject struct {
	ID            int64     `json:"id" gorm:"primaryKey"`
	ThemeID       *int64    `json:"themeId,omitempty" gorm:"column:theme_id"`
	Title         string    `json:"name" gorm:"column:title" binding:"required"`
	Description   string    `json:"description"`
	CompletedDate *string   `json:"completedDate,omitempty" gorm:"column:completed_date"`
	Scale         string    `json:"scale,omitempty"`
	Manufacturer  string    `json:"manufacturer,omitempty"`
	TimeSpent     *float64  `json:"timeSpent,omitempty" gorm:"column:time_spent"`
	Difficulty    string    `json:"difficulty,omitempty"`
	DisplayOrder  int       `json:"displayOrder,omitempty" gorm:"column:display_order"`
	CreatedAt     time.Time `json:"createdAt" gorm:"column:created_at"`
	UpdatedAt     time.Time `json:"updatedAt" gorm:"column:updated_at"`

	// Associations
	Theme          *MiniatureTheme             `json:"theme,omitempty" gorm:"foreignKey:ThemeID"`
	MiniatureFiles []MiniatureFile             `json:"-" gorm:"foreignKey:MiniatureProjectID"`
	Techniques     []MiniatureProjectTechnique `json:"techniques,omitempty" gorm:"foreignKey:MiniatureProjectID"`
	Paints         []MiniatureProjectPaint     `json:"paints,omitempty" gorm:"foreignKey:MiniatureProjectID"`

	// Computed field (populated by repository layer - requires URL building)
	Images []Image `json:"images,omitempty" gorm:"-"`
}

func (MiniatureProject) TableName

func (MiniatureProject) TableName() string

type MiniatureProjectPaint

type MiniatureProjectPaint struct {
	ID                 int64     `json:"id" gorm:"primaryKey"`
	MiniatureProjectID int64     `json:"miniatureProjectId" gorm:"column:miniature_project_id"`
	PaintID            int64     `json:"paintId" gorm:"column:paint_id"`
	Notes              string    `json:"notes,omitempty" gorm:"column:usage_notes"`
	CreatedAt          time.Time `json:"createdAt" gorm:"column:created_at"`

	// Associations
	Paint *MiniaturePaint `json:"paint,omitempty" gorm:"foreignKey:PaintID"`
}

MiniatureProjectPaint is the junction table linking projects to paints

func (MiniatureProjectPaint) TableName

func (MiniatureProjectPaint) TableName() string

type MiniatureProjectTechnique

type MiniatureProjectTechnique struct {
	ID                 int64     `json:"id" gorm:"primaryKey"`
	MiniatureProjectID int64     `json:"miniatureProjectId" gorm:"column:miniature_project_id"`
	TechniqueID        int64     `json:"techniqueId" gorm:"column:technique_id"`
	Notes              string    `json:"notes,omitempty"`
	CreatedAt          time.Time `json:"createdAt" gorm:"column:created_at"`

	// Associations
	Technique *MiniatureTechnique `json:"technique,omitempty" gorm:"foreignKey:TechniqueID"`
}

MiniatureProjectTechnique is the junction table linking projects to techniques

func (MiniatureProjectTechnique) TableName

func (MiniatureProjectTechnique) TableName() string

type MiniatureTechnique

type MiniatureTechnique struct {
	ID              int64     `json:"id" gorm:"primaryKey"`
	Name            string    `json:"name" binding:"required"`
	Description     string    `json:"description"`
	DifficultyLevel string    `json:"difficultyLevel,omitempty" gorm:"column:difficulty_level"`
	DisplayOrder    int       `json:"displayOrder,omitempty" gorm:"column:display_order"`
	CreatedAt       time.Time `json:"createdAt" gorm:"column:created_at"`
	UpdatedAt       time.Time `json:"updatedAt" gorm:"column:updated_at"`
}

MiniatureTechnique represents a painting technique in the master technique list (cl_techniques table). This model is used for managing the technique catalog with CRUD operations.

func (MiniatureTechnique) TableName

func (MiniatureTechnique) TableName() string

type MiniatureTheme

type MiniatureTheme struct {
	ID           int64              `json:"id" gorm:"primaryKey"`
	Name         string             `json:"name" binding:"required"`
	Description  string             `json:"description"`
	CoverImageID *int64             `json:"coverImageId,omitempty" gorm:"column:cover_image_id"`
	DisplayOrder int                `json:"displayOrder,omitempty" gorm:"column:display_order"`
	Miniatures   []MiniatureProject `json:"miniatures,omitempty" gorm:"foreignKey:ThemeID"`
	CreatedAt    time.Time          `json:"createdAt" gorm:"column:created_at"`
	UpdatedAt    time.Time          `json:"updatedAt" gorm:"column:updated_at"`

	// Associations
	CoverImageFile *StorageFile `json:"coverImageFile,omitempty" gorm:"foreignKey:CoverImageID"`
}

func (MiniatureTheme) TableName

func (MiniatureTheme) TableName() string

type PortfolioProject

type PortfolioProject struct {
	ID              int64     `json:"id" gorm:"primaryKey"`
	Title           string    `json:"title" binding:"required"`
	Category        string    `json:"category,omitempty"`
	Description     string    `json:"description"`
	LongDescription string    `json:"longDescription,omitempty" gorm:"column:long_description"`
	ImageFileID     *int64    `json:"imageFileId,omitempty" gorm:"column:image_file_id"`
	GithubURL       string    `json:"githubUrl,omitempty" gorm:"column:github_url" binding:"omitempty,url"`
	LiveURL         string    `json:"liveUrl,omitempty" gorm:"column:live_url" binding:"omitempty,url"`
	StartDate       *string   `json:"startDate,omitempty" gorm:"column:start_date"`
	EndDate         *string   `json:"endDate,omitempty" gorm:"column:end_date"`
	IsOngoing       bool      `json:"isOngoing" gorm:"column:is_ongoing"`
	TeamSize        *int      `json:"teamSize,omitempty" gorm:"column:team_size"`
	Role            string    `json:"role,omitempty"`
	Featured        bool      `json:"featured"`
	Features        []string  `json:"features,omitempty" gorm:"type:jsonb;serializer:json"`
	Challenges      []string  `json:"challenges,omitempty" gorm:"type:jsonb;serializer:json"`
	Learnings       []string  `json:"learnings,omitempty" gorm:"type:jsonb;serializer:json"`
	DisplayOrder    int       `json:"displayOrder,omitempty" gorm:"column:display_order"`
	CreatedAt       time.Time `json:"createdAt" gorm:"column:created_at"`
	UpdatedAt       time.Time `json:"updatedAt" gorm:"column:updated_at"`

	// Associations
	ImageFile    *StorageFile `json:"imageFile,omitempty" gorm:"foreignKey:ImageFileID"`
	Technologies []Skill      `json:"technologies,omitempty" gorm:"many2many:portfolio.project_technologies;joinForeignKey:ProjectID;joinReferences:SkillID"`
}

func (PortfolioProject) TableName

func (PortfolioProject) TableName() string

type Profile

type Profile struct {
	ID           int64        `json:"id" gorm:"primaryKey"`
	FullName     string       `json:"name" gorm:"column:full_name" binding:"required"`
	Title        string       `json:"title"`
	Bio          string       `json:"tagline"`
	Email        string       `json:"email" binding:"omitempty,email"`
	Phone        string       `json:"phone,omitempty"`
	Location     string       `json:"location,omitempty"`
	Github       string       `json:"github,omitempty" binding:"omitempty,url"`
	Linkedin     string       `json:"linkedin,omitempty" binding:"omitempty,url"`
	AvatarFileID *int64       `json:"avatarFileId,omitempty" gorm:"column:avatar_file_id"`
	AvatarFile   *StorageFile `json:"avatarFile,omitempty" gorm:"foreignKey:AvatarFileID"`
	ResumeFileID *int64       `json:"resumeFileId,omitempty" gorm:"column:resume_file_id"`
	ResumeFile   *StorageFile `json:"resumeFile,omitempty" gorm:"foreignKey:ResumeFileID"`
	CreatedAt    time.Time    `json:"createdAt" gorm:"column:created_at"`
	UpdatedAt    time.Time    `json:"updatedAt" gorm:"column:updated_at"`
}

func (Profile) TableName

func (Profile) TableName() string

type Recipient

type Recipient struct {
	ID        int64     `json:"id" gorm:"primaryKey"`
	Email     string    `json:"email" gorm:"column:email;uniqueIndex" binding:"required,email,max=255"`
	Name      string    `json:"name" gorm:"column:name" binding:"required,max=255"`
	IsActive  bool      `json:"isActive" gorm:"column:is_active;default:true"`
	CreatedAt time.Time `json:"createdAt" gorm:"column:created_at"`
	UpdatedAt time.Time `json:"updatedAt" gorm:"column:updated_at"`
}

Recipient represents an email recipient for contact form notifications

func (Recipient) TableName

func (Recipient) TableName() string

type RecipientCreate

type RecipientCreate struct {
	Email    string `json:"email" binding:"required,email,max=255"`
	Name     string `json:"name" binding:"required,max=255"`
	IsActive *bool  `json:"isActive"` // Optional, defaults to true
}

RecipientCreate is the DTO for creating a new recipient

type RecipientUpdate

type RecipientUpdate struct {
	Email    *string `json:"email,omitempty" binding:"omitempty,email,max=255"`
	Name     *string `json:"name,omitempty" binding:"omitempty,max=255"`
	IsActive *bool   `json:"isActive,omitempty"`
}

RecipientUpdate is the DTO for updating a recipient

type Skill

type Skill struct {
	ID           int64      `json:"id" gorm:"primaryKey"`
	Skill        string     `json:"skill" binding:"required"`
	SkillTypeID  int64      `json:"skillTypeId" gorm:"column:skill_type_id" binding:"required"`
	SkillType    *SkillType `json:"skillType,omitempty" gorm:"foreignKey:SkillTypeID"`
	IsVisible    bool       `json:"isVisible" gorm:"column:is_visible"`
	DisplayOrder int        `json:"displayOrder,omitempty" gorm:"column:display_order"`
	CreatedAt    time.Time  `json:"createdAt" gorm:"column:created_at"`
	UpdatedAt    time.Time  `json:"updatedAt" gorm:"column:updated_at"`

	// Computed field
	Type string `json:"type" gorm:"-"`
}

func (Skill) TableName

func (Skill) TableName() string

type SkillType

type SkillType struct {
	ID           int64     `json:"id" gorm:"primaryKey"`
	Name         string    `json:"name" binding:"required"`
	Description  string    `json:"description,omitempty"`
	DisplayOrder int       `json:"displayOrder,omitempty" gorm:"column:display_order"`
	CreatedAt    time.Time `json:"createdAt" gorm:"column:created_at"`
	UpdatedAt    time.Time `json:"updatedAt" gorm:"column:updated_at"`
}

func (SkillType) TableName

func (SkillType) TableName() string

type StorageFile

type StorageFile struct {
	ID        int64     `json:"id" gorm:"primaryKey"`
	S3Key     string    `json:"-" gorm:"column:s3_key"`
	S3Bucket  string    `json:"-" gorm:"column:s3_bucket"`
	FileName  string    `json:"fileName" gorm:"column:file_name"`
	FileSize  int64     `json:"fileSize" gorm:"column:file_size"`
	MimeType  string    `json:"mimeType" gorm:"column:mime_type"`
	FileType  string    `json:"fileType" gorm:"column:file_type"`
	URL       string    `json:"url,omitempty" gorm:"-"` // Computed field
	CreatedAt time.Time `json:"createdAt" gorm:"column:created_at"`
}

func (StorageFile) TableName

func (StorageFile) TableName() string

type WorkExperience

type WorkExperience struct {
	ID          int64     `json:"id" gorm:"primaryKey"`
	Company     string    `json:"company" binding:"required"`
	Position    string    `json:"position" binding:"required"`
	Description string    `json:"description"`
	StartDate   string    `json:"startDate" gorm:"column:start_date" binding:"required"`
	EndDate     *string   `json:"endDate,omitempty" gorm:"column:end_date"`
	IsCurrent   bool      `json:"isCurrent" gorm:"column:is_current"`
	CreatedAt   time.Time `json:"createdAt" gorm:"column:created_at"`
	UpdatedAt   time.Time `json:"updatedAt" gorm:"column:updated_at"`
}

func (WorkExperience) TableName

func (WorkExperience) TableName() string

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL