- 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
87 lines
No EOL
4 KiB
Go
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"
|
|
} |