Initial commit: Open sourcing all of the Maple Open Technologies code.

This commit is contained in:
Bartlomiej Mika 2025-12-02 14:33:08 -05:00
commit 755d54a99d
2010 changed files with 448675 additions and 0 deletions

View file

@ -0,0 +1,75 @@
package tenant
import (
"errors"
"regexp"
"time"
)
var (
ErrNameRequired = errors.New("tenant name is required")
ErrNameTooShort = errors.New("tenant name must be at least 2 characters")
ErrNameTooLong = errors.New("tenant name must not exceed 100 characters")
ErrSlugRequired = errors.New("tenant slug is required")
ErrSlugInvalid = errors.New("tenant slug must contain only lowercase letters, numbers, and hyphens")
ErrTenantNotFound = errors.New("tenant not found")
ErrTenantExists = errors.New("tenant already exists")
ErrTenantInactive = errors.New("tenant is inactive")
)
// Status represents the tenant's current status
type Status string
const (
StatusActive Status = "active"
StatusInactive Status = "inactive"
StatusSuspended Status = "suspended"
)
// Tenant represents a tenant in the system
// Each tenant is a separate customer/organization
type Tenant struct {
ID string
Name string // Display name (e.g., "Acme Corporation")
Slug string // URL-friendly identifier (e.g., "acme-corp")
Status Status
CreatedAt time.Time
UpdatedAt time.Time
// CWE-359: IP address tracking for GDPR compliance (90-day expiration)
CreatedFromIPAddress string // Encrypted IP address
CreatedFromIPTimestamp time.Time // For 90-day expiration tracking
ModifiedFromIPAddress string // Encrypted IP address
ModifiedFromIPTimestamp time.Time // For 90-day expiration tracking
}
var slugRegex = regexp.MustCompile(`^[a-z0-9]+(?:-[a-z0-9]+)*$`)
// Validate validates the tenant entity
func (t *Tenant) Validate() error {
// Name validation
if t.Name == "" {
return ErrNameRequired
}
if len(t.Name) < 2 {
return ErrNameTooShort
}
if len(t.Name) > 100 {
return ErrNameTooLong
}
// Slug validation
if t.Slug == "" {
return ErrSlugRequired
}
if !slugRegex.MatchString(t.Slug) {
return ErrSlugInvalid
}
return nil
}
// IsActive returns true if the tenant is active
func (t *Tenant) IsActive() bool {
return t.Status == StatusActive
}

View file

@ -0,0 +1,16 @@
package tenant
import "context"
// Repository defines data access for tenants
// Note: Tenant operations do NOT require tenantID parameter since
// tenants are the top-level entity in our multi-tenant architecture
type Repository interface {
Create(ctx context.Context, tenant *Tenant) error
GetByID(ctx context.Context, id string) (*Tenant, error)
GetBySlug(ctx context.Context, slug string) (*Tenant, error)
Update(ctx context.Context, tenant *Tenant) error
Delete(ctx context.Context, id string) error
List(ctx context.Context, limit int) ([]*Tenant, error)
ListByStatus(ctx context.Context, status Status, limit int) ([]*Tenant, error)
}