package domain import "time" type Principal struct { Subject string `json:"subject"` Email string `json:"email,omitempty"` Name string `json:"name,omitempty"` Role string `json:"role"` } type DashboardKPI struct { Code string `json:"code"` Label string `json:"label"` Value string `json:"value"` } type UpcomingBooking struct { Reference string `json:"reference"` CustomerName string `json:"customerName"` CustomerEmail string `json:"customerEmail"` StartsAt time.Time `json:"startsAt"` EndsAt time.Time `json:"endsAt"` Status string `json:"status"` Label string `json:"label,omitempty"` } type WidgetSnippet struct { Kind string `json:"kind"` Code string `json:"code"` } type TrackingStatus struct { Provider string `json:"provider"` Connected bool `json:"connected"` SiteID string `json:"siteId,omitempty"` Message string `json:"message,omitempty"` } type DashboardSummary struct { TenantName string `json:"tenantName"` TenantSlug string `json:"tenantSlug"` Locale string `json:"locale"` Timezone string `json:"timezone"` PlanCode string `json:"planCode"` PublicBookingURL string `json:"publicBookingUrl"` SetupCompletion int `json:"setupCompletion"` KPIs []DashboardKPI `json:"kpis"` UpcomingBookings []UpcomingBooking `json:"upcomingBookings"` AllBookings []UpcomingBooking `json:"allBookings"` WidgetSnippets []WidgetSnippet `json:"widgetSnippets"` Tracking TrackingStatus `json:"tracking"` } type BrandProfile struct { Name string `json:"name"` SiteURL string `json:"siteUrl,omitempty"` LogoURL string `json:"logoUrl,omitempty"` PrimaryColor string `json:"primaryColor,omitempty"` } type TenantBootstrap struct { TenantID string `json:"tenantId"` TenantName string `json:"tenantName"` TenantSlug string `json:"tenantSlug,omitempty"` Preset string `json:"preset"` Locale string `json:"locale"` Timezone string `json:"timezone"` PlanCode string `json:"planCode,omitempty"` OnboardingCompleted bool `json:"onboardingCompleted"` Brand BrandProfile `json:"brand"` CurrentUser Principal `json:"currentUser"` } type TeamInviteRequest struct { Email string `json:"email"` Role string `json:"role,omitempty"` } type AvailabilityBlockRequest struct { DayOfWeek int `json:"dayOfWeek"` StartsLocal string `json:"startsLocal"` EndsLocal string `json:"endsLocal"` Busy bool `json:"busy,omitempty"` } type BookingDefaultsRequest struct { ServiceName string `json:"serviceName"` DurationMinutes int `json:"durationMinutes"` BufferBeforeMinutes int `json:"bufferBeforeMinutes"` BufferAfterMinutes int `json:"bufferAfterMinutes"` CancelWindowHours int `json:"cancelWindowHours"` } type OnboardTenantRequest struct { Name string `json:"name"` Slug string `json:"slug"` Preset string `json:"preset"` Locale string `json:"locale"` Timezone string `json:"timezone"` Brand BrandProfile `json:"brand"` LocationName string `json:"locationName"` BookingDefaults BookingDefaultsRequest `json:"bookingDefaults"` AvailabilityBlocks []AvailabilityBlockRequest `json:"availabilityBlocks"` TeamInvites []TeamInviteRequest `json:"teamInvites"` } type TimeSlot struct { ServiceID *string `json:"serviceId,omitempty"` ClassSessionID *string `json:"classSessionId,omitempty"` StaffID *string `json:"staffId,omitempty"` LocationID *string `json:"locationId,omitempty"` StartsAt string `json:"startsAt"` EndsAt string `json:"endsAt"` Mode string `json:"mode"` Label string `json:"label"` RemainingCapacity *int32 `json:"remainingCapacity,omitempty"` } type PublicAvailability struct { TenantSlug string `json:"tenantSlug"` Timezone string `json:"timezone"` Locale string `json:"locale"` Slots []TimeSlot `json:"slots"` } type CreateBookingRequest struct { TenantSlug string `json:"tenantSlug"` BookingMode string `json:"bookingMode"` ServiceID *string `json:"serviceId,omitempty"` ClassSessionID *string `json:"classSessionId,omitempty"` StaffID *string `json:"staffId,omitempty"` LocationID *string `json:"locationId,omitempty"` CustomerName string `json:"customerName"` CustomerEmail string `json:"customerEmail"` CustomerPhone string `json:"customerPhone,omitempty"` Notes string `json:"notes"` StartsAt string `json:"startsAt"` EndsAt string `json:"endsAt"` } type CreateBookingResponse struct { BookingID string `json:"bookingId"` Reference string `json:"reference"` Status string `json:"status"` } type PlanEntitlements struct { MaxLocations int `json:"maxLocations"` MaxStaff int `json:"maxStaff"` MaxBookingsMonth int `json:"maxBookingsMonth"` // -1 = unlimited EmailReminders bool `json:"emailReminders"` AdvancedReporting bool `json:"advancedReporting"` WidgetEmbedding bool `json:"widgetEmbedding"` UmamiTracking bool `json:"umamiTracking"` APIAccess bool `json:"apiAccess"` DedicatedManager bool `json:"dedicatedManager"` SMSAvailable bool `json:"smsAvailable"` } type PlanPricing struct { MonthlyAmountCents int `json:"monthlyAmountCents"` YearlyAmountCents int `json:"yearlyAmountCents"` MonthlyFormatted string `json:"monthlyFormatted"` YearlyFormatted string `json:"yearlyFormatted"` YearlySavings string `json:"yearlySavings"` YearlySavingsPercent int `json:"yearlySavingsPercent"` } type PlanDisplayPrice struct { Currency string `json:"currency"` AmountCents int `json:"amountCents"` Formatted string `json:"formatted"` YearlyAmountCents int `json:"yearlyAmountCents,omitempty"` YearlyFormatted string `json:"yearlyFormatted,omitempty"` YearlySavings string `json:"yearlySavings,omitempty"` YearlySavingsPercent int `json:"yearlySavingsPercent,omitempty"` } type SubscriptionSnapshot struct { TenantID string `json:"tenantId"` Provider string `json:"provider"` CustomerID string `json:"customerId"` SubscriptionID string `json:"subscriptionId"` Status string `json:"status"` PlanCode string `json:"planCode"` Currency string `json:"currency"` PriceID string `json:"priceId"` CancelAtPeriodEnd bool `json:"cancelAtPeriodEnd"` CurrentPeriodStart *time.Time `json:"currentPeriodStart,omitempty"` CurrentPeriodEnd *time.Time `json:"currentPeriodEnd,omitempty"` PaymentMethodBrand string `json:"paymentMethodBrand,omitempty"` PaymentMethodLast4 string `json:"paymentMethodLast4,omitempty"` Entitlements PlanEntitlements `json:"entitlements"` DisplayPrices []PlanDisplayPrice `json:"displayPrices"` TrialDays int `json:"trialDays"` LastSyncedAt *time.Time `json:"lastSyncedAt,omitempty"` CheckoutURLAvailable bool `json:"checkoutUrlAvailable"` SyncAvailable bool `json:"syncAvailable"` PortalAvailable bool `json:"portalAvailable"` } type CheckoutSessionRequest struct { PlanCode string `json:"planCode"` Currency string `json:"currency,omitempty"` BillingInterval string `json:"billingInterval,omitempty"` // "monthly" or "yearly", defaults to "monthly" } type CheckoutLaunchResponse struct { // Stripe checkout CheckoutURL string `json:"checkoutUrl,omitempty"` // Paddle checkout PriceID string `json:"priceId,omitempty"` CustomerID string `json:"customerId,omitempty"` CustomerEmail string `json:"customerEmail,omitempty"` // Common SuccessRedirectURL string `json:"successRedirectUrl,omitempty"` CancelRedirectURL string `json:"cancelRedirectUrl,omitempty"` CustomData map[string]string `json:"customData,omitempty"` } type PortalSessionResponse struct { URL string `json:"url"` } type DispatchReminderJobsRequest struct { Limit int `json:"limit,omitempty"` } type DispatchReminderJobsResponse struct { ProcessedCount int `json:"processedCount"` SentCount int `json:"sentCount"` FailedCount int `json:"failedCount"` } // ============================================ // LOCATION / ZONE MODELS // ============================================ type Location struct { ID string `json:"id"` TenantID string `json:"tenantId"` Name string `json:"name"` Type string `json:"type"` // room, private, hall, etc. Capacity int `json:"capacity"` Timezone string `json:"timezone"` CreatedAt time.Time `json:"createdAt"` } type CreateLocationRequest struct { Name string `json:"name" binding:"required"` Type string `json:"type" binding:"required"` Capacity int `json:"capacity"` } type UpdateLocationRequest struct { Name string `json:"name,omitempty"` Type string `json:"type,omitempty"` Capacity int `json:"capacity,omitempty"` } // ============================================ // BLOCKED DAYS / AVAILABILITY EXCEPTION MODELS // ============================================ type BlockedDay struct { ID string `json:"id"` TenantID string `json:"tenantId"` Date time.Time `json:"date"` Reason string `json:"reason"` Type string `json:"type"` // full, partial StaffID *string `json:"staffId,omitempty"` CreatedAt time.Time `json:"createdAt"` } type CreateBlockedDayRequest struct { Date string `json:"date" binding:"required"` // RFC3339 Reason string `json:"reason" binding:"required"` Type string `json:"type" binding:"required"` // full, partial StaffID *string `json:"staffId,omitempty"` } type UpdateBlockedDayRequest struct { Reason string `json:"reason,omitempty"` Type string `json:"type,omitempty"` } // ============================================ // CUSTOMER MODELS // ============================================ type Customer struct { ID string `json:"id"` TenantID string `json:"tenantId"` Name string `json:"name"` Email string `json:"email"` Phone *string `json:"phone,omitempty"` Status string `json:"status"` // active, inactive, vip BookingsCount int `json:"bookingsCount"` LastBookingAt *time.Time `json:"lastBookingAt,omitempty"` CreatedAt time.Time `json:"createdAt"` Notes string `json:"notes,omitempty"` } type CreateCustomerRequest struct { Name string `json:"name" binding:"required"` Email string `json:"email" binding:"required,email"` Phone *string `json:"phone,omitempty"` Status string `json:"status,omitempty"` // defaults to active Notes string `json:"notes,omitempty"` } type UpdateCustomerRequest struct { Name string `json:"name,omitempty"` Email string `json:"email,omitempty"` Phone *string `json:"phone,omitempty"` Status string `json:"status,omitempty"` Notes string `json:"notes,omitempty"` } // ============================================ // CUSTOMER BOOKING MANAGEMENT MODELS // ============================================ type CustomerBookingView struct { Reference string `json:"reference"` CustomerName string `json:"customerName"` CustomerEmail string `json:"customerEmail"` Service string `json:"service"` BusinessName string `json:"businessName"` StartsAt time.Time `json:"startsAt"` EndsAt time.Time `json:"endsAt"` Location string `json:"location"` Status string `json:"status"` Notes string `json:"notes,omitempty"` } type RescheduleBookingRequest struct { NewStartsAt string `json:"newStartsAt" binding:"required"` // RFC3339 NewEndsAt string `json:"newEndsAt" binding:"required"` // RFC3339 Reason string `json:"reason,omitempty"` } type CancelBookingRequest struct { Reason string `json:"reason,omitempty"` } // ============================================ // ADMIN MODELS // ============================================ type AdminDashboardStats struct { TotalTenants int64 `json:"totalTenants"` TotalUsers int64 `json:"totalUsers"` ActiveSubscriptions int64 `json:"activeSubscriptions"` TrialSubscriptions int64 `json:"trialSubscriptions"` BookingsThisMonth int64 `json:"bookingsThisMonth"` RevenueThisMonthCents int64 `json:"revenueThisMonthCents"` } type AdminTenantList struct { Total int `json:"total"` Page int `json:"page"` PageSize int `json:"pageSize"` Tenants []AdminTenant `json:"tenants"` } type AdminTenant struct { ID string `json:"id"` Slug string `json:"slug"` Name string `json:"name"` PlanCode string `json:"planCode"` SubscriptionStatus string `json:"subscriptionStatus"` BillingProvider string `json:"billingProvider"` } type AdminUserList struct { Total int `json:"total"` Page int `json:"page"` PageSize int `json:"pageSize"` Users []AdminUser `json:"users"` } type AdminUser struct { ID string `json:"id"` Email string `json:"email"` Name string `json:"name,omitempty"` EmailVerified bool `json:"emailVerified"` Provider string `json:"provider"` Role string `json:"role"` CreatedAt time.Time `json:"createdAt"` } type AdminLoginRequest struct { Email string `json:"email" binding:"required,email"` Key string `json:"key" binding:"required"` } type UpdateUserRoleRequest struct { Role string `json:"role" binding:"required,oneof=user admin superadmin"` } // ============================================ // WORKING HOURS MODELS // ============================================ type WorkingHours struct { DayOfWeek int `json:"dayOfWeek"` // 0=Sunday, 1=Monday, etc. Open string `json:"open"` // HH:MM format Close string `json:"close"` // HH:MM format IsOpen bool `json:"isOpen"` } type UpdateWorkingHoursRequest struct { Open string `json:"open,omitempty"` Close string `json:"close,omitempty"` IsOpen *bool `json:"isOpen,omitempty"` } // ============================================ // EMAIL TEMPLATE MODELS // ============================================ type EmailTemplate struct { ID string `json:"id"` TenantID string `json:"tenantId"` Type string `json:"type"` // booking_confirmation, reminder, cancellation, etc. Subject string `json:"subject"` BodyHTML string `json:"bodyHtml"` BodyText string `json:"bodyText"` IsEnabled bool `json:"isEnabled"` } type SendEmailRequest struct { To string `json:"to" binding:"required,email"` Subject string `json:"subject" binding:"required"` Body string `json:"body" binding:"required"` Data map[string]string `json:"data,omitempty"` // Template variables } type EmailNotification struct { ID string `json:"id"` TenantID string `json:"tenantId"` BookingID string `json:"bookingId,omitempty"` Channel string `json:"channel"` // email, sms Type string `json:"type"` // confirmation, reminder, cancellation Recipient string `json:"recipient"` Status string `json:"status"` // pending, sent, failed SentAt *time.Time `json:"sentAt,omitempty"` Error string `json:"error,omitempty"` CreatedAt time.Time `json:"createdAt"` } // ============================================ // SMS MODELS // ============================================ type SMSSettings struct { Enabled bool `json:"enabled"` SenderName string `json:"senderName,omitempty"` MonthlyLimit int `json:"monthlyLimit,omitempty"` MessagesSent int `json:"messagesSent"` TotalCostCents int `json:"totalCostCents"` Available bool `json:"available"` } type UpdateSMSSettingsRequest struct { Enabled bool `json:"enabled"` SenderName string `json:"senderName,omitempty"` MonthlyLimit int `json:"monthlyLimit,omitempty"` } type SendSMSRequest struct { To string `json:"to" binding:"required"` Body string `json:"body" binding:"required,max=1000"` } type SendSMSResponse struct { LogID string `json:"logId"` MessageID string `json:"messageId,omitempty"` RequestID string `json:"requestId,omitempty"` Status string `json:"status"` CostCents int `json:"costCents"` } type SMSUsageLog struct { ID string `json:"id"` RecipientPhone string `json:"recipientPhone"` MessageBody string `json:"messageBody,omitempty"` Status string `json:"status"` CostCents int `json:"costCents"` CreatedAt time.Time `json:"createdAt"` } type SMSUsageReport struct { YearMonth string `json:"yearMonth"` MessageCount int `json:"messageCount"` TotalCostCents int `json:"totalCostCents"` StripeInvoiceID string `json:"stripeInvoiceId,omitempty"` InvoiceSentAt *time.Time `json:"invoiceSentAt,omitempty"` } type SMSInvoiceBatchResponse struct { YearMonth string `json:"yearMonth"` ProcessedCount int `json:"processedCount"` FailedCount int `json:"failedCount"` }