package domain import ( "context" "time" ) // AuditLog represents a single audit event type AuditLog struct { EventID string `json:"event_id"` Timestamp time.Time `json:"timestamp"` UserID string `json:"user_id"` TenantID string `json:"tenant_id,omitempty"` SessionID string `json:"session_id,omitempty"` EventType string `json:"event_type"` // e.g., "login_success", "login_failed", "otp_sent" Status string `json:"status"` // e.g., "success", "failure" AuthMethod string `json:"auth_method,omitempty"` IPAddress string `json:"ip_address"` UserAgent string `json:"user_agent"` DeviceID string `json:"device_id,omitempty"` Details string `json:"details,omitempty"` // JSON string or simple text } // AuditRepository defines interface for storing logs type AuditRepository interface { Create(log *AuditLog) error FindPage(ctx context.Context, limit int, cursor *AuditCursor, tenantID string) ([]AuditLog, error) FindByUserAndEvents(ctx context.Context, userID string, eventTypes []string, limit int) ([]AuditLog, error) CountEventsSince(ctx context.Context, since time.Time) (int64, error) CountFailuresSince(ctx context.Context, since time.Time, tenantID string) (int64, error) CountActiveSessionsSince(ctx context.Context, since time.Time, tenantID string) (int64, error) Ping(ctx context.Context) error } type AuditCursor struct { Timestamp time.Time EventID string } // RedisRepository defines interface for KV storage (Redis) type RedisRepository interface { Set(key string, value string, expiration time.Duration) error Get(key string) (string, error) Delete(key string) error StoreVerificationCode(phone, code string) error GetVerificationCode(phone string) (string, error) DeleteVerificationCode(phone string) error }