Interfaces TypeScript
Esta página documenta todas las interfaces TypeScript utilizadas en Cannahub. Estos tipos representan el modelo de dominio de la aplicación y son el resultado de las transformaciones aplicadas a los datos de Medusa.
Usuario (User)
La interfaz principal para representar usuarios en el sistema, ya sean miembros, administradores o staff.
- Name
id- Type
- string
- Description
Identificador único del usuario (Medusa customer/user ID).
- Name
email- Type
- string
- Description
Email del usuario. Debe ser único por organización.
- Name
firstName- Type
- string
- Description
Nombre del usuario.
- Name
lastName- Type
- string
- Description
Apellido del usuario.
- Name
phone- Type
- string
- Description
Número de teléfono con código de país.
- Name
role- Type
- Role
- Description
Rol del usuario en el sistema.
- Name
status- Type
- MemberStatus
- Description
Estado actual del miembro en el club.
- Name
membership- Type
- UserMembership
- Description
Información de la membresía activa.
- Name
medicalRecord- Type
- MedicalRecord
- Description
Expediente médico del usuario.
- Name
addresses- Type
- Address[]
- Description
Direcciones de envío registradas.
- Name
onboardingStep- Type
- OnboardingStep
- Description
Paso actual en el proceso de onboarding.
- Name
createdAt- Type
- Date
- Description
Fecha de creación del usuario.
- Name
updatedAt- Type
- Date
- Description
Fecha de última actualización.
Interface User
interface User {
id: string
email: string
firstName: string
lastName: string
phone: string
role: Role
status: MemberStatus
membership?: UserMembership
medicalRecord?: MedicalRecord
addresses: Address[]
onboardingStep?: OnboardingStep
avatar?: string
bornDate?: string
document?: string
hasReprocann?: boolean
permissions?: string[]
createdAt: Date
updatedAt: Date
}
Roles (Role)
Enum que define los diferentes roles de usuario en el sistema. Los valores utilizan minúsculas.
Roles Principales
- Name
root- Type
- 0
- Description
Super administrador de plataforma. Acceso total.
- Name
admin- Type
- 1
- Description
Administrador de club. Gestión completa del club.
- Name
doctor- Type
- 2
- Description
Profesional médico. Acceso a pacientes y prescripciones.
- Name
member- Type
- 3
- Description
Miembro del club. Acceso al dispensario.
Roles de Staff
- Name
president- Type
- staff
- Description
Presidente de la asociación civil.
- Name
secretary- Type
- staff
- Description
Secretario. Acceso a lectura/escritura de miembros.
- Name
treasurer- Type
- staff
- Description
Tesorero. Acceso a órdenes y analytics.
- Name
grower- Type
- staff
- Description
Cultivador. Gestión de cultivos y cosechas.
- Name
trimmer- Type
- staff
- Description
Procesador. Procesamiento de productos e inventario.
- Name
technical_manager- Type
- staff
- Description
Director técnico.
- Name
medical_director- Type
- staff
- Description
Director médico.
Enum Role
enum Role {
ROOT = 'root',
ADMIN = 'admin',
STAFF = 'staff',
DOCTOR = 'doctor',
MEMBER = 'member',
PRESIDENT = 'president',
SECRETARY = 'secretary',
TREASURER = 'treasurer',
VOCAL = 'vocal',
VOCAL_ALTERNATE = 'vocal_alternate',
ACCOUNT_REVIEWER = 'account_reviewer',
ACCOUNT_REVIEWER_ALTERNATE = 'account_reviewer_alternate',
GROWER = 'grower',
TRIMMER = 'trimmer',
TECHNICAL_MANAGER = 'technical_manager',
MEDICAL_DIRECTOR = 'medical_director'
}
El control de acceso actualmente se basa en roles. El sistema de permisos granulares está planificado para una próxima versión.
Estado de Miembro (MemberStatus)
Enum que define los posibles estados de un miembro en el club.
- Name
INVITED- Type
- initial
- Description
Invitación enviada, aún no registrado.
- Name
IN_REVIEW- Type
- pending
- Description
Registro recibido, pendiente de aprobación.
- Name
APPROVED- Type
- approved
- Description
Aprobado, completando wizard de activación.
- Name
IN_PROGRESS- Type
- onboarding
- Description
Completando proceso de onboarding.
- Name
ACTIVE- Type
- active
- Description
Acceso completo al dispensario.
- Name
DEBTOR- Type
- warning
- Description
Pago pendiente, acceso limitado.
- Name
INACTIVE- Type
- suspended
- Description
Suspendido o desactivado.
Enum MemberStatus
enum MemberStatus {
INVITED = 'INVITED',
IN_REVIEW = 'IN_REVIEW',
APPROVED = 'APPROVED',
IN_PROGRESS = 'IN_PROGRESS',
ACTIVE = 'ACTIVE',
DEBTOR = 'DEBTOR',
INACTIVE = 'INACTIVE'
}
Transiciones de estado
const statusTransitions = {
INVITED: ['IN_REVIEW'],
IN_REVIEW: ['APPROVED', 'INACTIVE'],
APPROVED: ['IN_PROGRESS'],
IN_PROGRESS: ['ACTIVE'],
ACTIVE: ['DEBTOR', 'INACTIVE'],
DEBTOR: ['ACTIVE', 'INACTIVE'],
INACTIVE: ['IN_REVIEW']
}
Expediente Médico (MedicalRecord)
Información médica del usuario requerida para el uso de cannabis medicinal.
- Name
reprocannCode- Type
- string
- Description
Código de registro REPROCANN.
- Name
reprocannExpiration- Type
- Date
- Description
Fecha de vencimiento del código REPROCANN.
- Name
allergies- Type
- string[]
- Description
Lista de alergias conocidas.
- Name
diseases- Type
- string[]
- Description
Enfermedades o condiciones médicas.
- Name
medications- Type
- string[]
- Description
Medicamentos actuales.
- Name
treatments- Type
- string[]
- Description
Tratamientos en curso.
- Name
diagnostic- Type
- string[]
- Description
Diagnósticos médicos.
- Name
cannabisUses- Type
- string[]
- Description
Usos terapéuticos del cannabis.
- Name
emergencyContact- Type
- EmergencyContact
- Description
Contacto de emergencia.
Interface MedicalRecord
interface MedicalRecord {
reprocannCode?: string
reprocannExpiration?: Date
allergies: string[]
diseases: string[]
medications: string[]
treatments: string[]
diagnostic: string[]
cannabisUses: string[]
emergencyContact: {
name: string
phoneNumber: string
relationship: string
}
}
Ejemplo
{
"reprocannCode": "REPRO-2024-AR-001234",
"reprocannExpiration": "2025-01-15",
"allergies": ["Polen", "Penicilina"],
"diseases": ["Ansiedad crónica", "Insomnio"],
"medications": ["Sertralina 50mg"],
"treatments": ["Terapia cognitiva"],
"diagnostic": ["Trastorno de ansiedad generalizada"],
"cannabisUses": [
"Manejo de ansiedad",
"Mejora del sueño"
],
"emergencyContact": {
"name": "Carlos González",
"phoneNumber": "+541145678902",
"relationship": "Hermano"
}
}
Producto (Product)
Representa un producto en el catálogo del dispensario.
- Name
id- Type
- string
- Description
Identificador único del producto.
- Name
name- Type
- string
- Description
Nombre del producto (título en Medusa).
- Name
description- Type
- string
- Description
Descripción completa del producto.
- Name
handle- Type
- string
- Description
Slug URL-friendly del producto.
- Name
status- Type
- 'draft' | 'published'
- Description
Estado de publicación.
- Name
imageUrl- Type
- string
- Description
URL de la imagen principal (thumbnail).
- Name
images- Type
- string[]
- Description
URLs de todas las imágenes.
- Name
variants- Type
- ProductVariant[]
- Description
Variantes/fracciones del producto.
- Name
strain- Type
- Strain
- Description
Información de la cepa (solo flores).
- Name
category- Type
- string
- Description
Categoría del producto.
- Name
isFlower- Type
- boolean
- Description
Indica si es un producto de flor.
- Name
price- Type
- number
- Description
Precio base (menor de las variantes).
- Name
discountPrice- Type
- number
- Description
Precio con descuento si aplica.
- Name
inventoryQuantity- Type
- number
- Description
Stock total disponible.
Interface Product
interface Product {
id: string
name: string
description: string
handle: string
status: 'draft' | 'published'
imageUrl: string
images: string[]
variants: ProductVariant[]
strain?: Strain
category: string
isFlower: boolean
price: number
discountPrice?: number
currency: string
inventoryQuantity: number
manageInventory: boolean
metadata: ProductMetadata
}
Variante de Producto (ProductVariant)
Representa una fracción o variante de un producto (ej: 1g, 5g, 7g).
- Name
id- Type
- string
- Description
Identificador único de la variante.
- Name
name- Type
- string
- Description
Nombre de la variante (ej: "Blue Dream 5g").
- Name
sku- Type
- string
- Description
Código SKU único.
- Name
weight- Type
- number
- Description
Peso en gramos por unidad.
- Name
inventoryQuantity- Type
- number
- Description
Unidades disponibles.
- Name
inventoryTotal- Type
- number
- Description
Total en gramos (quantity × weight).
- Name
price- Type
- number
- Description
Precio base de la variante.
- Name
discountPrice- Type
- number
- Description
Precio con descuento.
- Name
discountPercentage- Type
- number
- Description
Porcentaje de descuento aplicado.
- Name
prices- Type
- VariantPrice[]
- Description
Precios por lista de precios.
Interface ProductVariant
interface ProductVariant {
id: string
name: string
sku: string
weight: number
inventoryQuantity: number
inventoryTotal: number
price: number
discountPrice?: number
discountPercentage?: number
currencyCode: string
priceListId: string
priceListName?: string
prices: VariantPrice[]
quantity: number
metadata: {
weight: number
unit: 'grams' | 'ml' | 'units'
}
}
interface VariantPrice {
id: string
price: number
priceList: {
id: string
name: string
}
currency: string
createdAt: string
}
Cepa (Strain)
Información detallada sobre una cepa de cannabis.
- Name
id- Type
- string
- Description
Identificador único de la cepa.
- Name
name- Type
- string
- Description
Nombre de la cepa.
- Name
type- Type
- 'sativa' | 'indica' | 'hybrid'
- Description
Tipo genético de la cepa.
- Name
cannabinoids- Type
- Cannabinoids
- Description
Contenido de cannabinoides (THC, CBD, CBG).
- Name
terpenes- Type
- string[]
- Description
Terpenos presentes en la cepa.
- Name
effects- Type
- Effects
- Description
Efectos reportados de la cepa.
- Name
flavors- Type
- string[]
- Description
Sabores y aromas.
- Name
genetics- Type
- Genetics
- Description
Información genética (padres, hijos).
- Name
growInfo- Type
- GrowInfo
- Description
Información de cultivo.
Interface Strain
interface Strain {
id: string
name: string
altNames?: string
type: 'sativa' | 'indica' | 'hybrid'
description?: string
cannabinoids: {
thc: number
cbd: number
cbg?: number
cbn?: number
}
terpenes: string[]
effects: {
helpsWith: string[]
feelings: string[]
negatives: string[]
}
flavors: string[]
genetics: {
parents: string[]
children: string[]
breeder?: string
}
growInfo?: {
difficulty: 'easy' | 'moderate' | 'hard'
floweringTime: {
min: number
max: number
}
yield: {
indoor: string
outdoor: string
}
height: string
type: 'indoor' | 'outdoor' | 'both'
}
}
Pedido (Order)
Representa un pedido/dispensación en el sistema.
- Name
id- Type
- string
- Description
Identificador único del pedido.
- Name
displayId- Type
- string
- Description
Número de pedido para mostrar.
- Name
status- Type
- OrderStatus
- Description
Estado general del pedido.
- Name
fulfillmentStatus- Type
- FulfillmentStatus
- Description
Estado de fulfillment.
- Name
paymentStatus- Type
- PaymentStatus
- Description
Estado del pago.
- Name
customer- Type
- User
- Description
Cliente que realizó el pedido.
- Name
items- Type
- OrderItem[]
- Description
Items del pedido.
- Name
payments- Type
- OrderPayment[]
- Description
Pagos asociados.
- Name
total- Type
- number
- Description
Total del pedido.
- Name
shippingAddress- Type
- Address
- Description
Dirección de envío.
- Name
createdAt- Type
- Date
- Description
Fecha de creación.
Interface Order
interface Order {
id: string
displayId: string
status: OrderStatus
fulfillmentStatus: FulfillmentStatus
paymentStatus: PaymentStatus
customer: User
items: OrderItem[]
payments: OrderPayment[]
subtotal: number
shippingTotal: number
taxTotal: number
total: number
currency: string
shippingAddress?: Address
billingAddress?: Address
shippingMethod?: ShippingMethod
metadata: OrderMetadata
activityLogs?: ActivityLog[]
createdAt: Date
updatedAt: Date
}
interface OrderItem {
id: string
title: string
description?: string
thumbnail?: string
variantId: string
quantity: number
unitPrice: number
total: number
metadata?: Record<string, any>
}
Estados de Pedido
OrderStatus
- Name
pending- Type
- initial
- Description
Pedido creado, pendiente de procesamiento.
- Name
requires_action- Type
- action
- Description
Requiere acción del usuario o admin.
- Name
completed- Type
- final
- Description
Pedido completado exitosamente.
- Name
canceled- Type
- final
- Description
Pedido cancelado.
FulfillmentStatus
- Name
not_fulfilled- Type
- initial
- Description
No procesado aún.
- Name
partially_fulfilled- Type
- partial
- Description
Parcialmente procesado.
- Name
fulfilled- Type
- complete
- Description
Completamente procesado.
- Name
shipped- Type
- shipped
- Description
Enviado/entregado.
PaymentStatus
- Name
not_paid- Type
- initial
- Description
Sin pago registrado.
- Name
awaiting- Type
- pending
- Description
Esperando confirmación de pago.
- Name
captured- Type
- paid
- Description
Pago capturado/confirmado.
- Name
refunded- Type
- refund
- Description
Pago reembolsado.
Enums de Estado
enum OrderStatus {
PENDING = 'pending',
REQUIRES_ACTION = 'requires_action',
COMPLETED = 'completed',
CANCELED = 'canceled'
}
enum FulfillmentStatus {
NOT_FULFILLED = 'not_fulfilled',
PARTIALLY_FULFILLED = 'partially_fulfilled',
FULFILLED = 'fulfilled',
SHIPPED = 'shipped',
RETURNED = 'returned',
CANCELED = 'canceled'
}
enum PaymentStatus {
NOT_PAID = 'not_paid',
AWAITING = 'awaiting',
CAPTURED = 'captured',
PARTIALLY_REFUNDED = 'partially_refunded',
REFUNDED = 'refunded'
}
Membresía (Membership)
Representa un tipo de membresía del club.
- Name
id- Type
- string
- Description
Identificador único (customer group ID).
- Name
name- Type
- string
- Description
Nombre de la membresía.
- Name
description- Type
- string
- Description
Descripción de beneficios.
- Name
price- Type
- number
- Description
Precio mensual/anual.
- Name
currency- Type
- string
- Description
Moneda del precio.
- Name
benefits- Type
- string[]
- Description
Lista de beneficios incluidos.
- Name
limits- Type
- MembershipLimits
- Description
Límites de compra.
- Name
priceListId- Type
- string
- Description
Lista de precios asociada.
- Name
isActive- Type
- boolean
- Description
Si la membresía está activa.
Interface Membership
interface Membership {
id: string
name: string
description: string
price: number
currency: string
benefits: string[]
limits?: {
monthlyPurchase?: number
productAccess?: string[]
}
priceListId: string
isActive: boolean
sortOrder: number
color?: string
metadata: Record<string, any>
}
interface UserMembership {
id: string
name: string
status: 'PAID' | 'PENDING' | 'EXPIRED'
dueDate?: string
expirationDate: string
paymentMethod?: string
price: number
}
Inventario (Inventory)
Representa el stock de un producto por ubicación.
- Name
productId- Type
- string
- Description
ID del producto.
- Name
variantId- Type
- string
- Description
ID de la variante.
- Name
locationId- Type
- string
- Description
ID de la ubicación de stock.
- Name
locationName- Type
- string
- Description
Nombre de la ubicación.
- Name
quantity- Type
- number
- Description
Cantidad en stock.
- Name
reservedQuantity- Type
- number
- Description
Cantidad reservada por pedidos.
- Name
availableQuantity- Type
- number
- Description
Cantidad disponible para venta.
Interface ProductLocationStock
interface ProductLocationStock {
productId: string
variantId: string
inventoryItemId: string
locationId: string
locationName: string
quantity: number
reservedQuantity: number
availableQuantity: number
incomingQuantity: number
}
interface InventoryLevel {
id: string
inventoryItemId: string
locationId: string
stockedQuantity: number
reservedQuantity: number
incomingQuantity: number
metadata?: Record<string, any>
}
Dirección (Address)
Representa una dirección de envío o facturación.
- Name
id- Type
- string
- Description
Identificador único.
- Name
firstName- Type
- string
- Description
Nombre del destinatario.
- Name
lastName- Type
- string
- Description
Apellido del destinatario.
- Name
address1- Type
- string
- Description
Dirección línea 1.
- Name
address2- Type
- string
- Description
Dirección línea 2 (piso, depto).
- Name
city- Type
- string
- Description
Ciudad.
- Name
province- Type
- string
- Description
Provincia/Estado.
- Name
postalCode- Type
- string
- Description
Código postal.
- Name
countryCode- Type
- string
- Description
Código de país (ISO 3166-1 alpha-2).
- Name
phone- Type
- string
- Description
Teléfono de contacto.
Interface Address
interface Address {
id: string
firstName: string
lastName: string
address1: string
address2?: string
city: string
province: string
postalCode: string
countryCode: string
phone?: string
company?: string
metadata?: Record<string, any>
}
Ejemplo
{
"id": "addr_01HQ9XYZ789",
"firstName": "María",
"lastName": "González",
"address1": "Av. Corrientes 1234",
"address2": "Piso 5, Depto A",
"city": "Buenos Aires",
"province": "CABA",
"postalCode": "C1043",
"countryCode": "AR",
"phone": "+541145678901"
}
Pasos de Onboarding (OnboardingStep)
Enum que define los pasos del proceso de onboarding.
- Name
PhoneVerification- Type
- 1
- Description
Verificación de teléfono por SMS.
- Name
HasReprocann- Type
- 2
- Description
Pregunta si tiene REPROCANN.
- Name
PersonalInformation- Type
- 3
- Description
Datos personales completos.
- Name
Schedule- Type
- 4
- Description
Agendar consulta médica (sin REPROCANN).
- Name
Payment- Type
- 5
- Description
Pago de consulta (sin REPROCANN).
- Name
ReprocannSyncCode- Type
- 6
- Description
Vincular código REPROCANN (con REPROCANN).
- Name
MedicalConsultation- Type
- 7
- Description
Consulta médica realizada.
- Name
DocumentSigning- Type
- 8
- Description
Firma de documentos legales.
- Name
ReprocannPending- Type
- 9
- Description
Esperando aprobación REPROCANN.
- Name
MembershipSelection- Type
- 10
- Description
Selección de membresía.
- Name
Done- Type
- final
- Description
Onboarding completado.
Enum OnboardingStep
enum OnboardingStep {
PhoneVerification = 'PhoneVerification',
HasReprocann = 'HasReprocann',
PersonalInformation = 'PersonalInformation',
Schedule = 'Schedule',
Payment = 'Payment',
ReprocannSyncCode = 'ReprocannSyncCode',
MedicalConsultation = 'MedicalConsultation',
DocumentSigning = 'DocumentSigning',
ReprocannPending = 'ReprocannPending',
Contract = 'Contract',
MembershipSelection = 'MembershipSelection',
Done = 'Done'
}
Estado de Membresía de Usuario (UserMembershipStatus)
Enum que define los estados de la membresía de un usuario específico.
- Name
PAID- Type
- active
- Description
Membresía pagada y activa.
- Name
PENDING- Type
- pending
- Description
Pago pendiente, acceso limitado.
- Name
EXPIRED- Type
- expired
- Description
Membresía vencida.
- Name
INACTIVE- Type
- inactive
- Description
Membresía desactivada manualmente.
Este enum es diferente a MemberStatus. MemberStatus representa el estado del usuario en el club, mientras que UserMembershipStatus representa el estado específico de su suscripción/membresía.
Enum UserMembershipStatus
enum UserMembershipStatus {
PAID = 'PAID',
PENDING = 'PENDING',
EXPIRED = 'EXPIRED',
INACTIVE = 'INACTIVE'
}
Uso en UserMembership
interface UserMembership {
id: string
name: string
status: UserMembershipStatus
dueDate?: string
expirationDate: string
paymentMethod?: string
price: number
benefits: string[]
}
// Validación de acceso
const canAccessDispensary = (
membership: UserMembership
): boolean => {
return membership.status === 'PAID'
&& new Date(membership.expirationDate) > new Date()
}
Organizaciones (Organizations)
Enum con los slugs de las organizaciones/clubs soportados en Cannahub.
- Name
high-up- Type
- club
- Description
High Up Cannabis Club - Buenos Aires.
- Name
don-marcelino- Type
- club
- Description
Don Marcelino - Córdoba.
- Name
circulo-rojo- Type
- club
- Description
Círculo Rojo - Buenos Aires.
- Name
superfly- Type
- club
- Description
Superfly Club - Buenos Aires.
- Name
blow- Type
- club
- Description
Blow Cannabis - Buenos Aires.
- Name
weplant- Type
- club
- Description
WePlant - Buenos Aires.
- Name
growcast- Type
- platform
- Description
GrowCast - Plataforma de cultivo.
Identificación de Organización
La organización se identifica de varias formas:
- Subdomain:
high-up.cannahub.tech - Sales Channel ID: Asociado en Medusa
- Header:
x-organization-slug
Enum Organizations
enum Organizations {
HIGH_UP = 'high-up',
DON_MARCELINO = 'don-marcelino',
CIRCULO_ROJO = 'circulo-rojo',
SUPERFLY = 'superfly',
BLOW = 'blow',
WEPLANT = 'weplant',
GROWCAST = 'growcast'
}
Configuración por organización
interface OrganizationConfig {
slug: Organizations
name: string
salesChannelId: string
stockLocations: string[]
priceLists: string[]
features: {
dispensary: boolean
cultivation: boolean
medical: boolean
ecommerce: boolean
}
}
// Ejemplo de extracción desde subdomain
const getOrganizationFromHost = (
host: string
): Organizations | null => {
const subdomain = host.split('.')[0]
return Object.values(Organizations)
.includes(subdomain as Organizations)
? subdomain as Organizations
: null
}
Constantes cross-tenant
const CROSS_TENANT = {
salesChannelId: 'sc_01KBCZXJCPVWX8REW8880R45SW',
defaultShippingProfileId: 'sp_01KBCZX7ZEE2571TQ0V6XPNV8Q',
pickupShippingProfileId: 'sp_01KC00JHPV8WWY8PYC1J775TWW',
shippingOptionId: 'so_01KC04W7SNF3BF3T1WZ2V4735H',
fulfillmentProviderId: 'manual_manual',
shippingOptionTypeId: 'sotype_01KC04MKNR2Z2KS3R43JJEAZXV'
}
Método de Pago (PaymentMethod)
Enum que define los métodos de pago disponibles.
- Name
CASH- Type
- presencial
- Description
Pago en efectivo al momento de retiro.
- Name
MERCADOPAGO- Type
- digital
- Description
Pago online vía MercadoPago.
- Name
TRANSFER- Type
- digital
- Description
Transferencia bancaria.
- Name
CRYPTO- Type
- digital
- Description
Pago con criptomonedas (según club).
Enum PaymentMethod
enum PaymentMethod {
CASH = 'cash',
MERCADOPAGO = 'mercadopago',
TRANSFER = 'transfer',
CRYPTO = 'crypto'
}
Uso en Order
interface OrderPayment {
id: string
method: PaymentMethod
amount: number
currency: string
status: PaymentStatus
providerId?: string
externalId?: string
metadata?: {
mercadopagoPaymentId?: string
transferReference?: string
}
}
Método de Envío (ShippingMethod)
Enum que define los métodos de envío disponibles.
- Name
PICKUP- Type
- presencial
- Description
Retiro en el dispensario.
- Name
DELIVERY- Type
- delivery
- Description
Envío a domicilio (donde esté habilitado).
La mayoría de los clubs solo permiten PICKUP debido a regulaciones. El método DELIVERY está disponible solo en clubs con autorización específica.
Enum ShippingMethod
enum ShippingMethod {
PICKUP = 'pickup',
DELIVERY = 'delivery'
}
Verificación de disponibilidad
const isShippingAvailable = (
location: StockLocation,
method: ShippingMethod
): boolean => {
if (method === 'pickup') {
return location.metadata?.isPickupEnabled ?? true
}
if (method === 'delivery') {
return location.metadata?.isShippingEnabled ?? false
}
return false
}