{"openapi":"3.0.3","info":{"title":"Restaurant SaaS API","version":"1.0.0","description":"Express + Prisma backend for a restaurant SaaS platform with businesses, locations, catalog, modifiers, pricing, and public menu endpoints."},"servers":[{"url":"https://apiv2.ordrz.com","description":"Current deployment"},{"url":"http://localhost:3000","description":"Local development server"}],"x-tagGroups":[{"name":"Platform","tags":["System","Auth"]},{"name":"Business Setup","tags":["Location","Category","Collections","Taxes"]},{"name":"Catalog","tags":["Menu","Modifiers","Products"]},{"name":"Commerce","tags":["Pricing","Public"]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}},"schemas":{"LoginRequest":{"type":"object","required":["email","password"],"properties":{"email":{"type":"string","format":"email"},"password":{"type":"string","minLength":6}}},"SignupRequest":{"type":"object","required":["businessName","email","password"],"properties":{"name":{"type":"string","minLength":2,"maxLength":100,"example":"Sholay4"},"businessName":{"type":"string","minLength":2,"maxLength":100},"businessSlug":{"type":"string","pattern":"^[a-z0-9]+(?:-[a-z0-9]+)*$","example":"pizza-palace","description":"Optional lowercase kebab-case slug. Auto-generated from businessName if omitted."},"defaultCurrency":{"type":"string","minLength":3,"maxLength":10,"example":"PKR","description":"Business-level default currency. New locations inherit this when currency is omitted."},"phoneNumber":{"type":"string","example":"+92-300-1234567"},"email":{"type":"string","format":"email"},"password":{"type":"string","minLength":6,"maxLength":100}}},"ErrorResponse":{"type":"object","required":["success","message"],"properties":{"success":{"type":"boolean","enum":[false]},"message":{"type":"string","example":"Validation failed"},"details":{"nullable":true,"type":"array","items":{"type":"object","required":["field","message"],"properties":{"field":{"type":"string","example":"supportedOrderTypes[2]"},"message":{"type":"string","example":"Order type is not correct"}}}}}},"LocationRequest":{"type":"object","required":["name","slug","timezone"],"properties":{"name":{"type":"string","minLength":2},"slug":{"type":"string","minLength":2,"maxLength":80,"pattern":"^[a-z0-9]+(?:-[a-z0-9]+)*$","example":"main-branch","description":"Public URL/query identifier for this location. Must be unique within the business."},"timezone":{"type":"string","minLength":2,"example":"Asia/Karachi"},"currency":{"type":"string","minLength":3,"maxLength":10,"example":"PKR","description":"Optional location currency. If omitted, the business default currency is used."},"phone":{"type":"string","example":"+92-300-1234567"},"email":{"type":"string","format":"email","example":"main@example.com"},"addressLine1":{"type":"string"},"addressLine2":{"type":"string"},"city":{"type":"string"},"state":{"type":"string"},"country":{"type":"string"},"postalCode":{"type":"string"},"latitude":{"type":"number"},"longitude":{"type":"number"},"supportedOrderTypes":{"type":"array","description":"Order types this location supports. Defaults to DELIVERY and PICKUP when omitted.","items":{"$ref":"#/components/schemas/OrderType"},"example":["DELIVERY","PICKUP","DINE_IN"]},"cartSettings":{"type":"object","additionalProperties":true},"deliverySettings":{"type":"object","additionalProperties":true},"communicationSettings":{"type":"object","additionalProperties":true},"services":{"type":"object","additionalProperties":true},"metadata":{"type":"object","additionalProperties":true},"isActive":{"type":"boolean"}}},"OrderType":{"type":"string","enum":["DELIVERY","PICKUP","DINE_IN","RESERVATION","CURBSIDE","DRIVE_THRU","CATERING"],"example":"DELIVERY"},"LocationOrderTypesRequest":{"oneOf":[{"type":"object","required":["locationId","set"],"properties":{"locationId":{"type":"string","format":"uuid"},"set":{"type":"array","minItems":1,"items":{"$ref":"#/components/schemas/OrderType"},"example":["DELIVERY","PICKUP"]}}},{"type":"object","required":["locations"],"properties":{"locations":{"type":"array","minItems":1,"maxItems":500,"items":{"type":"object","required":["locationId","set"],"properties":{"locationId":{"type":"string","format":"uuid"},"set":{"type":"array","minItems":1,"items":{"$ref":"#/components/schemas/OrderType"},"example":["PICKUP","DINE_IN"]}}}}}}]},"BusinessHoursRequest":{"type":"object","required":["businessHours"],"description":"Supports multiple non-overlapping slots per day. Overnight ranges must be split across two days, for example 20:00-24:00 and 00:00-02:00.","properties":{"businessHours":{"type":"array","minItems":1,"items":{"type":"object","required":["dayOfWeek","slots"],"properties":{"dayOfWeek":{"type":"integer","minimum":0,"maximum":6},"slots":{"type":"array","items":{"type":"object","required":["openTime","closeTime"],"properties":{"openTime":{"type":"string","example":"09:00"},"closeTime":{"type":"string","example":"18:00"}}}}}}}}},"CategoryRequest":{"type":"object","required":["name","slug"],"properties":{"parentCategoryId":{"type":"string","format":"uuid"},"name":{"type":"string","minLength":2},"slug":{"type":"string","pattern":"^[a-z0-9]+(?:-[a-z0-9]+)*$","example":"burgers"},"description":{"type":"string"},"visibility":{"type":"string","enum":["ALL","WEB","APP","POS","NONE"]},"sortOrder":{"type":"integer","default":0},"isActive":{"type":"boolean","default":true},"imageUrl":{"type":"string"},"icon":{"type":"string"},"seo":{"type":"object","nullable":true,"additionalProperties":true},"metadata":{"type":"object","additionalProperties":true}}},"CategoryLocationsRequest":{"type":"object","required":["locationIds"],"properties":{"locationIds":{"type":"array","minItems":1,"items":{"type":"string","format":"uuid"}}}},"CategoryProductsRequest":{"type":"object","required":["productIds"],"properties":{"productIds":{"type":"array","items":{"type":"string","format":"uuid"}}}},"CategoryParentsRequest":{"type":"object","description":"Only one parent category is supported. Use collections for cross-grouping the same items into multiple merchandising buckets.","properties":{"parentIds":{"type":"array","maxItems":1,"items":{"type":"string","format":"uuid"}}}},"CollectionRequest":{"type":"object","required":["name","slug"],"properties":{"name":{"type":"string","minLength":2},"slug":{"type":"string","pattern":"^[a-z0-9]+(?:-[a-z0-9]+)*$","example":"deals"},"description":{"type":"string"},"sortOrder":{"type":"integer","default":0},"isActive":{"type":"boolean","default":true},"metadata":{"type":"object","additionalProperties":true}}},"CollectionItemsRequest":{"type":"object","required":["itemIds"],"properties":{"itemIds":{"type":"array","minItems":1,"items":{"type":"string","format":"uuid"}}}},"MenuItemRequest":{"type":"object","description":"Creates or updates an item. Prefer the item setup shape with item, categoryIds, tagIds, and modifierGroups. Flat item fields are still accepted for backward compatibility.","properties":{"item":{"type":"object","required":["slug","name","basePrice"],"properties":{"sku":{"type":"string","nullable":true},"slug":{"type":"string","pattern":"^[a-z0-9]+(?:-[a-z0-9]+)*$","example":"zinger-burger"},"name":{"type":"string","minLength":2},"description":{"type":"string","nullable":true},"basePrice":{"type":"number","minimum":0},"status":{"type":"string","enum":["ACTIVE","INACTIVE","ARCHIVED"],"default":"ACTIVE"},"isAvailable":{"type":"boolean","default":true},"imageUrl":{"type":"string","format":"uri","nullable":true},"thumbnailUrl":{"type":"string","format":"uri","nullable":true},"seo":{"type":"object","additionalProperties":true}}},"sku":{"type":"string","nullable":true},"slug":{"type":"string","pattern":"^[a-z0-9]+(?:-[a-z0-9]+)*$","example":"zinger-burger"},"name":{"type":"string","minLength":2},"description":{"type":"string","nullable":true},"basePrice":{"type":"number","minimum":0},"status":{"type":"string","enum":["ACTIVE","INACTIVE","ARCHIVED"],"default":"ACTIVE"},"isAvailable":{"type":"boolean","default":true},"categoryIds":{"type":"array","items":{"type":"string","format":"uuid"}},"tagIds":{"type":"array","items":{"type":"string","format":"uuid"}},"modifierGroups":{"type":"array","description":"When provided, replaces the item option-set assignments. Array order is used as sortOrder. Send an empty array to detach all option sets from the item.","items":{"type":"string","format":"uuid"},"example":["chooseSizeGroupId","chooseSauceGroupId"]},"imageUrl":{"type":"string","format":"uri","nullable":true},"thumbnailUrl":{"type":"string","format":"uri","nullable":true},"seo":{"type":"object","additionalProperties":true}}},"AssignItemLocationRequest":{"type":"object","description":"Creates or updates a location-specific item assignment. If an assignment already exists, omitted override fields keep their current values.","properties":{"locationId":{"type":"string","format":"uuid"},"priceOverride":{"type":"number","minimum":0},"isAvailable":{"type":"boolean"}},"required":["locationId"]},"ModifierGroupRequest":{"type":"object","required":["name"],"properties":{"name":{"type":"string","minLength":2},"minSelect":{"type":"integer","minimum":0,"default":0},"maxSelect":{"type":"integer","minimum":1,"default":1},"isRequired":{"type":"boolean","default":false},"sortOrder":{"type":"integer","default":0},"isActive":{"type":"boolean","default":true}}},"ModifierGroupUpdateRequest":{"type":"object","properties":{"name":{"type":"string","minLength":2},"minSelect":{"type":"integer","minimum":0},"maxSelect":{"type":"integer","minimum":1},"isRequired":{"type":"boolean"},"sortOrder":{"type":"integer"},"isActive":{"type":"boolean"}}},"ModifierRequest":{"type":"object","required":["name"],"description":"Creates one selectable option inside a modifier group. Default options must also be available. The number of default options cannot exceed the parent group maxSelect.","properties":{"name":{"type":"string","minLength":2},"priceModifier":{"type":"number","default":0},"isDefault":{"type":"boolean","default":false},"isAvailable":{"type":"boolean","default":true},"sortOrder":{"type":"integer","default":0}}},"ModifierUpdateRequest":{"type":"object","properties":{"name":{"type":"string","minLength":2},"priceModifier":{"type":"number"},"isDefault":{"type":"boolean"},"isAvailable":{"type":"boolean"},"sortOrder":{"type":"integer"}}},"AssignModifierGroupToItemRequest":{"type":"object","required":["modifierGroupId"],"properties":{"modifierGroupId":{"type":"string","format":"uuid"},"sortOrder":{"type":"integer","default":0}}},"ModifierRelationRequest":{"type":"object","required":["childModifierGroupId"],"description":"Creates or updates a parent modifier -> child modifier group relation. The parent modifier comes from the URL. The same child group can be reused under multiple parents without duplication, but cycles are rejected.","properties":{"childModifierGroupId":{"type":"string","format":"uuid"},"sortOrder":{"type":"integer","default":0}}},"ItemPriceCalculationRequest":{"type":"object","properties":{"locationId":{"type":"string","format":"uuid"},"quantity":{"type":"integer","minimum":1,"default":1},"selectedModifierIds":{"type":"array","items":{"type":"string","format":"uuid"}}},"required":["locationId"]},"CartCalculationRequest":{"type":"object","properties":{"locationId":{"type":"string","format":"uuid"},"items":{"type":"array","items":{"type":"object","required":["itemId"],"properties":{"itemId":{"type":"string","format":"uuid"},"quantity":{"type":"integer","minimum":1,"default":1},"selectedModifierIds":{"type":"array","items":{"type":"string","format":"uuid"}}}}}},"required":["locationId","items"]},"ProductParentsRequest":{"type":"object","required":["parentIds"],"description":"Only one parent category is supported. Use collections when the same items need to appear in multiple merchandising groups.","properties":{"parentIds":{"type":"array","maxItems":1,"items":{"type":"string","format":"uuid"}}}},"PaginationSimple":{"type":"object","required":["page","pageSize","total"],"properties":{"page":{"type":"integer","example":1},"pageSize":{"type":"integer","example":20},"total":{"type":"integer","example":124}}},"PaginationDetailed":{"type":"object","required":["page","pageSize","totalItems","totalPages","hasNextPage","hasPreviousPage"],"properties":{"page":{"type":"integer","example":1},"pageSize":{"type":"integer","example":20},"totalItems":{"type":"integer","example":124},"totalPages":{"type":"integer","example":7},"hasNextPage":{"type":"boolean","example":true},"hasPreviousPage":{"type":"boolean","example":false}}},"AuthUserSummary":{"type":"object","required":["id","name","email","role"],"properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string","example":"Sholay4"},"email":{"type":"string","format":"email","example":"owner@example.com"},"role":{"type":"string","enum":["OWNER","ADMIN","MANAGER","STAFF"],"example":"OWNER"}}},"AuthBusinessSummary":{"type":"object","required":["id","name","email","defaultCurrency","slug","isActive"],"properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string","example":"Pizza Palace"},"email":{"type":"string","format":"email","example":"owner@example.com"},"defaultCurrency":{"type":"string","example":"PKR"},"slug":{"type":"string","example":"pizza-palace"},"isActive":{"type":"boolean","example":true}}},"SignupAuthResponse":{"type":"object","required":["status","token","business","user"],"properties":{"status":{"type":"integer","example":201},"token":{"type":"string","example":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."},"business":{"$ref":"#/components/schemas/AuthBusinessSummary"},"user":{"$ref":"#/components/schemas/AuthUserSummary"}}},"LoginAuthResponse":{"type":"object","required":["status","token","business","user"],"properties":{"status":{"type":"integer","example":200},"token":{"type":"string","example":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."},"business":{"type":"array","items":{"$ref":"#/components/schemas/AuthBusinessSummary"}},"user":{"$ref":"#/components/schemas/AuthUserSummary"}}},"TimeSlot":{"type":"object","required":["openTime","closeTime"],"properties":{"openTime":{"type":"string","example":"09:00"},"closeTime":{"type":"string","example":"18:00"}}},"BusinessHoursDay":{"type":"object","required":["dayOfWeek","slots"],"properties":{"dayOfWeek":{"type":"integer","minimum":0,"maximum":6,"example":1},"slots":{"type":"array","items":{"$ref":"#/components/schemas/TimeSlot"}}}},"BusinessHoursResponse":{"type":"object","required":["success","data"],"properties":{"success":{"type":"boolean","example":true},"data":{"type":"array","items":{"$ref":"#/components/schemas/BusinessHoursDay"}}}},"CategorySummary":{"type":"object","required":["id","businessId","name","slug","parentCategoryId","sortOrder","isActive"],"properties":{"id":{"type":"string","format":"uuid"},"businessId":{"type":"string","format":"uuid"},"parentCategoryId":{"type":"string","format":"uuid","nullable":true},"name":{"type":"string","example":"Burgers"},"slug":{"type":"string","example":"burgers"},"description":{"type":"string","nullable":true},"visibility":{"type":"string","enum":["ALL","WEB","APP","POS","NONE"],"example":"ALL"},"sortOrder":{"type":"integer","example":0},"isActive":{"type":"boolean","example":true},"imageUrl":{"type":"string","nullable":true},"icon":{"type":"string","nullable":true},"seo":{"type":"object","nullable":true,"additionalProperties":true},"metadata":{"type":"object","nullable":true,"additionalProperties":true},"createdAt":{"type":"string","format":"date-time","nullable":true},"updatedAt":{"type":"string","format":"date-time","nullable":true},"locationSortOrder":{"type":"integer","nullable":true}}},"CategoryNode":{"allOf":[{"$ref":"#/components/schemas/CategorySummary"},{"type":"object","required":["children"],"properties":{"children":{"type":"array","items":{"$ref":"#/components/schemas/CategoryNode"}}}}]},"LocationSummary":{"type":"object","required":["id","businessId","name","slug","timezone","currency","supportedOrderTypes","isActive"],"properties":{"id":{"type":"string","format":"uuid"},"businessId":{"type":"string","format":"uuid"},"name":{"type":"string","example":"Main DHA"},"slug":{"type":"string","example":"main-dha"},"timezone":{"type":"string","example":"Asia/Karachi"},"currency":{"type":"string","example":"PKR"},"phone":{"type":"string","nullable":true,"example":"+92-300-1234567"},"email":{"type":"string","format":"email","nullable":true,"example":"main@example.com"},"addressLine1":{"type":"string","nullable":true},"addressLine2":{"type":"string","nullable":true},"supportedOrderTypes":{"type":"array","items":{"$ref":"#/components/schemas/OrderType"},"example":["DELIVERY","PICKUP"]},"city":{"type":"string","nullable":true},"state":{"type":"string","nullable":true},"country":{"type":"string","nullable":true},"postalCode":{"type":"string","nullable":true},"latitude":{"type":"number","nullable":true},"longitude":{"type":"number","nullable":true},"isActive":{"type":"boolean","example":true},"deletedAt":{"type":"string","format":"date-time","nullable":true},"createdAt":{"type":"string","format":"date-time","nullable":true},"updatedAt":{"type":"string","format":"date-time","nullable":true},"categorySortOrder":{"type":"integer","nullable":true}}},"LocationDetail":{"allOf":[{"$ref":"#/components/schemas/LocationSummary"},{"type":"object","properties":{"addressLine1":{"type":"string","nullable":true},"addressLine2":{"type":"string","nullable":true},"latitude":{"type":"number","nullable":true},"longitude":{"type":"number","nullable":true},"cartSettings":{"type":"object","nullable":true,"additionalProperties":true},"deliverySettings":{"type":"object","nullable":true,"additionalProperties":true},"communicationSettings":{"type":"object","nullable":true,"additionalProperties":true},"services":{"type":"object","nullable":true,"additionalProperties":true},"metadata":{"type":"object","nullable":true,"additionalProperties":true},"categories":{"type":"array","items":{"$ref":"#/components/schemas/CategorySummary"}}}}]},"TagSummary":{"type":"object","required":["id","name","slug"],"properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string","example":"spicy"},"slug":{"type":"string","example":"spicy"}}},"TagRequest":{"type":"object","required":["name","slug"],"properties":{"name":{"type":"string","minLength":2,"example":"Featured"},"slug":{"type":"string","pattern":"^[a-z0-9]+(?:-[a-z0-9]+)*$","example":"featured"}}},"TagRecord":{"allOf":[{"$ref":"#/components/schemas/TagSummary"},{"type":"object","properties":{"businessId":{"type":"string","format":"uuid"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}}]},"TagsResponse":{"type":"object","required":["success","data"],"properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","required":["tags","pagination"],"properties":{"tags":{"type":"array","items":{"$ref":"#/components/schemas/TagRecord"}},"pagination":{"$ref":"#/components/schemas/PaginationSimple"}}}}},"TagResponse":{"type":"object","required":["success","data"],"properties":{"success":{"type":"boolean","example":true},"data":{"$ref":"#/components/schemas/TagRecord"}}},"TagDeleteResponse":{"type":"object","required":["success","data"],"properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","required":["id"],"properties":{"id":{"type":"string","format":"uuid"}}}}},"TaxView":{"type":"object","required":["id","name","type","value","effectiveValue","isInclusive","effectiveIsInclusive","isActive","effectiveIsActive"],"properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string","example":"VAT"},"type":{"type":"string","example":"PERCENTAGE"},"value":{"type":"string","example":"15.00"},"effectiveValue":{"type":"string","example":"15.00"},"isInclusive":{"type":"boolean","example":false},"effectiveIsInclusive":{"type":"boolean","example":false},"isActive":{"type":"boolean","example":true},"effectiveIsActive":{"type":"boolean","example":true}}},"TaxRecord":{"type":"object","required":["id","businessId","name","type","value","isInclusive","isActive"],"properties":{"id":{"type":"string","format":"uuid"},"businessId":{"type":"string","format":"uuid"},"name":{"type":"string","example":"VAT 16%"},"type":{"type":"string","enum":["PERCENTAGE","FIXED"],"example":"PERCENTAGE"},"value":{"oneOf":[{"type":"number"},{"type":"string"}],"example":"16.00"},"isInclusive":{"type":"boolean","example":false},"isActive":{"type":"boolean","example":true},"createdAt":{"type":"string","format":"date-time","nullable":true},"updatedAt":{"type":"string","format":"date-time","nullable":true}}},"TaxRequest":{"type":"object","required":["name","type","value"],"properties":{"name":{"type":"string","example":"VAT 16%"},"type":{"type":"string","enum":["PERCENTAGE","FIXED"],"example":"PERCENTAGE"},"value":{"type":"number","example":16},"isInclusive":{"type":"boolean","example":false},"isActive":{"type":"boolean","example":true}}},"TaxUpdateRequest":{"type":"object","properties":{"name":{"type":"string","example":"VAT 18%"},"type":{"type":"string","enum":["PERCENTAGE","FIXED"],"example":"PERCENTAGE"},"value":{"type":"number","example":18},"isInclusive":{"type":"boolean","example":false},"isActive":{"type":"boolean","example":true}}},"BusinessTaxSettingsRequest":{"type":"object","properties":{"defaultTaxId":{"type":"string","format":"uuid","nullable":true}}},"ScopedTaxSettingsRequest":{"type":"object","required":["taxMode"],"properties":{"taxMode":{"type":"string","enum":["INHERIT","EXEMPT","CUSTOM"],"example":"CUSTOM"},"defaultTaxId":{"type":"string","format":"uuid","nullable":true},"taxId":{"type":"string","format":"uuid","nullable":true}}},"DiscountView":{"type":"object","required":["id","name","type","appliesTo","value","isActive","isStackable","startAt","endAt"],"properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string","example":"Ramadan Deal"},"type":{"type":"string","example":"PERCENTAGE"},"appliesTo":{"type":"string","example":"ITEM"},"value":{"type":"string","example":"10.00"},"isActive":{"type":"boolean","example":true},"isStackable":{"type":"boolean","example":false},"startAt":{"type":"string","format":"date-time","nullable":true},"endAt":{"type":"string","format":"date-time","nullable":true}}},"ModifierGroupChildSummary":{"type":"object","required":["id","name","minSelect","maxSelect","isRequired","sortOrder","modifiers"],"properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string","example":"Burger Sauces"},"minSelect":{"type":"integer","example":0},"maxSelect":{"type":"integer","example":2},"isRequired":{"type":"boolean","example":false},"sortOrder":{"type":"integer","example":0},"triggerSortOrder":{"type":"integer","example":0},"modifiers":{"type":"array","items":{"type":"object","required":["id","name","priceModifier","isDefault","isAvailable","sortOrder"],"properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string","example":"Garlic Mayo"},"priceModifier":{"type":"string","example":"50.00"},"isDefault":{"type":"boolean","example":false},"isAvailable":{"type":"boolean","example":true},"sortOrder":{"type":"integer","example":0}}}}}},"ModifierGroupExpanded":{"type":"object","required":["id","name","minSelect","maxSelect","isRequired","sortOrder","modifiers"],"properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string","example":"Patty Choice"},"minSelect":{"type":"integer","example":1},"maxSelect":{"type":"integer","example":1},"isRequired":{"type":"boolean","example":true},"sortOrder":{"type":"integer","example":0},"modifiers":{"type":"array","items":{"type":"object","required":["id","name","priceModifier","effectivePriceModifier","isDefault","isAvailable","effectiveAvailability","sortOrder","childGroups"],"properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string","example":"Chicken Patty"},"priceModifier":{"type":"string","example":"0.00"},"effectivePriceModifier":{"type":"string","example":"0.00"},"isDefault":{"type":"boolean","example":true},"isAvailable":{"type":"boolean","example":true},"effectiveAvailability":{"type":"boolean","example":true},"sortOrder":{"type":"integer","example":0},"childGroups":{"type":"array","items":{"$ref":"#/components/schemas/ModifierGroupChildSummary"}}}}}}},"MenuItemSummary":{"type":"object","required":["id","sku","slug","name","basePrice","status","isAvailable","effectiveBasePrice","effectiveAvailability","categories","tags"],"properties":{"id":{"type":"string","format":"uuid"},"sku":{"type":"string","nullable":true,"example":"BG-001"},"slug":{"type":"string","example":"zinger-burger"},"name":{"type":"string","example":"Zinger Burger"},"description":{"type":"string","nullable":true},"basePrice":{"oneOf":[{"type":"number"},{"type":"string"}],"example":"750.00"},"status":{"type":"string","enum":["ACTIVE","INACTIVE","ARCHIVED"],"example":"ACTIVE"},"isAvailable":{"type":"boolean","example":true},"effectiveBasePrice":{"oneOf":[{"type":"number"},{"type":"string"}],"example":"750.00"},"effectiveAvailability":{"type":"boolean","example":true},"imageUrl":{"type":"string","nullable":true},"thumbnailUrl":{"type":"string","nullable":true},"seo":{"type":"object","nullable":true,"additionalProperties":true},"categories":{"type":"array","items":{"type":"object","required":["id","name","slug"],"properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string","example":"Burgers"},"slug":{"type":"string","example":"burgers"}}}},"tags":{"type":"array","items":{"$ref":"#/components/schemas/TagSummary"}},"taxes":{"type":"array","items":{"$ref":"#/components/schemas/TaxView"}},"discounts":{"type":"array","items":{"$ref":"#/components/schemas/DiscountView"}},"locationOverride":{"type":"object","nullable":true,"properties":{"locationId":{"type":"string","format":"uuid"},"priceOverride":{"oneOf":[{"type":"number"},{"type":"string"}],"nullable":true},"isAvailable":{"type":"boolean","nullable":true}}},"modifierGroups":{"type":"array","description":"When `include=modifiers`, returns the option-set (modifier group) IDs assigned to the item.","items":{"type":"string","format":"uuid"}}}},"MenuItemDetail":{"type":"object","required":["id","sku","slug","name","basePrice","status","isAvailable","categories","tags","itemTaxes","itemDiscounts","modifierGroups"],"properties":{"id":{"type":"string","format":"uuid"},"sku":{"type":"string","nullable":true,"example":"BG-001"},"slug":{"type":"string","example":"zinger-burger"},"name":{"type":"string","example":"Zinger Burger"},"description":{"type":"string","nullable":true},"basePrice":{"oneOf":[{"type":"number"},{"type":"string"}],"example":"750.00"},"status":{"type":"string","enum":["ACTIVE","INACTIVE","ARCHIVED"],"example":"ACTIVE"},"isAvailable":{"type":"boolean","example":true},"imageUrl":{"type":"string","nullable":true},"thumbnailUrl":{"type":"string","nullable":true},"seo":{"type":"object","nullable":true,"additionalProperties":true},"categories":{"type":"array","items":{"type":"object","required":["id","name","slug"],"properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string","example":"Burgers"},"slug":{"type":"string","example":"burgers"}}}},"tags":{"type":"array","items":{"$ref":"#/components/schemas/TagSummary"}},"itemTaxes":{"type":"array","items":{"type":"object","required":["tax"],"properties":{"tax":{"type":"object","required":["id","name","type","value","isInclusive","isActive"],"properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string","example":"VAT"},"type":{"type":"string","example":"PERCENTAGE"},"value":{"type":"string","example":"15.00"},"isInclusive":{"type":"boolean","example":false},"isActive":{"type":"boolean","example":true}}}}}},"itemDiscounts":{"type":"array","items":{"type":"object","required":["discount"],"properties":{"discount":{"$ref":"#/components/schemas/DiscountView"}}}},"modifierGroups":{"type":"array","items":{"type":"object","required":["sortOrder","modifierGroup"],"properties":{"sortOrder":{"type":"integer","example":0},"modifierGroup":{"$ref":"#/components/schemas/ModifierGroupExpanded"}}}}}},"ModifierGroupSummary":{"type":"object","required":["id","businessId","name","minSelect","maxSelect","isRequired","sortOrder","isActive"],"properties":{"id":{"type":"string","format":"uuid"},"businessId":{"type":"string","format":"uuid"},"name":{"type":"string","example":"Patty Choice"},"minSelect":{"type":"integer","example":1},"maxSelect":{"type":"integer","example":1},"isRequired":{"type":"boolean","example":true},"sortOrder":{"type":"integer","example":0},"isActive":{"type":"boolean","example":true},"modifierCount":{"type":"integer","example":3}}},"ModifierGroupDetail":{"allOf":[{"$ref":"#/components/schemas/ModifierGroupSummary"},{"type":"object","required":["modifiers"],"properties":{"modifiers":{"type":"array","items":{"$ref":"#/components/schemas/ModifierSummary"}}}}]},"ModifierSummary":{"type":"object","required":["id","businessId","modifierGroupId","name","priceModifier","isDefault","isAvailable","sortOrder"],"properties":{"id":{"type":"string","format":"uuid"},"businessId":{"type":"string","format":"uuid"},"modifierGroupId":{"type":"string","format":"uuid"},"name":{"type":"string","example":"Chicken Patty"},"priceModifier":{"oneOf":[{"type":"number"},{"type":"string"}],"example":"0.00"},"isDefault":{"type":"boolean","example":true},"isAvailable":{"type":"boolean","example":true},"sortOrder":{"type":"integer","example":0}}},"ModifierRelationSummary":{"type":"object","required":["parentModifierId","childModifierGroupId","sortOrder"],"properties":{"parentModifierId":{"type":"string","format":"uuid"},"childModifierGroupId":{"type":"string","format":"uuid"},"sortOrder":{"type":"integer","example":0}}},"ModifierAssignmentSummary":{"type":"object","required":["itemId","modifierGroupId","sortOrder"],"properties":{"itemId":{"type":"string","format":"uuid"},"modifierGroupId":{"type":"string","format":"uuid"},"sortOrder":{"type":"integer","example":0}}},"ModifierTreeNode":{"type":"object","required":["id","name","minSelect","maxSelect","isRequired","sortOrder","modifiers"],"properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string","example":"Patty Choice"},"minSelect":{"type":"integer","example":1},"maxSelect":{"type":"integer","example":1},"isRequired":{"type":"boolean","example":true},"sortOrder":{"type":"integer","example":0},"modifiers":{"type":"array","items":{"type":"object","required":["id","name","basePriceModifier","effectivePriceModifier","isDefault","isAvailable","sortOrder","childGroups"],"properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string","example":"Chicken Patty"},"basePriceModifier":{"type":"number","example":0},"effectivePriceModifier":{"type":"number","example":0},"isDefault":{"type":"boolean","example":true},"isAvailable":{"type":"boolean","example":true},"sortOrder":{"type":"integer","example":0},"childGroups":{"type":"array","items":{"$ref":"#/components/schemas/ModifierTreeNode"}}}}}}},"PricingBreakdown":{"type":"object","required":["basePrice","modifierTotal","subtotalBeforeDiscount","discountTotal","subtotalAfterDiscount","inclusiveTaxTotal","exclusiveTaxTotal","total","quantity","lineTotal","appliedDiscounts","appliedTaxes","selectedModifiers"],"properties":{"basePrice":{"type":"number","example":750},"modifierTotal":{"type":"number","example":100},"subtotalBeforeDiscount":{"type":"number","example":850},"discountTotal":{"type":"number","example":85},"subtotalAfterDiscount":{"type":"number","example":765},"inclusiveTaxTotal":{"type":"number","example":0},"exclusiveTaxTotal":{"type":"number","example":114.75},"total":{"type":"number","example":879.75},"quantity":{"type":"integer","example":2},"lineTotal":{"type":"number","example":1759.5},"appliedDiscounts":{"type":"array","items":{"type":"object","required":["id","name","amount"],"properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string","example":"Ramadan Deal"},"amount":{"type":"number","example":85}}}},"appliedTaxes":{"type":"array","items":{"type":"object","required":["id","name","amount","isInclusive"],"properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string","example":"VAT"},"amount":{"type":"number","example":114.75},"isInclusive":{"type":"boolean","example":false}}}},"selectedModifiers":{"type":"array","items":{"type":"object","required":["id","name","priceModifier"],"properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string","example":"Extra Cheese"},"priceModifier":{"type":"number","example":100}}}}}},"CartPricing":{"type":"object","required":["lines","cartTotal"],"properties":{"lines":{"type":"array","items":{"$ref":"#/components/schemas/PricingBreakdown"}},"cartTotal":{"type":"number","example":1759.5}}},"ProductCategoryNode":{"allOf":[{"$ref":"#/components/schemas/CategorySummary"},{"type":"object","required":["children"],"properties":{"children":{"type":"array","items":{"$ref":"#/components/schemas/ProductCategoryNode"}}}}]},"ProductListItem":{"type":"object","required":["id","sku","slug","name","basePrice","isAvailable","effectiveBasePrice","effectiveAvailability","categories","tags"],"properties":{"id":{"type":"string","format":"uuid"},"sku":{"type":"string","nullable":true,"example":"BG-001"},"slug":{"type":"string","example":"zinger-burger"},"name":{"type":"string","example":"Zinger Burger"},"description":{"type":"string","nullable":true},"basePrice":{"oneOf":[{"type":"number"},{"type":"string"}],"example":"750.00"},"isAvailable":{"type":"boolean","example":true},"effectiveBasePrice":{"oneOf":[{"type":"number"},{"type":"string"}],"example":"750.00"},"effectiveAvailability":{"type":"boolean","example":true},"imageUrl":{"type":"string","nullable":true},"thumbnailUrl":{"type":"string","nullable":true},"categories":{"type":"array","items":{"$ref":"#/components/schemas/ProductCategoryNode"}},"tags":{"type":"array","items":{"$ref":"#/components/schemas/TagSummary"}}}},"LocationListResponse":{"type":"object","required":["success","data"],"properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","required":["locations","pagination"],"properties":{"locations":{"type":"array","items":{"$ref":"#/components/schemas/LocationSummary"}},"pagination":{"$ref":"#/components/schemas/PaginationSimple"}}}}},"LocationResponse":{"type":"object","required":["success","data"],"properties":{"success":{"type":"boolean","example":true},"data":{"$ref":"#/components/schemas/LocationDetail"}}},"BulkLocationOrderTypesResponse":{"type":"object","required":["success","data"],"properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","required":["updatedCount","items"],"properties":{"updatedCount":{"type":"integer","example":3},"items":{"type":"array","items":{"$ref":"#/components/schemas/LocationDetail"}}}}}},"CategoryTreeResponse":{"type":"object","required":["success","data"],"properties":{"success":{"type":"boolean","example":true},"data":{"type":"array","items":{"$ref":"#/components/schemas/CategoryNode"}}}},"CategoryListResponse":{"type":"object","required":["success","data"],"properties":{"success":{"type":"boolean","example":true},"data":{"type":"array","items":{"$ref":"#/components/schemas/CategorySummary"}}}},"CategoryResponse":{"type":"object","required":["success","data"],"properties":{"success":{"type":"boolean","example":true},"data":{"$ref":"#/components/schemas/CategorySummary"}}},"CategoryLocationsResponse":{"type":"object","required":["success","data"],"properties":{"success":{"type":"boolean","example":true},"data":{"type":"array","items":{"$ref":"#/components/schemas/LocationSummary"}}}},"CategoryLocationAssignmentsResponse":{"type":"object","required":["success","data"],"properties":{"success":{"type":"boolean","example":true},"data":{"type":"array","items":{"type":"object","required":["locationId"],"properties":{"locationId":{"type":"string","format":"uuid"}}}}}},"CategoryProductsResponse":{"type":"object","required":["success","data"],"properties":{"success":{"type":"boolean","example":true},"data":{"type":"array","items":{"$ref":"#/components/schemas/ProductListItem"}}}},"CategoryProductAssignmentsResponse":{"type":"object","required":["success","data"],"properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","required":["categoryId","productIds"],"properties":{"categoryId":{"type":"string","format":"uuid"},"productIds":{"type":"array","items":{"type":"string","format":"uuid"}}}}}},"CategoryProductRemovalResponse":{"type":"object","required":["success","data"],"properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","required":["categoryId","productId","removed"],"properties":{"categoryId":{"type":"string","format":"uuid"},"productId":{"type":"string","format":"uuid"},"removed":{"type":"boolean","example":true}}}}},"CategoryParentsResponse":{"type":"object","required":["success","data"],"properties":{"success":{"type":"boolean","example":true},"data":{"type":"array","items":{"type":"string","format":"uuid"}}}},"CategoryParentAssignmentsResponse":{"type":"object","required":["success","data"],"properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","required":["categoryId","parentIds"],"properties":{"categoryId":{"type":"string","format":"uuid"},"parentIds":{"type":"array","items":{"type":"string","format":"uuid"}}}}}},"TaxListResponse":{"type":"object","required":["success","data"],"properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","required":["items","pagination"],"properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/TaxRecord"}},"pagination":{"$ref":"#/components/schemas/PaginationSimple"}}}}},"TaxResponse":{"type":"object","required":["success","data"],"properties":{"success":{"type":"boolean","example":true},"data":{"$ref":"#/components/schemas/TaxRecord"}}},"BusinessTaxSettingsResponse":{"type":"object","required":["success","data"],"properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","required":["businessId","defaultTaxId"],"properties":{"businessId":{"type":"string","format":"uuid"},"defaultTaxId":{"type":"string","format":"uuid","nullable":true},"defaultTax":{"anyOf":[{"$ref":"#/components/schemas/TaxRecord"},{"type":"null"}]}}}}},"LocationTaxSettingsResponse":{"type":"object","required":["success","data"],"properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","required":["businessId","locationId","taxMode","defaultTaxId"],"properties":{"id":{"type":"string","format":"uuid","nullable":true},"locationId":{"type":"string","format":"uuid"},"businessId":{"type":"string","format":"uuid"},"taxMode":{"type":"string","enum":["INHERIT","EXEMPT","CUSTOM"],"example":"INHERIT"},"defaultTaxId":{"type":"string","format":"uuid","nullable":true},"defaultTax":{"anyOf":[{"$ref":"#/components/schemas/TaxRecord"},{"type":"null"}]}}}}},"ItemTaxSettingsResponse":{"type":"object","required":["success","data"],"properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","required":["businessId","itemId","taxMode","taxId"],"properties":{"id":{"type":"string","format":"uuid","nullable":true},"itemId":{"type":"string","format":"uuid"},"businessId":{"type":"string","format":"uuid"},"taxMode":{"type":"string","enum":["INHERIT","EXEMPT","CUSTOM"],"example":"INHERIT"},"taxId":{"type":"string","format":"uuid","nullable":true},"tax":{"anyOf":[{"$ref":"#/components/schemas/TaxRecord"},{"type":"null"}]}}}}},"DeleteStatusResponse":{"type":"object","required":["success","data"],"properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","required":["id","deleted"],"properties":{"id":{"type":"string","format":"uuid"},"deleted":{"type":"boolean","example":true}}}}},"CollectionSummary":{"type":"object","required":["id","businessId","name","slug","sortOrder","isActive"],"properties":{"id":{"type":"string","format":"uuid"},"businessId":{"type":"string","format":"uuid"},"name":{"type":"string","example":"Deals"},"slug":{"type":"string","example":"deals"},"description":{"type":"string","nullable":true},"sortOrder":{"type":"integer","example":0},"isActive":{"type":"boolean","example":true},"metadata":{"type":"object","nullable":true,"additionalProperties":true},"createdAt":{"type":"string","format":"date-time","nullable":true},"updatedAt":{"type":"string","format":"date-time","nullable":true}}},"CollectionItem":{"type":"object","required":["id","businessId","sku","slug","name","basePrice","isAvailable"],"properties":{"id":{"type":"string","format":"uuid"},"businessId":{"type":"string","format":"uuid"},"sku":{"type":"string","nullable":true,"example":"BG-001"},"slug":{"type":"string","example":"zinger-burger"},"name":{"type":"string","example":"Zinger Burger"},"description":{"type":"string","nullable":true},"basePrice":{"oneOf":[{"type":"number"},{"type":"string"}],"example":"750.00"},"isAvailable":{"type":"boolean","example":true},"imageUrl":{"type":"string","nullable":true},"thumbnailUrl":{"type":"string","nullable":true},"collectionSortOrder":{"type":"integer","nullable":true},"assignedAt":{"type":"string","format":"date-time","nullable":true}}},"CollectionListResponse":{"type":"object","required":["success","data"],"properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","required":["items","pagination"],"properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/CollectionSummary"}},"pagination":{"$ref":"#/components/schemas/PaginationSimple"}}}}},"CollectionResponse":{"type":"object","required":["success","data"],"properties":{"success":{"type":"boolean","example":true},"data":{"allOf":[{"$ref":"#/components/schemas/CollectionSummary"},{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/CollectionItem"}}}}]}}},"CollectionItemsResponse":{"type":"object","required":["success","data"],"properties":{"success":{"type":"boolean","example":true},"data":{"type":"array","items":{"$ref":"#/components/schemas/CollectionItem"}}}},"CollectionItemAssignmentsResponse":{"type":"object","required":["success","data"],"properties":{"success":{"type":"boolean","example":true},"data":{"type":"array","items":{"type":"object","required":["itemId"],"properties":{"itemId":{"type":"string","format":"uuid"}}}}}},"MenuItemsResponse":{"type":"object","required":["success","data","pagination"],"properties":{"success":{"type":"boolean","example":true},"data":{"type":"array","items":{"$ref":"#/components/schemas/MenuItemSummary"}},"pagination":{"$ref":"#/components/schemas/PaginationDetailed"}}},"MenuItemResponse":{"type":"object","required":["success","data"],"properties":{"success":{"type":"boolean","example":true},"data":{"$ref":"#/components/schemas/MenuItemDetail"}}},"MenuItemWriteResponse":{"type":"object","required":["success","data"],"properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","required":["id","businessId","sku","slug","name","status","isAvailable"],"properties":{"id":{"type":"string","format":"uuid"},"businessId":{"type":"string","format":"uuid"},"sku":{"type":"string","nullable":true,"example":"BG-001"},"slug":{"type":"string","example":"zinger-burger"},"name":{"type":"string","example":"Zinger Burger"},"description":{"type":"string","nullable":true},"basePrice":{"oneOf":[{"type":"number"},{"type":"string"}],"nullable":true},"status":{"type":"string","enum":["ACTIVE","INACTIVE","ARCHIVED"],"example":"ACTIVE"},"isAvailable":{"type":"boolean","example":true},"imageUrl":{"type":"string","nullable":true},"thumbnailUrl":{"type":"string","nullable":true},"seo":{"type":"object","nullable":true,"additionalProperties":true}}}}},"MenuLocationAssignmentResponse":{"type":"object","required":["success","data"],"properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","required":["itemId","locationId","priceOverride","isAvailable"],"properties":{"itemId":{"type":"string","format":"uuid"},"locationId":{"type":"string","format":"uuid"},"priceOverride":{"oneOf":[{"type":"number"},{"type":"string"}],"nullable":true},"isAvailable":{"type":"boolean","nullable":true}}}}},"LocationMenuResponse":{"type":"object","required":["success","data"],"properties":{"success":{"type":"boolean","example":true},"data":{"type":"array","items":{"$ref":"#/components/schemas/MenuItemSummary"}}}},"ModifierGroupResponse":{"type":"object","required":["success","data"],"properties":{"success":{"type":"boolean","example":true},"data":{"$ref":"#/components/schemas/ModifierGroupSummary"}}},"ModifierGroupsResponse":{"type":"object","required":["success","data"],"properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","required":["items","pagination"],"properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/ModifierGroupSummary"}},"pagination":{"$ref":"#/components/schemas/PaginationSimple"}}}}},"ModifierGroupDetailResponse":{"type":"object","required":["success","data"],"properties":{"success":{"type":"boolean","example":true},"data":{"$ref":"#/components/schemas/ModifierGroupDetail"}}},"ModifierResponseEnvelope":{"type":"object","required":["success","data"],"properties":{"success":{"type":"boolean","example":true},"data":{"$ref":"#/components/schemas/ModifierSummary"}}},"ModifiersResponse":{"type":"object","required":["success","data"],"properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","required":["items","pagination"],"properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/ModifierSummary"}},"pagination":{"$ref":"#/components/schemas/PaginationSimple"}}}}},"ModifierAssignmentResponse":{"type":"object","required":["success","data"],"properties":{"success":{"type":"boolean","example":true},"data":{"$ref":"#/components/schemas/ModifierAssignmentSummary"}}},"ModifierRelationResponse":{"type":"object","required":["success","data"],"properties":{"success":{"type":"boolean","example":true},"data":{"$ref":"#/components/schemas/ModifierRelationSummary"}}},"ModifierTreeResponse":{"type":"object","required":["success","data"],"properties":{"success":{"type":"boolean","example":true},"data":{"type":"array","items":{"$ref":"#/components/schemas/ModifierTreeNode"}}}},"PricingResponse":{"type":"object","required":["success","data"],"properties":{"success":{"type":"boolean","example":true},"data":{"$ref":"#/components/schemas/PricingBreakdown"}}},"CartPricingResponse":{"type":"object","required":["success","data"],"properties":{"success":{"type":"boolean","example":true},"data":{"$ref":"#/components/schemas/CartPricing"}}},"ProductListingResponse":{"type":"object","required":["success","data"],"properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","required":["categories","items","pagination"],"properties":{"categories":{"type":"array","items":{"$ref":"#/components/schemas/ProductCategoryNode"}},"items":{"type":"array","items":{"$ref":"#/components/schemas/ProductListItem"}},"pagination":{"type":"object","required":["page","pageSize","totalItems","totalPages","hasNextPage","hasPreviousPage"],"properties":{"page":{"type":"integer","example":1},"pageSize":{"type":"integer","example":20},"totalItems":{"type":"integer","example":124},"totalPages":{"type":"integer","example":7},"hasNextPage":{"type":"boolean","example":false},"hasPreviousPage":{"type":"boolean","example":false}}}}}}},"PublicItemResponse":{"type":"object","required":["success","data"],"properties":{"success":{"type":"boolean","example":true},"data":{"allOf":[{"$ref":"#/components/schemas/MenuItemDetail"},{"type":"object","required":["modifierTree"],"properties":{"modifierTree":{"type":"array","items":{"$ref":"#/components/schemas/ModifierTreeNode"}}}}]}}}}},"paths":{"/health":{"get":{"tags":["System"],"summary":"Health check","responses":{"200":{"description":"Service is healthy"}}}},"/api/v1/auth/signup":{"post":{"tags":["Auth"],"summary":"Create business and owner account","description":"Creates the business, owner user, and initial membership in one request, then returns a JWT token for the new owner.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignupRequest"}}}},"responses":{"201":{"description":"Business and owner account created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignupAuthResponse"}}}},"409":{"description":"Email or business name is already taken","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"success":false,"message":"Email or business name is already taken"}}}},"500":{"description":"Failed to complete initial business setup","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"success":false,"message":"Failed to complete initial business setup"}}}}}}},"/api/v1/auth/login":{"post":{"tags":["Auth"],"summary":"Login and get JWT token","description":"Authenticates an existing user and returns a JWT token scoped to the selected business membership.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LoginRequest"}}}},"responses":{"200":{"description":"Login successful","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LoginAuthResponse"}}}},"401":{"description":"Invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"success":false,"message":"Invalid credentials"}}}}}}},"/api/v1/business/{businessId}/locations":{"get":{"tags":["Location"],"security":[{"bearerAuth":[]}],"summary":"List locations","parameters":[{"name":"businessId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"page","in":"query","schema":{"type":"integer","minimum":1}},{"name":"pageSize","in":"query","schema":{"type":"integer","minimum":1,"maximum":100}},{"name":"slug","in":"query","schema":{"type":"string","pattern":"^[a-z0-9]+(?:-[a-z0-9]+)*$"},"description":"Filter by the public location slug."},{"name":"orderType","in":"query","schema":{"$ref":"#/components/schemas/OrderType"},"description":"Filter locations that support this order type."}],"responses":{"200":{"description":"Locations fetched successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LocationListResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"success":false,"message":"Unauthorized"}}}},"403":{"description":"Forbidden for this business","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"success":false,"message":"Forbidden for this business"}}}}}},"post":{"tags":["Location"],"security":[{"bearerAuth":[]}],"summary":"Create location","description":"Creates a new business location.","parameters":[{"name":"businessId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LocationRequest"}}}},"responses":{"201":{"description":"Location created successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LocationResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"success":false,"message":"Unauthorized"}}}},"403":{"description":"Forbidden for this business","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"success":false,"message":"Forbidden for this business"}}}}}}},"/api/v1/business/{businessId}/locations/order-types":{"patch":{"tags":["Location"],"security":[{"bearerAuth":[]}],"summary":"Replace location supported order types","description":"Updates supported order types for one or multiple locations in one request. Send either locationId/set for one location or locations[] for multiple locations.","parameters":[{"name":"businessId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LocationOrderTypesRequest"}}}},"responses":{"200":{"description":"Location order types updated successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BulkLocationOrderTypesResponse"}}}},"400":{"description":"Invalid or duplicate location order type payload","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"success":false,"message":"Invalid or duplicate location order type payload"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"success":false,"message":"Unauthorized"}}}},"403":{"description":"Forbidden for this business","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"success":false,"message":"Forbidden for this business"}}}},"404":{"description":"One or more locations were not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"success":false,"message":"One or more locations were not found"}}}}}}},"/api/v1/business/{businessId}/locations/{id}":{"get":{"tags":["Location"],"security":[{"bearerAuth":[]}],"summary":"Get location by id","parameters":[{"name":"businessId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Location fetched successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LocationResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"success":false,"message":"Unauthorized"}}}},"403":{"description":"Forbidden for this business","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"success":false,"message":"Forbidden for this business"}}}},"404":{"description":"Location not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"success":false,"message":"Location not found"}}}}}},"patch":{"tags":["Location"],"security":[{"bearerAuth":[]}],"summary":"Update location","parameters":[{"name":"businessId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LocationRequest"}}}},"responses":{"200":{"description":"Location updated successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LocationResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"success":false,"message":"Unauthorized"}}}},"403":{"description":"Forbidden for this business","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"success":false,"message":"Forbidden for this business"}}}},"404":{"description":"Location not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"success":false,"message":"Location not found"}}}}}},"delete":{"tags":["Location"],"security":[{"bearerAuth":[]}],"summary":"Delete location","description":"Soft-deletes a location by setting deletedAt to the current timestamp and isActive to false.","parameters":[{"name":"businessId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Location deleted successfully","content":{"application/json":{"schema":{"type":"object","required":["success","message","data"],"properties":{"success":{"type":"boolean","example":true},"message":{"type":"string","example":"Location deleted successfully"},"data":{"type":"object","required":["id","deletedAt"],"properties":{"id":{"type":"string","format":"uuid"},"deletedAt":{"type":"string","format":"date-time"}}}}}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"success":false,"message":"Unauthorized"}}}},"403":{"description":"Forbidden for this business","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"success":false,"message":"Forbidden for this business"}}}},"404":{"description":"Location not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"success":false,"message":"Location not found"}}}}}}},"/api/v1/business/{businessId}/locations/{id}/business-hours":{"get":{"tags":["Location"],"security":[{"bearerAuth":[]}],"summary":"Get location business hours","parameters":[{"name":"businessId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Business hours fetched successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BusinessHoursResponse"}}}}}},"put":{"tags":["Location"],"security":[{"bearerAuth":[]}],"summary":"Replace location business hours","description":"Replaces the full weekly schedule. Each day can contain multiple non-overlapping slots.","parameters":[{"name":"businessId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BusinessHoursRequest"}}}},"responses":{"200":{"description":"Business hours updated successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BusinessHoursResponse"}}}},"400":{"description":"Duplicate day entries, overlapping slots, or invalid overnight slot","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"success":false,"message":"Duplicate day entries, overlapping slots, or invalid overnight slot"}}}}}},"patch":{"tags":["Location"],"security":[{"bearerAuth":[]}],"summary":"Patch location business hours","description":"Merges the provided days into the existing weekly schedule and validates the final result.","parameters":[{"name":"businessId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BusinessHoursRequest"}}}},"responses":{"200":{"description":"Business hours updated successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BusinessHoursResponse"}}}},"400":{"description":"Duplicate day entries, overlapping slots, or invalid overnight slot","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"success":false,"message":"Duplicate day entries, overlapping slots, or invalid overnight slot"}}}}}}},"/api/v1/business/{businessId}/locations/{id}/categories":{"get":{"tags":["Location"],"security":[{"bearerAuth":[]}],"summary":"Get categories assigned to a location","parameters":[{"name":"businessId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Location categories fetched successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CategoryListResponse"}}}}}}},"/api/v1/business/{businessId}/categories":{"get":{"tags":["Category"],"security":[{"bearerAuth":[]}],"summary":"List category tree","description":"Returns the hierarchical business category tree. Each category can have at most one parent.","parameters":[{"name":"businessId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Categories fetched successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CategoryTreeResponse"}}}}}},"post":{"tags":["Category"],"security":[{"bearerAuth":[]}],"summary":"Create category","description":"Creates a category within the business catalog.","parameters":[{"name":"businessId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CategoryRequest"}}}},"responses":{"201":{"description":"Category created successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CategoryResponse"}}}},"400":{"description":"Parent category is invalid for this business","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"success":false,"message":"Parent category is invalid for this business"}}}},"409":{"description":"Category slug already exists","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"success":false,"message":"Category slug already exists"}}}}}}},"/api/v1/business/{businessId}/categories/{id}":{"patch":{"tags":["Category"],"security":[{"bearerAuth":[]}],"summary":"Update category","description":"Updates a category and validates that parent assignments remain acyclic and business-scoped.","parameters":[{"name":"businessId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CategoryRequest"}}}},"responses":{"200":{"description":"Category updated successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CategoryResponse"}}}},"400":{"description":"Invalid parent category or cyclic category relation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"success":false,"message":"Invalid parent category or cyclic category relation"}}}},"404":{"description":"Category not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"success":false,"message":"Category not found"}}}},"409":{"description":"Category slug already exists","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"success":false,"message":"Category slug already exists"}}}}}},"delete":{"tags":["Category"],"security":[{"bearerAuth":[]}],"summary":"Delete category","parameters":[{"name":"businessId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Category deleted successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeleteStatusResponse"}}}},"400":{"description":"Category still has child categories, products, or locations assigned","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"success":false,"message":"Category still has child categories, products, or locations assigned"}}}}}}},"/api/v1/business/{businessId}/categories/{id}/locations":{"get":{"tags":["Category"],"security":[{"bearerAuth":[]}],"summary":"Get locations assigned to category","parameters":[{"name":"businessId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Category locations fetched successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CategoryLocationsResponse"}}}}}},"put":{"tags":["Category"],"security":[{"bearerAuth":[]}],"summary":"Replace category locations","description":"Replaces all location assignments for the category.","parameters":[{"name":"businessId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CategoryLocationsRequest"}}}},"responses":{"200":{"description":"Category locations updated successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CategoryLocationAssignmentsResponse"}}}},"400":{"description":"One or more locations do not belong to this business","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"success":false,"message":"One or more locations do not belong to this business"}}}},"404":{"description":"Category not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"success":false,"message":"Category not found"}}}}}}},"/api/v1/business/{businessId}/categories/{id}/products":{"get":{"tags":["Category"],"security":[{"bearerAuth":[]}],"summary":"Get products assigned to category","parameters":[{"name":"businessId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Category products fetched successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CategoryProductsResponse"}}}}}},"put":{"tags":["Category"],"security":[{"bearerAuth":[]}],"summary":"Replace products in category","description":"Replaces the full set of menu items assigned to the category.","parameters":[{"name":"businessId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CategoryProductsRequest"}}}},"responses":{"200":{"description":"Category products replaced successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CategoryProductAssignmentsResponse"}}}},"400":{"description":"One or more products do not belong to this business","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"success":false,"message":"One or more products do not belong to this business"}}}},"404":{"description":"Category not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"success":false,"message":"Category not found"}}}}}},"post":{"tags":["Category"],"security":[{"bearerAuth":[]}],"summary":"Add products to category","description":"Adds additional menu items to the category without removing existing assignments.","parameters":[{"name":"businessId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CategoryProductsRequest"}}}},"responses":{"200":{"description":"Products added to category successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CategoryProductAssignmentsResponse"}}}},"400":{"description":"One or more products do not belong to this business","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"success":false,"message":"One or more products do not belong to this business"}}}},"404":{"description":"Category not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"success":false,"message":"Category not found"}}}}}}},"/api/v1/business/{businessId}/categories/{id}/products/{productId}":{"delete":{"tags":["Category"],"security":[{"bearerAuth":[]}],"summary":"Remove a product from category","parameters":[{"name":"businessId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"productId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Product removed from category successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CategoryProductRemovalResponse"}}}}}}},"/api/v1/business/{businessId}/categories/{id}/parents":{"get":{"tags":["Category"],"security":[{"bearerAuth":[]}],"summary":"Get parent category id as an array","parameters":[{"name":"businessId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Parent categories fetched successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CategoryParentsResponse"}}}}}},"put":{"tags":["Category"],"security":[{"bearerAuth":[]}],"summary":"Replace single parent category","description":"Assigns zero or one parent category. Multi-parent category graphs are intentionally not supported.","parameters":[{"name":"businessId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CategoryParentsRequest"}}}},"responses":{"200":{"description":"Parent categories updated successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CategoryParentAssignmentsResponse"}}}},"400":{"description":"More than one parent, invalid parent category, or cyclic relation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"success":false,"message":"More than one parent, invalid parent category, or cyclic relation"}}}},"404":{"description":"Category not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"success":false,"message":"Category not found"}}}}}}},"/api/v1/business/{businessId}/tags":{"get":{"tags":["Tags"],"security":[{"bearerAuth":[]}],"summary":"List tags","parameters":[{"name":"businessId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"search","in":"query","schema":{"type":"string"}},{"name":"page","in":"query","schema":{"type":"integer","minimum":1}},{"name":"pageSize","in":"query","schema":{"type":"integer","minimum":1,"maximum":100}}],"responses":{"200":{"description":"Tags fetched successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TagsResponse"}}}}}},"post":{"tags":["Tags"],"security":[{"bearerAuth":[]}],"summary":"Create tag","parameters":[{"name":"businessId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TagRequest"}}}},"responses":{"201":{"description":"Tag created successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TagResponse"}}}},"409":{"description":"Tag already exists","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"success":false,"message":"Tag already exists"}}}}}}},"/api/v1/business/{businessId}/tags/{id}":{"get":{"tags":["Tags"],"security":[{"bearerAuth":[]}],"summary":"Get tag","parameters":[{"name":"businessId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Tag fetched successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TagResponse"}}}},"404":{"description":"Tag not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"success":false,"message":"Tag not found"}}}}}},"patch":{"tags":["Tags"],"security":[{"bearerAuth":[]}],"summary":"Update tag","parameters":[{"name":"businessId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TagRequest"}}}},"responses":{"200":{"description":"Tag updated successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TagResponse"}}}},"404":{"description":"Tag not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"success":false,"message":"Tag not found"}}}},"409":{"description":"Tag already exists","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"success":false,"message":"Tag already exists"}}}}}},"delete":{"tags":["Tags"],"security":[{"bearerAuth":[]}],"summary":"Delete tag","description":"Deletes the tag and removes item-tag assignments through database cascade.","parameters":[{"name":"businessId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Tag deleted successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TagDeleteResponse"}}}},"404":{"description":"Tag not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"success":false,"message":"Tag not found"}}}}}}},"/api/v1/business/{businessId}/collections":{"get":{"tags":["Collections"],"security":[{"bearerAuth":[]}],"summary":"List collections","parameters":[{"name":"businessId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"page","in":"query","schema":{"type":"integer","minimum":1}},{"name":"pageSize","in":"query","schema":{"type":"integer","minimum":1,"maximum":100}}],"responses":{"200":{"description":"Collections fetched successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectionListResponse"}}}}}},"post":{"tags":["Collections"],"security":[{"bearerAuth":[]}],"summary":"Create collection","description":"Creates a merchandising collection. Collections are for cross-grouping items beyond the single-parent category tree.","parameters":[{"name":"businessId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectionRequest"}}}},"responses":{"201":{"description":"Collection created successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectionResponse"}}}},"409":{"description":"Collection slug already exists","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"success":false,"message":"Collection slug already exists"}}}}}}},"/api/v1/business/{businessId}/collections/{id}":{"get":{"tags":["Collections"],"security":[{"bearerAuth":[]}],"summary":"Get collection by id","parameters":[{"name":"businessId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Collection fetched successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectionResponse"}}}}}},"patch":{"tags":["Collections"],"security":[{"bearerAuth":[]}],"summary":"Update collection","parameters":[{"name":"businessId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectionRequest"}}}},"responses":{"200":{"description":"Collection updated successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectionResponse"}}}},"404":{"description":"Collection not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"success":false,"message":"Collection not found"}}}},"409":{"description":"Collection slug already exists","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"success":false,"message":"Collection slug already exists"}}}}}},"delete":{"tags":["Collections"],"security":[{"bearerAuth":[]}],"summary":"Delete collection","parameters":[{"name":"businessId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"204":{"description":"Collection deleted successfully"}}}},"/api/v1/business/{businessId}/collections/{id}/items":{"get":{"tags":["Collections"],"security":[{"bearerAuth":[]}],"summary":"List collection items","parameters":[{"name":"businessId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Collection items fetched successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectionItemsResponse"}}}}}},"put":{"tags":["Collections"],"security":[{"bearerAuth":[]}],"summary":"Replace collection items","description":"Replaces the full set of menu items attached to the collection.","parameters":[{"name":"businessId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectionItemsRequest"}}}},"responses":{"200":{"description":"Collection items updated successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectionItemAssignmentsResponse"}}}},"400":{"description":"One or more items do not belong to this business","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"success":false,"message":"One or more items do not belong to this business"}}}},"404":{"description":"Collection not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"success":false,"message":"Collection not found"}}}}}},"post":{"tags":["Collections"],"security":[{"bearerAuth":[]}],"summary":"Add items to collection","description":"Adds items to the collection without removing existing assignments.","parameters":[{"name":"businessId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectionItemsRequest"}}}},"responses":{"200":{"description":"Collection items added successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectionItemAssignmentsResponse"}}}},"400":{"description":"One or more items do not belong to this business","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"success":false,"message":"One or more items do not belong to this business"}}}},"404":{"description":"Collection not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"success":false,"message":"Collection not found"}}}}}}},"/api/v1/business/{businessId}/collections/{id}/items/{itemId}":{"delete":{"tags":["Collections"],"security":[{"bearerAuth":[]}],"summary":"Remove item from collection","parameters":[{"name":"businessId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"itemId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"204":{"description":"Collection item removed successfully"}}}},"/api/v1/business/{businessId}/taxes":{"get":{"tags":["Taxes"],"security":[{"bearerAuth":[]}],"summary":"List taxes","description":"Lists the reusable tax definitions for a business. These are later referenced by business, location, or item tax settings.","parameters":[{"name":"businessId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"search","in":"query","schema":{"type":"string"}},{"name":"page","in":"query","schema":{"type":"integer","minimum":1}},{"name":"pageSize","in":"query","schema":{"type":"integer","minimum":1,"maximum":100}}],"responses":{"200":{"description":"Taxes fetched successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TaxListResponse"}}}}}},"post":{"tags":["Taxes"],"security":[{"bearerAuth":[]}],"summary":"Create tax","description":"Creates a reusable tax definition. Inclusive/exclusive behavior belongs to the tax definition itself and is reused by business, location, or item tax settings.","parameters":[{"name":"businessId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TaxRequest"}}}},"responses":{"201":{"description":"Tax created successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TaxResponse"}}}},"409":{"description":"Tax name already exists","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"success":false,"message":"Tax name already exists"}}}}}}},"/api/v1/business/{businessId}/taxes/settings":{"get":{"tags":["Taxes"],"security":[{"bearerAuth":[]}],"summary":"Get business tax settings","description":"Returns the business-level default tax fallback. Pricing resolves tax precedence as item setting → location setting → business setting → legacy item tax mappings.","parameters":[{"name":"businessId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Business tax settings fetched successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BusinessTaxSettingsResponse"}}}}}},"patch":{"tags":["Taxes"],"security":[{"bearerAuth":[]}],"summary":"Update business tax settings","parameters":[{"name":"businessId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BusinessTaxSettingsRequest"}}}},"responses":{"200":{"description":"Business tax settings updated successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BusinessTaxSettingsResponse"}}}},"400":{"description":"Default tax must belong to this business","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"success":false,"message":"Default tax must belong to this business"}}}}}}},"/api/v1/business/{businessId}/taxes/locations/{locationId}/settings":{"get":{"tags":["Taxes"],"security":[{"bearerAuth":[]}],"summary":"Get location tax settings","parameters":[{"name":"businessId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"locationId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Location tax settings fetched successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LocationTaxSettingsResponse"}}}},"404":{"description":"Location not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"success":false,"message":"Location not found"}}}}}},"patch":{"tags":["Taxes"],"security":[{"bearerAuth":[]}],"summary":"Update location tax settings","description":"Set the location tax mode to inherit, exempt, or use a custom default tax. This affects add-to-cart and pricing calculations for all items that do not use an item-level custom or exempt setting.","parameters":[{"name":"businessId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"locationId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/ScopedTaxSettingsRequest"},{"type":"object","properties":{"defaultTaxId":{"type":"string","format":"uuid","nullable":true}}}]}}}},"responses":{"200":{"description":"Location tax settings updated successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LocationTaxSettingsResponse"}}}},"400":{"description":"defaultTaxId is invalid for the chosen taxMode or belongs to another business","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"success":false,"message":"defaultTaxId is invalid for the chosen taxMode or belongs to another business"}}}},"404":{"description":"Location not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"success":false,"message":"Location not found"}}}}}}},"/api/v1/business/{businessId}/taxes/items/{itemId}/settings":{"get":{"tags":["Taxes"],"security":[{"bearerAuth":[]}],"summary":"Get item tax settings","parameters":[{"name":"businessId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"itemId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Item tax settings fetched successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ItemTaxSettingsResponse"}}}},"404":{"description":"Item not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"success":false,"message":"Item not found"}}}}}},"patch":{"tags":["Taxes"],"security":[{"bearerAuth":[]}],"summary":"Update item tax settings","description":"Set the item tax mode to inherit, exempt, or use a custom tax. Item settings have the highest precedence in pricing and add-to-cart calculations.","parameters":[{"name":"businessId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"itemId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/ScopedTaxSettingsRequest"},{"type":"object","properties":{"taxId":{"type":"string","format":"uuid","nullable":true}}}]}}}},"responses":{"200":{"description":"Item tax settings updated successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ItemTaxSettingsResponse"}}}},"400":{"description":"taxId is invalid for the chosen taxMode or belongs to another business","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"success":false,"message":"taxId is invalid for the chosen taxMode or belongs to another business"}}}},"404":{"description":"Item not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"success":false,"message":"Item not found"}}}}}}},"/api/v1/business/{businessId}/taxes/{taxId}":{"get":{"tags":["Taxes"],"security":[{"bearerAuth":[]}],"summary":"Get tax","parameters":[{"name":"businessId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"taxId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Tax fetched successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TaxResponse"}}}},"404":{"description":"Tax not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"success":false,"message":"Tax not found"}}}}}},"patch":{"tags":["Taxes"],"security":[{"bearerAuth":[]}],"summary":"Update tax","parameters":[{"name":"businessId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"taxId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TaxUpdateRequest"}}}},"responses":{"200":{"description":"Tax updated successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TaxResponse"}}}},"404":{"description":"Tax not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"success":false,"message":"Tax not found"}}}},"409":{"description":"Tax name already exists","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"success":false,"message":"Tax name already exists"}}}}}},"delete":{"tags":["Taxes"],"security":[{"bearerAuth":[]}],"summary":"Delete tax","description":"Deletes a tax only when it is no longer referenced by business, location, item, or legacy tax assignment records.","parameters":[{"name":"businessId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"taxId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"204":{"description":"Tax deleted successfully"},"400":{"description":"Tax is still in use","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"success":false,"message":"Tax is still in use"}}}},"404":{"description":"Tax not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"success":false,"message":"Tax not found"}}}}}}},"/api/v1/business/{businessId}/menu/items":{"get":{"tags":["Menu"],"security":[{"bearerAuth":[]}],"summary":"List menu items","description":"Lists business menu items with optional location visibility filtering, category filtering, search, and relation inclusion. Use `include=categories,tags,modifiers` to include item categories, tags, and modifier groups.","parameters":[{"name":"businessId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"locationId","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"categoryId","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"search","in":"query","schema":{"type":"string"}},{"name":"page","in":"query","schema":{"type":"integer","minimum":1}},{"name":"pageSize","in":"query","schema":{"type":"integer","minimum":1,"maximum":100}},{"name":"include","in":"query","schema":{"type":"string","example":"categories,tags,modifiers"}}],"responses":{"200":{"description":"Menu items fetched successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MenuItemsResponse"}}}}}},"post":{"tags":["Menu"],"security":[{"bearerAuth":[]}],"summary":"Create menu item","description":"Creates a menu item and optionally assigns categories and tags within the same business.","parameters":[{"name":"businessId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MenuItemRequest"}}}},"responses":{"201":{"description":"Menu item created successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MenuItemWriteResponse"}}}},"400":{"description":"Categories or tags are invalid for this business","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"success":false,"message":"Categories or tags are invalid for this business"}}}},"409":{"description":"Item SKU or slug already exists","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"success":false,"message":"Item SKU or slug already exists"}}}}}}},"/api/v1/business/{businessId}/menu/items/{itemId}":{"get":{"tags":["Menu"],"security":[{"bearerAuth":[]}],"summary":"Get menu item with modifier groups","parameters":[{"name":"businessId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"itemId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"include","in":"query","schema":{"type":"string","example":"categories,tags,modifiers"}}],"responses":{"200":{"description":"Menu item fetched successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MenuItemResponse"}}}}}},"patch":{"tags":["Menu"],"security":[{"bearerAuth":[]}],"summary":"Update menu item","parameters":[{"name":"businessId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"itemId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MenuItemRequest"}}}},"responses":{"200":{"description":"Menu item updated successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MenuItemWriteResponse"}}}},"400":{"description":"Categories or tags are invalid for this business","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"success":false,"message":"Categories or tags are invalid for this business"}}}},"404":{"description":"Item not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"success":false,"message":"Item not found"}}}},"409":{"description":"Item SKU or slug already exists","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"success":false,"message":"Item SKU or slug already exists"}}}}}},"delete":{"tags":["Menu"],"security":[{"bearerAuth":[]}],"summary":"Delete menu item","parameters":[{"name":"businessId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"itemId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"204":{"description":"Menu item deleted successfully"}}}},"/api/v1/business/{businessId}/menu/items/{itemId}/locations":{"post":{"tags":["Menu"],"security":[{"bearerAuth":[]}],"summary":"Assign item to location with overrides","description":"Creates or updates a location-specific assignment for an item. On update, omitted override fields preserve existing values.","parameters":[{"name":"businessId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"itemId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AssignItemLocationRequest"}}}},"responses":{"200":{"description":"Item assigned to location successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MenuLocationAssignmentResponse"}}}},"400":{"description":"Location is invalid for this business","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"success":false,"message":"Location is invalid for this business"}}}},"404":{"description":"Item or location not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"success":false,"message":"Item or location not found"}}}}}}},"/api/v1/business/{businessId}/menu/locations/{locationId}/menu":{"get":{"tags":["Menu"],"security":[{"bearerAuth":[]}],"summary":"Get menu visible for a location","parameters":[{"name":"businessId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"locationId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Location menu fetched successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LocationMenuResponse"}}}}}}},"/api/v1/business/{businessId}/modifier-groups":{"get":{"tags":["Modifiers"],"security":[{"bearerAuth":[]}],"summary":"List modifier groups","parameters":[{"name":"businessId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"search","in":"query","schema":{"type":"string"}},{"name":"page","in":"query","schema":{"type":"integer","minimum":1}},{"name":"pageSize","in":"query","schema":{"type":"integer","minimum":1,"maximum":100}}],"responses":{"200":{"description":"Modifier groups fetched successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ModifierGroupsResponse"}}}}}},"post":{"tags":["Modifiers"],"security":[{"bearerAuth":[]}],"summary":"Create modifier group","description":"Creates an option set that can be attached to items or triggered by a modifier in another group.","parameters":[{"name":"businessId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ModifierGroupRequest"}}}},"responses":{"201":{"description":"Modifier group created successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ModifierGroupResponse"}}}},"400":{"description":"minSelect cannot be greater than maxSelect","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"success":false,"message":"minSelect cannot be greater than maxSelect"}}}},"409":{"description":"Modifier group name already exists","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"success":false,"message":"Modifier group name already exists"}}}}}}},"/api/v1/business/{businessId}/modifier-groups/{groupId}":{"get":{"tags":["Modifiers"],"security":[{"bearerAuth":[]}],"summary":"Get modifier group","parameters":[{"name":"businessId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"groupId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Modifier group fetched successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ModifierGroupDetailResponse"}}}},"404":{"description":"Modifier group not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"success":false,"message":"Modifier group not found"}}}}}},"patch":{"tags":["Modifiers"],"security":[{"bearerAuth":[]}],"summary":"Update modifier group","parameters":[{"name":"businessId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"groupId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ModifierGroupUpdateRequest"}}}},"responses":{"200":{"description":"Modifier group updated successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ModifierGroupResponse"}}}},"400":{"description":"Invalid selection constraints for this modifier group","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"success":false,"message":"Invalid selection constraints for this modifier group"}}}},"404":{"description":"Modifier group not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"success":false,"message":"Modifier group not found"}}}},"409":{"description":"Modifier group name already exists","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"success":false,"message":"Modifier group name already exists"}}}}}},"delete":{"tags":["Modifiers"],"security":[{"bearerAuth":[]}],"summary":"Delete modifier group","description":"Deletes a modifier group only when it is not assigned to items, not reused as a child group, and has no modifiers remaining.","parameters":[{"name":"businessId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"groupId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"204":{"description":"Modifier group deleted successfully"},"400":{"description":"Modifier group still has modifiers, item assignments, or child-group usage","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"success":false,"message":"Modifier group still has modifiers, item assignments, or child-group usage"}}}},"404":{"description":"Modifier group not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"success":false,"message":"Modifier group not found"}}}}}}},"/api/v1/business/{businessId}/modifier-groups/{groupId}/options":{"get":{"tags":["Modifiers"],"security":[{"bearerAuth":[]}],"summary":"List options in a modifier group","parameters":[{"name":"businessId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"groupId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"search","in":"query","schema":{"type":"string"}},{"name":"page","in":"query","schema":{"type":"integer","minimum":1}},{"name":"pageSize","in":"query","schema":{"type":"integer","minimum":1,"maximum":100}}],"responses":{"200":{"description":"Modifier group options fetched successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ModifiersResponse"}}}},"404":{"description":"Modifier group not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"success":false,"message":"Modifier group not found"}}}}}},"post":{"tags":["Modifiers"],"security":[{"bearerAuth":[]}],"summary":"Create option in a modifier group","description":"Creates one selectable option inside a modifier group. Default options must be available and cannot exceed the group maxSelect.","parameters":[{"name":"businessId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"groupId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ModifierRequest"}}}},"responses":{"201":{"description":"Modifier group option created successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ModifierResponseEnvelope"}}}},"400":{"description":"Invalid default/availability combination or defaults exceed maxSelect","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"success":false,"message":"Invalid default/availability combination or defaults exceed maxSelect"}}}},"404":{"description":"Modifier group not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"success":false,"message":"Modifier group not found"}}}},"409":{"description":"Modifier name already exists in this group","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"success":false,"message":"Modifier name already exists in this group"}}}}}}},"/api/v1/business/{businessId}/modifier-groups/{groupId}/options/{modifierId}":{"get":{"tags":["Modifiers"],"security":[{"bearerAuth":[]}],"summary":"Get option in a modifier group","parameters":[{"name":"businessId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"groupId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"modifierId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Modifier group option fetched successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ModifierResponseEnvelope"}}}},"404":{"description":"Modifier not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"success":false,"message":"Modifier not found"}}}}}},"patch":{"tags":["Modifiers"],"security":[{"bearerAuth":[]}],"summary":"Update option in a modifier group","parameters":[{"name":"businessId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"groupId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"modifierId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ModifierUpdateRequest"}}}},"responses":{"200":{"description":"Modifier group option updated successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ModifierResponseEnvelope"}}}},"400":{"description":"Invalid default/availability combination or defaults exceed maxSelect","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"success":false,"message":"Invalid default/availability combination or defaults exceed maxSelect"}}}},"404":{"description":"Modifier not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"success":false,"message":"Modifier not found"}}}},"409":{"description":"Modifier name already exists in this group","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"success":false,"message":"Modifier name already exists in this group"}}}}}},"delete":{"tags":["Modifiers"],"security":[{"bearerAuth":[]}],"summary":"Delete option in a modifier group","description":"Deletes an option and cleans up its location overrides and nested child-group relations. Use this when the option should be removed from the catalog model.","parameters":[{"name":"businessId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"groupId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"modifierId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"204":{"description":"Modifier deleted successfully"},"404":{"description":"Modifier not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"success":false,"message":"Modifier not found"}}}}}}},"/api/v1/business/{businessId}/modifiers/items/{itemId}/groups":{"post":{"tags":["Modifiers"],"security":[{"bearerAuth":[]}],"summary":"Assign modifier group to item","description":"Attaches a root modifier group to an item. Repeated calls update the sort order.","parameters":[{"name":"businessId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"itemId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AssignModifierGroupToItemRequest"}}}},"responses":{"200":{"description":"Modifier group assigned successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ModifierAssignmentResponse"}}}},"404":{"description":"Item or modifier group not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"success":false,"message":"Item or modifier group not found"}}}}}}},"/api/v1/business/{businessId}/modifiers/{modifierId}/child-groups":{"post":{"tags":["Modifiers"],"security":[{"bearerAuth":[]}],"summary":"Attach child modifier group to modifier","description":"Links a parent modifier option to a child modifier group for nth-level option flows. The same child group may be reused under multiple parents. Cycles are blocked.","parameters":[{"name":"businessId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"modifierId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ModifierRelationRequest"}}}},"responses":{"201":{"description":"Modifier relation created successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ModifierRelationResponse"}}}},"400":{"description":"Relation would create a cycle","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"success":false,"message":"Relation would create a cycle"}}}},"404":{"description":"Parent modifier or child group is invalid for this business","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"success":false,"message":"Parent modifier or child group is invalid for this business"}}}}}}},"/api/v1/business/{businessId}/modifiers/items/{itemId}/tree":{"get":{"tags":["Modifiers"],"security":[{"bearerAuth":[]}],"summary":"Get modifier tree for an item","description":"Returns the resolved nested modifier tree for an item. When a location is provided, location-level availability and price overrides are applied.","parameters":[{"name":"businessId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"itemId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"locationId","in":"query","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Modifier tree fetched successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ModifierTreeResponse"}}}},"404":{"description":"Item or modifier group not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"success":false,"message":"Item or modifier group not found"}}}}}}},"/api/v1/business/{businessId}/pricing/items/{itemId}/calculate":{"post":{"tags":["Pricing"],"security":[{"bearerAuth":[]}],"summary":"Calculate single item price","description":"Validates the selection path against the modifier tree, applies defaults when no explicit choice is provided, and calculates the final price. Tax precedence is item setting → location setting → business setting → legacy item tax mappings.","parameters":[{"name":"businessId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"itemId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ItemPriceCalculationRequest"}}}},"responses":{"200":{"description":"Price calculated successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PricingResponse"}}}},"400":{"description":"Invalid selection path, group selection rule, or unavailable item/modifier","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"success":false,"message":"Invalid selection path, group selection rule, or unavailable item/modifier"}}}},"404":{"description":"Item not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"success":false,"message":"Item not found"}}}}}}},"/api/v1/business/{businessId}/pricing/cart/calculate":{"post":{"tags":["Pricing"],"security":[{"bearerAuth":[]}],"summary":"Calculate cart total","description":"Calculates all cart lines with nested modifiers using the same pricing rules as single-item calculation, including tax precedence from item, location, and business settings.","parameters":[{"name":"businessId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CartCalculationRequest"}}}},"responses":{"200":{"description":"Cart calculated successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CartPricingResponse"}}}},"400":{"description":"Invalid location or one or more invalid item modifier selections","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"success":false,"message":"Invalid location or one or more invalid item modifier selections"}}}}}}},"/api/v1/business/{businessId}/products":{"get":{"tags":["Products"],"summary":"Get business-wide catalog listing with category tree","description":"Primary catalog endpoint for business-wide menu/catalog views. Use `include=categories,tags,modifiers` to include the category tree, item categories, tags, and modifier groups.","parameters":[{"name":"businessId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"search","in":"query","schema":{"type":"string"}},{"name":"page","in":"query","schema":{"type":"integer","minimum":1}},{"name":"pageSize","in":"query","schema":{"type":"integer","minimum":1,"maximum":100}},{"name":"include","in":"query","schema":{"type":"string","example":"categories,tags,modifiers"}}],"responses":{"200":{"description":"Products fetched successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductListingResponse"}}}}}}},"/api/v1/business/{businessId}/locations/{locationId}/products":{"get":{"tags":["Products"],"summary":"Get location catalog listing with category tree","description":"Canonical storefront/catalog endpoint for a specific location. Use `include=categories,tags,modifiers` to include the location-scoped category tree, item categories, tags, and modifier groups.","parameters":[{"name":"businessId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"locationId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"search","in":"query","schema":{"type":"string"}},{"name":"page","in":"query","schema":{"type":"integer","minimum":1}},{"name":"pageSize","in":"query","schema":{"type":"integer","minimum":1,"maximum":100}},{"name":"include","in":"query","schema":{"type":"string","example":"categories,tags,modifiers"}}],"responses":{"200":{"description":"Location products fetched successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductListingResponse"}}}}}}},"/api/v1/business/{businessId}/products/categories/{categoryId}/parents":{"put":{"tags":["Products"],"security":[{"bearerAuth":[]}],"summary":"Replace single parent category from product module","description":"Compatibility route for updating category parentage from the product module surface.","parameters":[{"name":"businessId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"categoryId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductParentsRequest"}}}},"responses":{"200":{"description":"Parent categories updated successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CategoryParentAssignmentsResponse"}}}},"400":{"description":"More than one parent, invalid parent category, or cyclic relation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"success":false,"message":"More than one parent, invalid parent category, or cyclic relation"}}}},"404":{"description":"Category not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"success":false,"message":"Category not found"}}}}}}},"/api/v1/business/{businessId}/locations/{locationId}/products/categories/{categoryId}/parents":{"put":{"tags":["Products"],"security":[{"bearerAuth":[]}],"summary":"Replace single parent category from location product module","description":"Location-scoped compatibility route for updating category parentage from the product module surface. The category change is still business-level; the location segment comes from the mounted products router.","parameters":[{"name":"businessId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"locationId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"categoryId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductParentsRequest"}}}},"responses":{"200":{"description":"Parent categories updated successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CategoryParentAssignmentsResponse"}}}},"400":{"description":"More than one parent, invalid parent category, or cyclic relation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"success":false,"message":"More than one parent, invalid parent category, or cyclic relation"}}}},"404":{"description":"Category not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"success":false,"message":"Category not found"}}}}}}},"/api/v1/public/locations/{locationId}/products":{"get":{"tags":["Public"],"summary":"Get public catalog listing for a location","description":"Public website/mobile catalog endpoint. Use `include=categories,tags,modifiers` to include the location-scoped category tree, item categories, tags, and modifier groups.","parameters":[{"name":"locationId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"search","in":"query","schema":{"type":"string"}},{"name":"page","in":"query","schema":{"type":"integer","minimum":1}},{"name":"pageSize","in":"query","schema":{"type":"integer","minimum":1,"maximum":100}},{"name":"include","in":"query","schema":{"type":"string","example":"categories,tags,modifiers"}}],"responses":{"200":{"description":"Public products fetched successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductListingResponse"}}}}}}},"/api/v1/public/locations/{locationId}/menu":{"get":{"tags":["Public"],"summary":"Get public menu for a location","parameters":[{"name":"locationId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Public menu fetched successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LocationMenuResponse"}}}}}}},"/api/v1/public/items/{itemId}":{"get":{"tags":["Public"],"summary":"Get public item with resolved modifiers","description":"Returns a menu item with its resolved nested modifier tree. When locationId is provided, location-specific overrides are applied.","parameters":[{"name":"itemId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"locationId","in":"query","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Public item fetched successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicItemResponse"}}}}}}},"/api/v1/public/cart/calculate":{"post":{"tags":["Public"],"summary":"Calculate public cart","description":"Public pricing endpoint using the same nested modifier validation, tax precedence, and pricing rules as private cart calculation.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CartCalculationRequest"}}}},"responses":{"200":{"description":"Public cart calculated successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CartPricingResponse"}}}}}}}},"tags":[{"name":"System","description":"Health checks and platform-level utility endpoints."},{"name":"Auth","description":"Signup, login, and business owner access flows."},{"name":"Location","description":"Business locations, hours, and location-linked catalog setup."},{"name":"Category","description":"Category tree management, parent assignment, and category-product links."},{"name":"Collections","description":"Storefront merchandising collections and collection item management."},{"name":"Tags","description":"Reusable item tags for menu filtering and merchandising."},{"name":"Taxes","description":"Reusable tax definitions plus business, location, and item tax settings."},{"name":"Menu","description":"Menu item CRUD, item-to-location overrides, and location menu views."},{"name":"Modifiers","description":"Modifier groups, modifiers, nested relations, and item assignments."},{"name":"Pricing","description":"Resolved pricing endpoints for items and carts."},{"name":"Products","description":"Frontend-ready business and location catalog listing endpoints."},{"name":"Public","description":"Public storefront menu, product, and pricing endpoints."}]}