Documentation
¶
Overview ¶
File Path: monorepo/cloud/maplepress-backend/internal/domain/site/site.go
Index ¶
- Constants
- Variables
- type Repository
- type Site
- func (s *Site) CanAccessAPI() bool
- func (s *Site) IncrementMonthlyPageCount(count int64)
- func (s *Site) IncrementPageCount()
- func (s *Site) IncrementSearchCount()
- func (s *Site) IsActive() bool
- func (s *Site) IsTestMode() bool
- func (s *Site) RequiresVerification() bool
- func (s *Site) ResetMonthlyUsage()
- func (s *Site) UpdateStorageUsed(bytes int64)
- func (s *Site) Verify()
Constants ¶
const ( StatusPending = "pending" // Site created, awaiting verification StatusActive = "active" // Site verified and operational StatusInactive = "inactive" // User temporarily disabled StatusSuspended = "suspended" // Suspended due to violation or non-payment StatusArchived = "archived" // Soft deleted )
Status constants
Variables ¶
var ( // ErrNotFound is returned when a site is not found ErrNotFound = errors.New("site not found") // ErrSiteNotFound is an alias for ErrNotFound ErrSiteNotFound = ErrNotFound // ErrDomainAlreadyExists is returned when trying to create a site with a domain that already exists ErrDomainAlreadyExists = errors.New("domain already exists") // ErrInvalidAPIKey is returned when API key authentication fails ErrInvalidAPIKey = errors.New("invalid API key") // ErrSiteNotActive is returned when trying to perform operations on an inactive site ErrSiteNotActive = errors.New("site is not active") // ErrSiteNotVerified is returned when trying to perform operations on an unverified site ErrSiteNotVerified = errors.New("site is not verified") // ErrQuotaExceeded is returned when a quota limit is reached ErrQuotaExceeded = errors.New("quota exceeded") // ErrStorageQuotaExceeded is returned when storage quota is exceeded ErrStorageQuotaExceeded = errors.New("storage quota exceeded") // ErrSearchQuotaExceeded is returned when search quota is exceeded ErrSearchQuotaExceeded = errors.New("search quota exceeded") // ErrIndexingQuotaExceeded is returned when indexing quota is exceeded ErrIndexingQuotaExceeded = errors.New("indexing quota exceeded") )
Functions ¶
This section is empty.
Types ¶
type Repository ¶
type Repository interface {
// Create inserts a new site into all Cassandra tables
Create(ctx context.Context, site *Site) error
// GetByID retrieves a site by tenant_id and site_id
GetByID(ctx context.Context, tenantID, siteID gocql.UUID) (*Site, error)
// GetByDomain retrieves a site by domain name
GetByDomain(ctx context.Context, domain string) (*Site, error)
// GetByAPIKeyHash retrieves a site by API key hash (for authentication)
GetByAPIKeyHash(ctx context.Context, apiKeyHash string) (*Site, error)
// ListByTenant retrieves all sites for a tenant (paginated)
ListByTenant(ctx context.Context, tenantID gocql.UUID, pageSize int, pageState []byte) ([]*Site, []byte, error)
// Update updates a site in all Cassandra tables
Update(ctx context.Context, site *Site) error
// UpdateAPIKey updates the API key for a site (handles sites_by_apikey table correctly)
// Must provide both old and new API key hashes to properly delete old entry and insert new one
UpdateAPIKey(ctx context.Context, site *Site, oldAPIKeyHash string) error
// Delete removes a site from all Cassandra tables
Delete(ctx context.Context, tenantID, siteID gocql.UUID) error
// DomainExists checks if a domain is already registered
DomainExists(ctx context.Context, domain string) (bool, error)
// UpdateUsage updates only usage tracking fields (optimized for frequent updates)
UpdateUsage(ctx context.Context, site *Site) error
// GetAllSitesForUsageReset retrieves all sites for monthly usage counter reset
// This uses ALLOW FILTERING and should only be used for administrative tasks
GetAllSitesForUsageReset(ctx context.Context, pageSize int, pageState []byte) ([]*Site, []byte, error)
}
Repository defines the interface for site data access
type Site ¶
type Site struct {
// Core Identity
ID gocql.UUID `json:"id"`
TenantID gocql.UUID `json:"tenant_id"`
// Site Information
SiteURL string `json:"site_url"` // Full URL: https://example.com
Domain string `json:"domain"` // Extracted: example.com
// Authentication
APIKeyHash string `json:"-"` // SHA-256 hash, never exposed in JSON
APIKeyPrefix string `json:"api_key_prefix"` // "live_sk_a1b2" for display
APIKeyLastFour string `json:"api_key_last_four"` // Last 4 chars for display
// Status & Verification
Status string `json:"status"` // active, inactive, pending, suspended, archived
IsVerified bool `json:"is_verified"`
VerificationToken string `json:"-"` // Never exposed
// Search & Indexing
SearchIndexName string `json:"search_index_name"`
TotalPagesIndexed int64 `json:"total_pages_indexed"` // All-time total for stats
LastIndexedAt time.Time `json:"last_indexed_at,omitempty"`
// Plugin Info
PluginVersion string `json:"plugin_version,omitempty"`
// Usage Tracking (for billing) - no quotas/limits
StorageUsedBytes int64 `json:"storage_used_bytes"` // Current storage usage
SearchRequestsCount int64 `json:"search_requests_count"` // Monthly search count
MonthlyPagesIndexed int64 `json:"monthly_pages_indexed"` // Monthly indexing count
LastResetAt time.Time `json:"last_reset_at"` // Last monthly reset
// Metadata (optional fields)
Language string `json:"language,omitempty"` // ISO 639-1
Timezone string `json:"timezone,omitempty"` // IANA timezone
Notes string `json:"notes,omitempty"`
// Audit
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
// CWE-359: IP address tracking for GDPR compliance (90-day expiration)
CreatedFromIPAddress string `json:"-"` // Encrypted IP address, never exposed in JSON
CreatedFromIPTimestamp time.Time `json:"-"` // For 90-day expiration tracking
ModifiedFromIPAddress string `json:"-"` // Encrypted IP address, never exposed in JSON
ModifiedFromIPTimestamp time.Time `json:"-"` // For 90-day expiration tracking
}
Site represents a WordPress site registered in the system
func NewSite ¶
func NewSite(tenantID gocql.UUID, domain, siteURL string, apiKeyHash, apiKeyPrefix, apiKeyLastFour string, encryptedIP string) *Site
NewSite creates a new Site entity with defaults
func (*Site) CanAccessAPI ¶
CanAccessAPI checks if the site can access the API More lenient than IsActive - allows pending sites for initial setup
func (*Site) IncrementMonthlyPageCount ¶
IncrementMonthlyPageCount increments both lifetime and monthly page counters
func (*Site) IncrementPageCount ¶
func (s *Site) IncrementPageCount()
IncrementPageCount increments the indexed page counter (lifetime total)
func (*Site) IncrementSearchCount ¶
func (s *Site) IncrementSearchCount()
IncrementSearchCount increments the search request counter
func (*Site) IsTestMode ¶
IsTestMode checks if the site is using a test API key
func (*Site) RequiresVerification ¶
RequiresVerification checks if the site requires verification Test mode sites skip verification for development
func (*Site) ResetMonthlyUsage ¶
func (s *Site) ResetMonthlyUsage()
ResetMonthlyUsage resets monthly usage counters for billing cycles
func (*Site) UpdateStorageUsed ¶
UpdateStorageUsed updates the storage usage