API ReferenceModels

Models

All data models are Codable structs in StaccatoCoffee/Models/. They map directly to Supabase database tables using CodingKeys for snake_case conversion.

Profile

File: Models/Profile.swift

PropertyTypeDB ColumnDescription
idStringidUUID, references auth.users
emailStringemailUser email
fullNameString?full_nameDisplay name
phoneString?phonePhone number
avatarUrlString?avatar_urlProfile image URL
birthdayString?birthdayBirthday string
roleUserRolerolecustomer, employee, or admin
createdAtDatecreated_atAccount creation date
updatedAtDateupdated_atLast update

Computed Properties:

  • displayName — fullName or email prefix or “Coffee Lover”
  • firstName — First word of fullName
  • isStaff — role == .employee || role == .admin
  • isAdmin — role == .admin

File: Models/MenuItem.swift

PropertyTypeDB ColumnDescription
idStringidUUID
categoryIdStringcategory_idFK to menu_categories
nameStringnameItem name
descriptionString?descriptionItem description
basePriceIntbase_pricePrice in cents
imageUrlString?image_urlItem image
starsToRedeemIntstars_to_redeemStars needed to redeem for free
isFeaturedBoolis_featuredShown on home page
isAvailableBoolis_availableCurrently available
sortOrderIntsort_orderDisplay order
nutritionInfoNutritionInfo?nutrition_infoJSONB nutrition data

Computed: starsEarned — (basePrice * 2) / 100 (2 stars per dollar)

MenuCategory: id, name, slug, description, imageUrl, sortOrder, isActive

MenuItemWithModifiers: Extends MenuItem with category: MenuCategory and modifierGroups: [ModifierGroupWithModifiers]

ModifierGroup: id, name, slug, isRequired, minSelections, maxSelections, sortOrder

  • Computed: isSingleSelect — maxSelections == 1

Modifier: id, groupId, name, priceAdjustment (cents), isDefault, isAvailable, sortOrder


Order

File: Models/Order.swift

PropertyTypeDB ColumnDescription
idStringidUUID
locationIdStringlocation_idFK to locations
userIdString?user_idFK to auth.users
orderNumberStringorder_numbere.g., “SC-A042”
statusOrderStatusstatusCurrent status
assignedToString?assigned_toStaff who claimed
claimedAtDate?claimed_atWhen claimed
subtotalIntsubtotalIn cents
taxInttaxIn cents
discountIntdiscountIn cents
tipInttipIn cents
totalInttotalIn cents
starsEarnedIntstars_earnedStars awarded
paymentMethodString?payment_methodPayment type
squarePaymentIdString?square_payment_idSquare payment ref
squareOrderIdString?square_order_idSquare order ref
idempotencyKeyString?idempotency_keyDuplicate prevention
versionIntversionOptimistic locking

OrderStatus

enum OrderStatus: String, Codable {
    case pending
    case inProgress = "in_progress"
    case ready
    case completed
    case cancelled
}

OrderItem

id, orderId, menuItemId, name, quantity, unitPrice, totalPrice, notes

OrderItemModifier

id, orderItemId, modifierId, name, priceAdjustment


CartItem

File: Models/CartItem.swift

PropertyTypeDescription
idStringUUID
menuItemIdStringReference to menu item
nameStringItem name
basePriceIntBase price in cents
quantityIntQuantity (mutable)
modifiers[CartItemModifier]Selected modifiers
notesString?Special instructions

Computed Properties:

  • totalPrice — (basePrice + modifierTotal) * quantity
  • unitPriceWithModifiers — basePrice + modifierTotal
  • starsEarned — (unitPriceWithModifiers * 2) / 100
  • totalStars — starsEarned * quantity

LoyaltyAccount

File: Models/LoyaltyAccount.swift

PropertyTypeDB ColumnDescription
idStringidUUID
userIdStringuser_idFK to auth.users
starsBalanceIntstars_balanceCurrent redeemable stars
lifetimeStarsIntlifetime_starsTotal ever earned
tierLoyaltyTiertiergreen, gold, platinum
tierExpiryDate?tier_expiryWhen tier expires

LoyaltyTier

CaseRequired StarsColor
.green0#22C55E
.gold300#EAB308
.platinum600#94A3B8

Reward

File: Models/Reward.swift

PropertyTypeDB ColumnDescription
idStringidUUID
nameStringnameReward name
descriptionString?descriptionDescription
starsRequiredIntstars_requiredCost in stars
rewardTypeRewardTypereward_typeType of reward
rewardValueRewardValue?reward_valueJSONB value config
minTierLoyaltyTiermin_tierMinimum tier required
isActiveBoolis_activeCurrently available