hatch-surf/internal/face/config.go
Chris Anderson 4bf37faf4f Add face service package for AWS Rekognition integration
- Client interface and MockClient for testing
- Service layer with IndexPhoto and SearchFaces methods
- CacheService interface and MemoryCache implementation
- Configuration with environment variable support
- Error types and user-facing messages
- Unit tests for service layer

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-06-25 21:11:45 +02:00

103 lines
2.4 KiB
Go

package face
import (
"os"
"strconv"
"time"
)
// Config holds configuration for the face service
type Config struct {
// AWS Configuration
Region string
CollectionID string
// Face Detection Configuration
MaxFaces int
Threshold float64
QualityFilter string
// Cache Configuration
CacheTTL time.Duration
SearchCacheTTL time.Duration
PhotoCacheTTL time.Duration
// Rate Limiting
GuestRateLimit int
GuestRateWindowMin int
AuthRateLimit int
AuthRateWindowMin int
// Image Optimization
MaxImageSize int
ResizeWidth int
ResizeHeight int
ImageQuality int
}
// DefaultConfig returns default configuration
func DefaultConfig() *Config {
return &Config{
Region: getEnv("AWS_REGION", "us-east-1"),
CollectionID: getEnv("REKOGNITION_COLLECTION", "hatch-faces"),
MaxFaces: getEnvInt("REKOGNITION_MAX_FACES", 10),
Threshold: getEnvFloat("REKOGNITION_THRESHOLD", 80.0),
QualityFilter: getEnv("REKOGNITION_QUALITY_FILTER", "AUTO"),
CacheTTL: 5 * time.Minute,
SearchCacheTTL: 5 * time.Minute,
PhotoCacheTTL: 24 * time.Hour,
GuestRateLimit: getEnvInt("RATE_LIMIT_GUEST_SEARCHES", 20),
GuestRateWindowMin: getEnvInt("RATE_LIMIT_GUEST_WINDOW_MINUTES", 15),
AuthRateLimit: getEnvInt("RATE_LIMIT_AUTH_SEARCHES", 100),
AuthRateWindowMin: getEnvInt("RATE_LIMIT_AUTH_WINDOW_MINUTES", 1),
MaxImageSize: 10 * 1024 * 1024, // 10MB
ResizeWidth: 1024,
ResizeHeight: 1024,
ImageQuality: 85,
}
}
// Validate checks if the configuration is valid
func (c *Config) Validate() error {
if c.Region == "" {
return ErrMissingRegion
}
if c.CollectionID == "" {
return ErrMissingCollectionID
}
if c.MaxFaces <= 0 {
return ErrInvalidMaxFaces
}
if c.Threshold < 0 || c.Threshold > 100 {
return ErrInvalidThreshold
}
return nil
}
// Helper functions for environment variables
func getEnv(key, defaultValue string) string {
if value := os.Getenv(key); value != "" {
return value
}
return defaultValue
}
func getEnvInt(key string, defaultValue int) int {
if value := os.Getenv(key); value != "" {
if intValue, err := strconv.Atoi(value); err == nil {
return intValue
}
}
return defaultValue
}
func getEnvFloat(key string, defaultValue float64) float64 {
if value := os.Getenv(key); value != "" {
if floatValue, err := strconv.ParseFloat(value, 64); err == nil {
return floatValue
}
}
return defaultValue
}