inboxer/src/internal/db/models.go
cclohmar 766e3e3de6 Phase 4: Polish, settings fix, 7-way AI classification & empty-inbox guarantee (Version: 2026-04.5)
- Fixed settings form silently dropping fields (multipart/form-data parse)
- Fixed IMAP test connection (multipart parse + raw field logging)
- Added IMAPUsername field throughout (model, settings, handlers, worker)
- Replaced smtp.SendMail with custom sendMail (explicit HELO + STARTTLS)
- Added From header to OTP/Welcome emails (RFC5322 compliance)
- Worker now processes ALL INBOX emails (FetchBatch instead of FetchUnseen)
- Fixed go build . compiling debug scripts instead of src/cmd/main.go
- Added Notifications, Finance, Social classification folders (7 total)
- Refined AI prompt with precise category descriptions
- Added session guardrail to AGENTS.md
2026-04-23 18:35:30 +00:00

87 lines
No EOL
4 KiB
Go

package db
import (
"time"
"gorm.io/gorm"
)
// User represents a user of the application
type User struct {
ID uint `gorm:"primaryKey" json:"id"`
Email string `gorm:"uniqueIndex;not null" json:"email"`
HashedOTP string `gorm:"column:hashed_otp" json:"-"` // Hashed OTP (bcrypt)
OTPExpiry *time.Time `gorm:"column:otp_expiry" json:"-"` // OTP expiry time
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
DeletedAt gorm.DeletedAt `gorm:"index" json:"-"`
// Relationships
MailboxSettings MailboxSettings `gorm:"foreignKey:UserID" json:"mailbox_settings,omitempty"`
}
// MailboxSettings stores user's IMAP/SMTP configuration (encrypted)
type MailboxSettings struct {
ID uint `gorm:"primaryKey" json:"id"`
UserID uint `gorm:"uniqueIndex;not null" json:"user_id"`
IMAPHost string `gorm:"not null" json:"imap_host"`
IMAPPort int `gorm:"not null;default:993" json:"imap_port"`
IMAPUser string `gorm:"not null" json:"imap_user"` // Email address for the IMAP account
IMAPUsername string `gorm:"column:imap_username" json:"imap_username"` // Login username (if different from email)
IMAPPassEncrypted string `gorm:"column:imap_pass_encrypted;not null" json:"-"` // Encrypted password
IMAPTLS bool `gorm:"column:imap_tls;default:true" json:"imap_tls"`
SMTPHost string `gorm:"not null" json:"smtp_host"`
SMTPPort int `gorm:"not null;default:587" json:"smtp_port"`
SMTPUser string `gorm:"not null" json:"smtp_user"`
SMTPPassEncrypted string `gorm:"column:smtp_pass_encrypted;not null" json:"-"` // Encrypted password
BatchSize int `gorm:"default:10" json:"batch_size"`
PollInterval int `gorm:"default:5" json:"poll_interval"` // minutes
AutoStart bool `gorm:"default:true" json:"auto_start"`
TestMode bool `gorm:"default:false" json:"test_mode"`
LastProcessedUID uint32 `gorm:"column:last_processed_uid" json:"last_processed_uid"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
DeletedAt gorm.DeletedAt `gorm:"index" json:"-"`
}
// ProcessedEmail tracks emails that have been classified
type ProcessedEmail struct {
ID uint `gorm:"primaryKey" json:"id"`
UserID uint `gorm:"index;not null" json:"user_id"`
MessageID string `gorm:"index;not null" json:"message_id"`
UID uint32 `gorm:"not null" json:"uid"`
From string `json:"from"`
Subject string `json:"subject"`
ReceivedDate time.Time `json:"received_date"`
ClassifiedFolder string `gorm:"not null" json:"classified_folder"`
ConfidenceScore int `gorm:"default:0" json:"confidence_score"` // 0-100
AIResponse string `gorm:"type:text" json:"ai_response"` // Full AI response JSON
Moved bool `gorm:"default:false" json:"moved"` // Whether email was actually moved
TestMode bool `gorm:"default:false" json:"test_mode"` // Processed in test mode
Error string `gorm:"type:text" json:"error"` // Error if processing failed
ProcessedAt time.Time `json:"processed_at"`
// Relationships
User User `gorm:"foreignKey:UserID" json:"-"`
}
// FolderCount represents aggregated folder counts for dashboard
type FolderCount struct {
Folder string `json:"folder"`
Count int `json:"count"`
}
// TableName overrides the table name for User
func (User) TableName() string {
return "users"
}
// TableName overrides the table name for MailboxSettings
func (MailboxSettings) TableName() string {
return "mailbox_settings"
}
// TableName overrides the table name for ProcessedEmail
func (ProcessedEmail) TableName() string {
return "processed_emails"
}