package domain import ( "time" "github.com/gofrs/uuid/v5" ) // Tenant represents a B2B actor (pharmacy/distributor) in the marketplace. type Tenant struct { ID uuid.UUID `db:"id" json:"id"` CNPJ string `db:"cnpj" json:"cnpj"` CorporateName string `db:"corporate_name" json:"corporate_name"` Category string `db:"category" json:"category"` // farmacia, distribuidora LicenseNumber string `db:"license_number" json:"license_number"` IsVerified bool `db:"is_verified" json:"is_verified"` // Location Latitude float64 `db:"latitude" json:"latitude"` Longitude float64 `db:"longitude" json:"longitude"` City string `db:"city" json:"city"` State string `db:"state" json:"state"` CreatedAt time.Time `db:"created_at" json:"created_at"` UpdatedAt time.Time `db:"updated_at" json:"updated_at"` } // Company is an alias for Tenant for backward compatibility. type Company = Tenant // User represents an authenticated actor inside a company. type User struct { ID uuid.UUID `db:"id" json:"id"` CompanyID uuid.UUID `db:"company_id" json:"company_id"` Role string `db:"role" json:"role"` Name string `db:"name" json:"name"` Email string `db:"email" json:"email"` PasswordHash string `db:"password_hash" json:"-"` CreatedAt time.Time `db:"created_at" json:"created_at"` UpdatedAt time.Time `db:"updated_at" json:"updated_at"` } // UserFilter captures listing constraints. type UserFilter struct { CompanyID *uuid.UUID Limit int Offset int } // UserPage wraps paginated results. type UserPage struct { Users []User `json:"users"` Total int64 `json:"total"` Page int `json:"page"` PageSize int `json:"page_size"` } // Product represents a medicine SKU with batch tracking. type Product struct { ID uuid.UUID `db:"id" json:"id"` SellerID uuid.UUID `db:"seller_id" json:"seller_id"` Name string `db:"name" json:"name"` Description string `db:"description" json:"description"` Batch string `db:"batch" json:"batch"` ExpiresAt time.Time `db:"expires_at" json:"expires_at"` PriceCents int64 `db:"price_cents" json:"price_cents"` Stock int64 `db:"stock" json:"stock"` CreatedAt time.Time `db:"created_at" json:"created_at"` UpdatedAt time.Time `db:"updated_at" json:"updated_at"` } // InventoryItem exposes stock tracking tied to product batches. type InventoryItem struct { ProductID uuid.UUID `db:"product_id" json:"product_id"` SellerID uuid.UUID `db:"seller_id" json:"seller_id"` Name string `db:"name" json:"name"` Batch string `db:"batch" json:"batch"` ExpiresAt time.Time `db:"expires_at" json:"expires_at"` Quantity int64 `db:"quantity" json:"quantity"` PriceCents int64 `db:"price_cents" json:"price_cents"` UpdatedAt time.Time `db:"updated_at" json:"updated_at"` } // InventoryFilter allows filtering by expiration window with pagination. type InventoryFilter struct { ExpiringBefore *time.Time SellerID *uuid.UUID Limit int Offset int } // InventoryPage wraps paginated inventory results. type InventoryPage struct { Items []InventoryItem `json:"items"` Total int64 `json:"total"` Page int `json:"page"` PageSize int `json:"page_size"` } // ProductFilter captures product listing constraints. type ProductFilter struct { SellerID *uuid.UUID Category string Search string Limit int Offset int } // ProductPage wraps paginated product results. type ProductPage struct { Products []Product `json:"products"` Total int64 `json:"total"` Page int `json:"page"` PageSize int `json:"page_size"` } // CompanyFilter captures company/tenant listing constraints. type CompanyFilter struct { Category string Search string City string State string Limit int Offset int } // TenantFilter is an alias for CompanyFilter. type TenantFilter = CompanyFilter // CompanyPage wraps paginated company/tenant results. type CompanyPage struct { Companies []Company `json:"tenants"` Total int64 `json:"total"` Page int `json:"page"` PageSize int `json:"page_size"` } // TenantPage is an alias for CompanyPage. type TenantPage = CompanyPage // OrderFilter captures order listing constraints. type OrderFilter struct { BuyerID *uuid.UUID SellerID *uuid.UUID Status OrderStatus Limit int Offset int } // OrderPage wraps paginated order results. type OrderPage struct { Orders []Order `json:"orders"` Total int64 `json:"total"` Page int `json:"page"` PageSize int `json:"page_size"` } // InventoryAdjustment records manual stock corrections. type InventoryAdjustment struct { ID uuid.UUID `db:"id" json:"id"` ProductID uuid.UUID `db:"product_id" json:"product_id"` Delta int64 `db:"delta" json:"delta"` Reason string `db:"reason" json:"reason"` CreatedAt time.Time `db:"created_at" json:"created_at"` } // Order captures the status lifecycle and payment intent. type Order struct { ID uuid.UUID `db:"id" json:"id"` BuyerID uuid.UUID `db:"buyer_id" json:"buyer_id"` SellerID uuid.UUID `db:"seller_id" json:"seller_id"` Status OrderStatus `db:"status" json:"status"` TotalCents int64 `db:"total_cents" json:"total_cents"` Items []OrderItem `json:"items"` Shipping ShippingAddress `json:"shipping"` CreatedAt time.Time `db:"created_at" json:"created_at"` UpdatedAt time.Time `db:"updated_at" json:"updated_at"` } // OrderItem stores SKU-level batch tracking. type OrderItem struct { ID uuid.UUID `db:"id" json:"id"` OrderID uuid.UUID `db:"order_id" json:"order_id"` ProductID uuid.UUID `db:"product_id" json:"product_id"` Quantity int64 `db:"quantity" json:"quantity"` UnitCents int64 `db:"unit_cents" json:"unit_cents"` Batch string `db:"batch" json:"batch"` ExpiresAt time.Time `db:"expires_at" json:"expires_at"` } // PaymentPreference wraps the data needed for Mercado Pago split payments. type PaymentPreference struct { OrderID uuid.UUID `json:"order_id"` Gateway string `json:"gateway"` CommissionPct float64 `json:"commission_pct"` MarketplaceFee int64 `json:"marketplace_fee"` SellerReceivable int64 `json:"seller_receivable"` PaymentURL string `json:"payment_url"` } // PaymentWebhookEvent represents Mercado Pago notifications with split amounts. type PaymentWebhookEvent struct { PaymentID string `json:"payment_id"` OrderID uuid.UUID `json:"order_id"` Status string `json:"status"` MarketplaceFee int64 `json:"marketplace_fee"` SellerAmount int64 `json:"seller_amount"` TotalPaidAmount int64 `json:"total_paid_amount"` } // PaymentSplitResult echoes the amounts distributed between actors. type PaymentSplitResult struct { OrderID uuid.UUID `json:"order_id"` PaymentID string `json:"payment_id"` Status string `json:"status"` MarketplaceFee int64 `json:"marketplace_fee"` SellerReceivable int64 `json:"seller_receivable"` TotalPaidAmount int64 `json:"total_paid_amount"` } // ShippingAddress captures delivery details at order time. type ShippingAddress struct { RecipientName string `json:"recipient_name" db:"shipping_recipient_name"` Street string `json:"street" db:"shipping_street"` Number string `json:"number" db:"shipping_number"` Complement string `json:"complement,omitempty" db:"shipping_complement"` District string `json:"district" db:"shipping_district"` City string `json:"city" db:"shipping_city"` State string `json:"state" db:"shipping_state"` ZipCode string `json:"zip_code" db:"shipping_zip_code"` Country string `json:"country" db:"shipping_country"` } // Shipment stores freight label data and tracking linkage. type Shipment struct { ID uuid.UUID `db:"id" json:"id"` OrderID uuid.UUID `db:"order_id" json:"order_id"` Carrier string `db:"carrier" json:"carrier"` TrackingCode string `db:"tracking_code" json:"tracking_code"` ExternalTracking string `db:"external_tracking" json:"external_tracking"` Status string `db:"status" json:"status"` CreatedAt time.Time `db:"created_at" json:"created_at"` UpdatedAt time.Time `db:"updated_at" json:"updated_at"` } // OrderStatus enumerates supported transitions. type OrderStatus string const ( OrderStatusPending OrderStatus = "Pendente" OrderStatusPaid OrderStatus = "Pago" OrderStatusInvoiced OrderStatus = "Faturado" OrderStatusDelivered OrderStatus = "Entregue" ) // CartItem stores buyer selections with unit pricing. type CartItem struct { ID uuid.UUID `db:"id" json:"id"` BuyerID uuid.UUID `db:"buyer_id" json:"buyer_id"` ProductID uuid.UUID `db:"product_id" json:"product_id"` Quantity int64 `db:"quantity" json:"quantity"` UnitCents int64 `db:"unit_cents" json:"unit_cents"` ProductName string `db:"product_name" json:"product_name"` Batch string `db:"batch" json:"batch"` ExpiresAt time.Time `db:"expires_at" json:"expires_at"` CreatedAt time.Time `db:"created_at" json:"created_at"` UpdatedAt time.Time `db:"updated_at" json:"updated_at"` } // CartSummary aggregates cart totals and discounts. type CartSummary struct { Items []CartItem `json:"items"` SubtotalCents int64 `json:"subtotal_cents"` DiscountCents int64 `json:"discount_cents"` TotalCents int64 `json:"total_cents"` DiscountReason string `json:"discount_reason,omitempty"` } // Review captures the buyer feedback for a completed order. type Review struct { ID uuid.UUID `db:"id" json:"id"` OrderID uuid.UUID `db:"order_id" json:"order_id"` BuyerID uuid.UUID `db:"buyer_id" json:"buyer_id"` SellerID uuid.UUID `db:"seller_id" json:"seller_id"` Rating int `db:"rating" json:"rating"` Comment string `db:"comment" json:"comment"` CreatedAt time.Time `db:"created_at" json:"created_at"` } // CompanyRating exposes the aggregate score for a seller or pharmacy. type CompanyRating struct { CompanyID uuid.UUID `json:"company_id"` AverageScore float64 `json:"average_score"` TotalReviews int64 `json:"total_reviews"` } // TopProduct aggregates seller performance per SKU. type TopProduct struct { ProductID uuid.UUID `json:"product_id"` Name string `json:"name"` TotalQuantity int64 `json:"total_quantity"` RevenueCents int64 `json:"revenue_cents"` } // SellerDashboard summarizes commercial metrics for sellers. type SellerDashboard struct { SellerID uuid.UUID `json:"seller_id"` TotalSalesCents int64 `json:"total_sales_cents"` OrdersCount int64 `json:"orders_count"` TopProducts []TopProduct `json:"top_products"` LowStockAlerts []Product `json:"low_stock_alerts"` } // AdminDashboard surfaces platform-wide KPIs. type AdminDashboard struct { GMVCents int64 `json:"gmv_cents"` NewCompanies int64 `json:"new_companies"` WindowStartAt time.Time `json:"window_start_at"` }