basePath: /api/v1 definitions: admin.BanUserRequest: properties: duration_hours: description: nil for permanent ban type: integer reason: maxLength: 500 minLength: 10 type: string required: - reason type: object admin.BulkActionJobResponse: properties: job_id: type: string message: type: string status: description: '"queued", "processing", "completed", "failed"' type: string type: object admin.BulkActionRequest: properties: action: enum: - ban - unban - verify_email - delete - export type: string async: description: 'Optional: force async processing' type: boolean options: additionalProperties: {} type: object reason: type: string user_ids: items: type: string maxItems: 100 minItems: 1 type: array required: - action - user_ids type: object admin.CreateUserRequest: properties: email: type: string email_verified: type: boolean first_name: maxLength: 100 type: string last_name: maxLength: 100 type: string password: minLength: 8 type: string phone: type: string role: enum: - customer - vendor - admin type: string required: - email - password - role type: object admin.DeleteUserRequest: properties: reason: maxLength: 500 minLength: 10 type: string required: - reason type: object admin.EndImpersonateRequest: properties: session_id: type: string required: - session_id type: object admin.ImpersonateRequest: properties: duration_minutes: description: Max 8 hours maximum: 480 minimum: 1 type: integer reason: maxLength: 200 minLength: 10 type: string required: - reason type: object admin.ResetPasswordRequest: properties: new_password: maxLength: 128 minLength: 8 type: string reason: maxLength: 200 minLength: 10 type: string required: - new_password - reason type: object admin.RevokeAllSessionsRequest: properties: reason: maxLength: 200 type: string type: object admin.RevokeSessionRequest: properties: reason: maxLength: 200 type: string type: object admin.UpdateUserRequest: properties: email: type: string email_verified: type: boolean name: maxLength: 100 minLength: 2 type: string role: enum: - customer - vendor - moderator - admin - super_admin type: string type: object admin.WarnUserRequest: properties: message: maxLength: 1000 minLength: 20 type: string reason: maxLength: 500 minLength: 10 type: string severity: enum: - low - medium - high type: string required: - message - reason - severity type: object audit.AuditLogEntryDTO: properties: action: type: string actor_role: type: string changes: additionalProperties: $ref: '#/definitions/audit.Change' description: |- Changes is the field-level before/after of the audited action. The trail has stored and hydrated it all along; it was simply never exposed, so the admin UI had nothing to render and no way to tell that from "this action changed nothing". type: object created_at: type: string error_message: type: string event_category: type: string event_type: type: string id: type: string ip_address: type: string metadata: additionalProperties: true type: object request_id: type: string success: type: boolean target_id: type: string target_identifier: type: string target_type: type: string user_agent: type: string user_email: type: string user_id: type: string type: object audit.AuditLogsResponseDTO: properties: events: items: $ref: '#/definitions/audit.AuditLogEntryDTO' type: array total: type: integer type: object audit.Change: properties: new: {} old: {} type: object auth.AdminMeResponse: properties: created_at: type: string email: type: string email_verified: type: boolean email_verified_at: type: string first_name: type: string id: type: string last_login_at: type: string last_name: type: string phone: type: string role: type: string two_factor_enabled: type: boolean updated_at: type: string type: object auth.AuthUserResponse: properties: email: example: user@example.com type: string email_verified: example: false type: boolean first_name: example: John type: string id: example: 123e4567-e89b-12d3-a456-426614174000 type: string role: example: customer type: string type: object auth.ChangePasswordRequest: properties: current_password: type: string new_password: minLength: 8 type: string required: - current_password - new_password type: object auth.Enable2FARequestDTO: properties: code: type: string required: - code type: object auth.Enable2FASetupResponse: properties: backup_codes: items: type: string type: array qr_code: type: string secret: type: string type: object auth.ForgotPasswordRequestDTO: properties: email: type: string required: - email type: object auth.GoogleOneTapRequest: properties: credential: type: string required: - credential type: object auth.LoginRequestDTO: properties: email: type: string password: type: string required: - email - password type: object auth.LoginResponseDTO: properties: backup_codes_count: type: integer expires_in: type: integer two_factor_required: type: boolean two_factor_token: type: string user: $ref: '#/definitions/auth.AuthUserResponse' type: object auth.LogoutRequestDTO: properties: logout_all: type: boolean refresh_token: type: string type: object auth.OAuthCallbackResponseDTO: properties: expires_in: type: integer is_new_user: type: boolean user: $ref: '#/definitions/auth.AuthUserResponse' type: object auth.OTPRequest: properties: email: example: admin@university.edu type: string required: - email type: object auth.OTPResponse: properties: expires_in: example: 300 type: integer message: example: If an administrator account exists, a login code has been sent. type: string success: example: true type: boolean type: object auth.OTPVerifyRequest: properties: code: example: "123456" type: string email: example: admin@university.edu type: string required: - code - email type: object auth.OTPVerifyResponse: properties: expires_in: type: integer redirect_to: type: string two_factor_required: type: boolean two_factor_token: type: string user: $ref: '#/definitions/auth.AuthUserResponse' type: object auth.OTPWith2FAVerifyRequest: properties: backup_code: type: string code: type: string two_factor_token: type: string required: - two_factor_token type: object auth.RefreshTokenRequestDTO: properties: refresh_token: type: string type: object auth.RefreshTokenResponseDTO: properties: expires_in: type: integer type: object auth.RegisterResponse: properties: expires_in: type: integer message: type: string requires_verification: type: boolean user: $ref: '#/definitions/auth.AuthUserResponse' type: object auth.RegisterWithEmailRequest: properties: email: type: string first_name: type: string last_name: type: string password: minLength: 8 type: string phone: type: string required: - email - password type: object auth.ResetPasswordRequestDTO: properties: new_password: minLength: 8 type: string token: type: string required: - new_password - token type: object auth.SendVerificationTokenRequest: properties: email: type: string required: - email type: object auth.TwoFactorLoginRequestDTO: properties: backup_code: type: string code: type: string two_factor_token: type: string required: - two_factor_token type: object auth.Verify2FARequest: properties: code: type: string required: - code type: object auth.VerifyEmailRequest: properties: email: type: string token: type: string required: - email - token type: object auth.VerifyEmailResponse: properties: expires_in: type: integer redirect_to: type: string user: $ref: '#/definitions/auth.AuthUserResponse' type: object booking.AddDateOverrideRequest: properties: date: description: '"YYYY-MM-DD"' type: string is_closed: description: true = fully unavailable type: boolean reason: description: e.g. "Christmas holiday" type: string time_slots: description: custom hours if not closed items: $ref: '#/definitions/booking.TimeSlotRequest' type: array required: - date type: object booking.AddReviewRequestDTO: properties: comment: type: string rating: maximum: 5 minimum: 1 type: integer required: - rating type: object booking.AdminBulkRefundRequestDTO: properties: booking_ids: items: type: string maxItems: 100 minItems: 1 type: array reason: type: string required: - booking_ids type: object booking.AdminBulkRefundResponseDTO: properties: failure_count: type: integer results: items: $ref: '#/definitions/booking.AdminBulkRefundResultDTO' type: array success_count: type: integer type: object booking.AdminBulkRefundResultDTO: properties: booking_id: type: string error: type: string success: type: boolean type: object booking.AdminCancelRequestDTO: properties: override_refund: type: number reason: type: string type: object booking.AdminCancelResponseDTO: properties: booking: $ref: '#/definitions/booking.BookingResponseDTO' refund_amount: type: number refund_percent: type: integer type: object booking.AdminFlagBookingRequestDTO: properties: reason: maxLength: 500 minLength: 3 type: string severity: enum: - low - medium - high type: string required: - reason - severity type: object booking.AdminRefundRequestDTO: properties: reason: type: string type: object booking.AdminRefundResponseDTO: properties: booking: $ref: '#/definitions/booking.BookingResponseDTO' type: object booking.AvailabilityResponse: properties: created_at: type: string id: type: string is_active: type: boolean provider_id: type: string schedule: items: $ref: '#/definitions/booking.DayAvailability' type: array service_id: type: string timezone: type: string updated_at: type: string type: object booking.AvailabilitySlotResponseDTO: properties: end_time: type: string is_available: type: boolean start_time: type: string type: object booking.BookingFlagResponseDTO: properties: booking_id: type: string created_at: type: string flagged_by: type: string id: type: string is_active: type: boolean reason: type: string resolved_at: type: string resolved_by: type: string severity: type: string type: object booking.BookingResponseDTO: properties: booking_code: type: string booking_date: type: string booking_time: type: string cancel_reason: type: string created_at: type: string customer_first_name: type: string customer_id: type: string duration_minutes: type: integer end_time: type: string expires_at: type: string id: type: string notes: type: string payment_status: type: string provider_first_name: type: string provider_id: type: string reschedule_count: type: integer service_id: type: string service_slug: type: string service_title: description: Enriched fields — populated on list endpoints only type: string status: type: string total_price: type: number updated_at: type: string type: object booking.BookingStatus: enum: - pending - confirmed - in_progress - completed - cancelled - no_show type: string x-enum-varnames: - BookingStatusPending - BookingStatusConfirmed - BookingStatusInProgress - BookingStatusCompleted - BookingStatusCancelled - BookingStatusNoShow booking.BulkUpdateResponseDTO: properties: failure_count: type: integer results: items: $ref: '#/definitions/booking.BulkUpdateResultResponseDTO' type: array success_count: type: integer type: object booking.BulkUpdateResultResponseDTO: properties: booking_id: type: string error: type: string success: type: boolean type: object booking.BulkUpdateStatusRequestDTO: properties: booking_ids: items: type: string maxItems: 100 minItems: 1 type: array new_status: $ref: '#/definitions/booking.BookingStatus' reason: type: string required: - booking_ids - new_status type: object booking.CancelBookingRequestDTO: properties: reason: type: string type: object booking.CancelBookingResponseDTO: properties: booking: $ref: '#/definitions/booking.BookingResponseDTO' refund_amount: type: number refund_percent: type: integer type: object booking.CheckAvailabilityResponseDTO: properties: accepting_bookings: description: |- AcceptingBookings is false when the service has no active weekly schedule (never set up or paused) and true when it takes bookings but is full/closed on this date. type: boolean available_slots: items: $ref: '#/definitions/booking.AvailabilitySlotResponseDTO' type: array date: type: string duration_minutes: type: integer is_fully_booked: type: boolean service_id: type: string type: object booking.CreateBookingRequestDTO: properties: addon_option_ids: description: |- AddonOptionIDs are the optional extras chosen. Unlike the two fields above these are valid on every pricing model, because add-ons are orthogonal to how the base price is composed. The server prices them from the option rows: the customer says which extras, never what they cost. items: type: string type: array booking_date: description: |- BookingDate/BookingTime are required for slot-based bookings; digital package tiers are purchase-only and may omit them. The booking flow validates this per service, so they are not marked required here. type: string booking_time: description: HH:MM type: string menu_item_ids: description: |- MenuItemIDs are the selected menu items for menu-priced services; omitted for every other model. The server composes the total from these items. items: type: string type: array notes: type: string service_id: type: string service_tier_id: description: |- ServiceTierID is required for tiered services and omitted for every other model. The server-resolved booking flow enforces this. type: string required: - service_id type: object booking.CreateBookingResponseDTO: properties: booking_code: type: string created_at: type: string expires_at: description: |- ExpiresAt is set for manual-mode bookings — the vendor must confirm by this time or the booking is auto-canceled by the BookingExpiryJob worker. Null for instant-mode bookings (already confirmed). type: string id: type: string status: type: string total_price: type: number type: object booking.DateOverrideResponse: properties: created_at: type: string date: type: string id: type: string is_closed: type: boolean provider_id: type: string reason: type: string time_slots: items: $ref: '#/definitions/booking.TimeSlot' type: array type: object booking.DayAvailability: properties: day_of_week: $ref: '#/definitions/booking.DayOfWeek' is_enabled: type: boolean max_daily_bookings: description: |- MaxDailyBookings caps the total number of bookings for this day regardless of available time slots. 0 means unlimited (use slot count as the natural cap). Example: a photographer sets MaxDailyBookings=2 — even if 4 slots are open, only 2 bookings are accepted that day. Useful for days with flexible workload. type: integer time_slots: items: $ref: '#/definitions/booking.TimeSlot' type: array type: object booking.DayAvailabilityRequest: properties: day_of_week: maximum: 6 minimum: 0 type: integer is_enabled: type: boolean max_daily_bookings: description: |- MaxDailyBookings caps total bookings for this day. 0 = unlimited (natural cap from slots). Example: photographer sets 2 — only 2 sessions per day even if 4 time slots are open. type: integer time_slots: description: required when is_enabled=true items: $ref: '#/definitions/booking.TimeSlotRequest' type: array type: object booking.DayOfWeek: enum: - 0 - 1 - 2 - 3 - 4 - 5 - 6 type: integer x-enum-varnames: - Sunday - Monday - Tuesday - Wednesday - Thursday - Friday - Saturday booking.FlaggedBookingResponseDTO: properties: booking: $ref: '#/definitions/booking.BookingResponseDTO' flag: $ref: '#/definitions/booking.BookingFlagResponseDTO' type: object booking.PayBookingRequestDTO: properties: callback_url: type: string email: description: Email is optional; the authenticated user's own email is used when omitted. type: string required: - callback_url type: object booking.PayBookingResponseDTO: properties: checkout_url: type: string reference: type: string type: object booking.RescheduleBookingRequestDTO: properties: new_booking_date: description: YYYY-MM-DD type: string new_booking_time: description: HH:MM type: string required: - new_booking_date - new_booking_time type: object booking.ReviewResponseDTO: properties: booking_id: type: string comment: type: string created_at: type: string id: type: string provider_response: type: string rating: type: integer responded_at: type: string type: object booking.SetScheduleRequest: properties: schedule: description: must have 7 entries items: $ref: '#/definitions/booking.DayAvailabilityRequest' type: array timezone: description: IANA tz e.g. "Africa/Accra" type: string required: - schedule - timezone type: object booking.StatsResponseDTO: properties: average_booking_value: type: number canceled_bookings: type: integer cancellation_rate: type: number completed_bookings: type: integer completion_rate: type: number confirmed_bookings: type: integer no_show_bookings: type: integer pending_bookings: type: integer total_bookings: type: integer total_revenue: type: number type: object booking.TimeSlot: properties: end_time: description: 'Format: "HH:MM"' type: string start_time: description: 'Format: "HH:MM"' type: string type: object booking.TimeSlotRequest: properties: end_time: description: '"HH:MM" 24-hour' type: string start_time: description: '"HH:MM" 24-hour' type: string required: - end_time - start_time type: object booking.UpdateBookingReviewRequest: properties: comment: maxLength: 2000 minLength: 1 type: string rating: maximum: 5 minimum: 1 type: integer type: object cart.AbandonedProductResponse: properties: abandoned_count: type: integer product_id: type: string product_name: type: string store_id: type: string store_name: type: string total_quantity: type: integer total_value: type: string type: object cart.ActorType: enum: - user - system - admin type: string x-enum-varnames: - ActorTypeUser - ActorTypeSystem - ActorTypeAdmin cart.AddNoteRequest: properties: note: maxLength: 2000 minLength: 1 type: string required: - note type: object cart.AddToCartRequestDTO: properties: product_id: type: string quantity: maximum: 99 minimum: 1 type: integer variant_id: type: string required: - product_id - quantity type: object cart.BulkAddItemRequest: properties: product_id: type: string quantity: maximum: 100 minimum: 1 type: integer required: - product_id - quantity type: object cart.BulkAddToCartRequestDTO: properties: items: items: $ref: '#/definitions/cart.BulkAddItemRequest' maxItems: 20 minItems: 1 type: array required: - items type: object cart.CappedItemDTO: properties: capped: type: integer product_id: type: string requested: type: integer type: object cart.CartAction: enum: - created - item_added - item_removed - item_quantity_updated - cleared - abandoned - recovered - converted - expired - merged - flagged - unflagged - note_added - recovery_email_sent type: string x-enum-varnames: - CartActionCreated - CartActionItemAdded - CartActionItemRemoved - CartActionItemQuantityUpdated - CartActionCleared - CartActionAbandoned - CartActionRecovered - CartActionConverted - CartActionExpired - CartActionMerged - CartActionFlagged - CartActionUnflagged - CartActionNoteAdded - CartActionRecoveryEmailSent cart.CartActionHistory: properties: action: $ref: '#/definitions/cart.CartAction' actor_id: type: string actor_type: $ref: '#/definitions/cart.ActorType' cart_id: type: string created_at: type: string details: {} id: type: string ip_address: type: string user_agent: type: string type: object cart.CartActionHistoryDTO: properties: action: type: string actor_id: type: string actor_type: type: string created_at: type: string description: type: string id: type: string new_value: type: string old_value: type: string type: object cart.CartAdminNoteDTO: properties: admin_id: type: string created_at: type: string id: type: string note: type: string type: object cart.CartAdminResponse: properties: abandoned_at: type: string converted_at: type: string created_at: type: string currency: type: string flagged: type: boolean flagged_reason: type: string id: type: string items: items: $ref: '#/definitions/cart.CartItemResponse' type: array items_by_store: additionalProperties: items: $ref: '#/definitions/cart.CartItemResponse' type: array type: object items_count: type: integer last_activity_at: type: string recovery_sent: type: boolean session_id: type: string status: type: string total_value: type: string updated_at: type: string user_id: type: string type: object cart.CartAnalyticsResponse: properties: abandoned_cart_value: type: string abandonment_rate: type: number average_cart_value: type: string calculated_at: type: string conversion_rate: type: number new_carts_7d: type: integer new_carts_30d: type: integer new_carts_today: type: integer recovered_carts: type: integer recovery_emails_sent: type: integer recovery_rate: type: number total_abandoned_carts: type: integer total_active_carts: type: integer total_cart_value: type: string total_converted_carts: type: integer total_expired_carts: type: integer type: object cart.CartDetailResponse: properties: cart: $ref: '#/definitions/cart.CartAdminResponse' history: items: $ref: '#/definitions/cart.CartActionHistoryDTO' type: array notes: items: $ref: '#/definitions/cart.CartAdminNoteDTO' type: array type: object cart.CartItemResponse: properties: added_at: type: string currency: type: string current_price: description: live price — compare with price_at_add type: string id: type: string in_stock: description: false = block checkout for this item type: boolean line_total: type: string price_at_add: type: string product_id: type: string product_image_url: type: string product_name: description: Enriched fields — populated from product/store/images tables via batch query type: string product_slug: type: string quantity: type: integer store_id: type: string store_name: type: string store_slug: type: string variant_id: type: string variant_name: type: string type: object cart.CartListResponse: properties: carts: items: $ref: '#/definitions/cart.CartAdminResponse' type: array limit: type: integer page: type: integer total: type: integer type: object cart.CartResponse: properties: currency: type: string id: type: string items: items: $ref: '#/definitions/cart.CartItemResponse' type: array items_by_store: additionalProperties: items: $ref: '#/definitions/cart.CartItemResponse' type: array type: object items_count: type: integer session_id: type: string status: type: string total_value: type: string user_id: type: string type: object cart.CheckoutItemResponse: properties: product_id: type: string quantity: type: integer store_id: type: string total_price: type: string unit_price: type: string type: object cart.CheckoutSessionResponse: properties: cart_id: type: string currency: type: string items: items: $ref: '#/definitions/cart.CheckoutItemResponse' type: array items_by_store: additionalProperties: items: $ref: '#/definitions/cart.CheckoutItemResponse' type: array type: object items_count: type: integer total_value: type: string user_id: type: string type: object cart.FlagCartRequest: properties: reason: maxLength: 500 minLength: 1 type: string required: - reason type: object cart.MergeGuestCartResponseDTO: properties: capped_items: items: $ref: '#/definitions/cart.CappedItemDTO' type: array cart: $ref: '#/definitions/cart.CartResponse' items_merged: type: integer new_cart_created: type: boolean type: object cart.MessageResponse: properties: message: type: string type: object cart.ProductCartStatsDTO: properties: count: type: integer product_id: type: string product_name: type: string total_value: type: string type: object cart.SendRecoveryRequest: properties: custom_message: type: string discount_code: type: string type: object cart.StoreCartAnalyticsResponse: properties: abandoned_carts: type: integer abandonment_rate: type: number add_to_cart_rate: type: number average_cart_value: type: string carts_containing_products: type: integer conversion_rate: type: number converted_carts: type: integer most_abandoned_products: items: $ref: '#/definitions/cart.ProductCartStatsDTO' type: array most_added_products: items: $ref: '#/definitions/cart.ProductCartStatsDTO' type: array store_id: type: string total_abandoned_value: type: string type: object cart.UpdateCartItemRequestDTO: properties: quantity: maximum: 99 minimum: 1 type: integer required: - quantity type: object category.AddAttributeValueRequest: properties: hex: type: string position: type: integer value: type: string required: - value type: object category.AdminListCategoriesResponse: properties: active_count: type: integer categories: items: $ref: '#/definitions/category.CategoryResponse' type: array deleted_count: type: integer pagination: $ref: '#/definitions/pagination.Pagination' total_count: type: integer type: object category.AttributePositionDTO: properties: attribute_id: type: string position: type: integer required: - attribute_id type: object category.AttributeValueDTO: properties: hex: description: |- Hex is the colour a swatch value paints. Absent unless a merchandiser authored one, which leaves the client to resolve the colour from the value's name and fall back to a neutral. type: string id: type: string is_filterable: description: |- IsFilterable is whether this value may appear as a facet option. It is derived rather than stored: an admin-authored or promoted value filters, a raw vendor value only displays. type: boolean is_promoted: type: boolean position: type: integer source: type: string usage_count: type: integer value: type: string type: object category.BreadcrumbItemResponse: properties: id: type: string is_active: type: boolean level: type: integer name: type: string slug: type: string type: object category.BreadcrumbResponse: properties: breadcrumb: items: $ref: '#/definitions/category.BreadcrumbItemResponse' type: array category: $ref: '#/definitions/category.CategoryResponse' type: object category.BulkActionRequestDTO: properties: category_ids: items: type: string maxItems: 100 minItems: 1 type: array required: - category_ids type: object category.BulkActionResponseDTO: properties: failed_ids: items: type: string type: array failure_count: type: integer message: type: string success_count: type: integer type: object category.CategoryAncestorResponse: properties: id: type: string name: type: string slug: type: string type: object category.CategoryNavChild: properties: id: type: string image_url: type: string name: type: string slug: type: string type: object category.CategoryNavItem: properties: children: items: $ref: '#/definitions/category.CategoryNavChild' type: array color: type: string id: type: string image_url: type: string name: type: string slug: type: string trending_products: items: $ref: '#/definitions/category.CategoryNavProduct' type: array type: object category.CategoryNavProduct: properties: id: type: string price: type: string primary_image: type: string slug: type: string title: type: string type: object category.CategoryOrderItem: properties: category_id: type: string position: minimum: 0 type: integer required: - category_id type: object category.CategoryResponse: properties: ancestors: description: |- Ancestors is the trail from the root down to this node's parent. Only search results carry it — a tree response already shows ancestry by its shape, and a flat result list is the only place it is missing. items: $ref: '#/definitions/category.CategoryAncestorResponse' type: array children: items: $ref: '#/definitions/category.CategoryResponse' type: array color: type: string created_at: type: string deleted_at: type: string description: type: string display_order: type: integer id: type: string image_url: type: string is_active: type: boolean is_featured: type: boolean is_leaf: description: |- IsLeaf is a pointer so that absent and false stay distinguishable: not every endpoint knows whether a node has children, and reporting "no" when the answer is "not looked up" would let a caller file a listing under a group. type: boolean level: type: integer meta_description: type: string meta_title: type: string name: type: string parent_id: type: string path: type: string product_count: type: integer service_count: type: integer slug: type: string synonyms: items: type: string type: array type: type: string updated_at: type: string type: object category.CategorySelectItem: properties: has_children: type: boolean id: type: string image_url: type: string level: type: integer name: type: string parent_id: type: string slug: type: string type: type: string type: object category.CategoryStatisticsResponse: properties: active_product_count: type: integer active_service_count: type: integer category_id: type: string product_count: type: integer service_count: type: integer subcategory_count: type: integer total_item_count: type: integer type: object category.CategoryTreeMetadataResponse: properties: max_depth: type: integer root_categories: type: integer total_categories: type: integer type: object category.CategoryTreeNodeResponse: properties: category: $ref: '#/definitions/category.CategoryResponse' children: items: $ref: '#/definitions/category.CategoryTreeNodeResponse' type: array type: object category.CategoryTreeResponseDTO: properties: metadata: $ref: '#/definitions/category.CategoryTreeMetadataResponse' tree: items: $ref: '#/definitions/category.CategoryTreeNodeResponse' type: array type: object category.CreateCategoryRequestDTO: properties: color: type: string description: maxLength: 500 type: string display_order: minimum: 0 type: integer image_url: type: string is_active: type: boolean is_featured: type: boolean meta_description: maxLength: 1000 type: string meta_title: maxLength: 255 type: string name: maxLength: 100 minLength: 2 type: string parent_id: type: string slug: maxLength: 100 type: string type: enum: - product - service type: string required: - name - type type: object category.DeclareAttributeRequest: properties: display_type: type: string is_filterable: type: boolean is_required: type: boolean is_variant: type: boolean key: type: string name: type: string position: type: integer unit: type: string required: - display_type - key - name type: object category.EffectiveAttributeDTO: properties: declared_by: description: |- DeclaredBy names the category that declared the attribute, which the UI needs in order to explain why an inherited attribute cannot be removed here. type: string display_type: type: string id: type: string inherited: type: boolean is_filterable: description: IsFilterable is whether the attribute itself may be faceted at all. type: boolean is_required: description: IsRequired is whether a listing may be published without it. type: boolean is_variant: type: boolean key: type: string name: type: string permitted_values: items: $ref: '#/definitions/category.AttributeValueDTO' type: array position: type: integer unit: type: string type: object category.EffectiveTemplateResponse: properties: attributes: items: $ref: '#/definitions/category.EffectiveAttributeDTO' type: array category_id: type: string specs: items: $ref: '#/definitions/category.EffectiveAttributeDTO' type: array variants: description: |- Variants and Specs partition Attributes by whether they mint SKUs. Both are supplied because the two drive different parts of a listing form and splitting them client-side would duplicate the rule. items: $ref: '#/definitions/category.EffectiveAttributeDTO' type: array type: object category.GetCategoryNavResponse: properties: categories: items: $ref: '#/definitions/category.CategoryNavItem' type: array type: object category.GetCategorySelectResponse: properties: categories: items: $ref: '#/definitions/category.CategorySelectItem' type: array type: object category.GlobalStatisticsResponseDTO: properties: active_categories: type: integer average_items_per_category: type: number categories_with_items: type: integer empty_categories: type: integer featured_categories: type: integer inactive_categories: type: integer product_categories: type: integer root_categories: type: integer service_categories: type: integer total_categories: type: integer total_subcategories: type: integer type: object category.MoveCategoryRequestDTO: properties: new_parent_id: type: string type: object category.NarrowAttributeRequest: properties: value_ids: items: type: string minItems: 1 type: array required: - value_ids type: object category.ReorderAttributesRequest: properties: positions: items: $ref: '#/definitions/category.AttributePositionDTO' minItems: 1 type: array required: - positions type: object category.ReorderCategoriesRequestDTO: properties: orders: items: $ref: '#/definitions/category.CategoryOrderItem' minItems: 1 type: array parent_id: type: string required: - orders type: object category.SearchCategoriesResponseDTO: properties: categories: items: $ref: '#/definitions/category.CategoryResponse' type: array pagination: $ref: '#/definitions/pagination.Pagination' type: object category.UpdateAttributeRequest: properties: display_type: type: string is_filterable: type: boolean is_required: type: boolean is_variant: type: boolean name: type: string unit: type: string type: object category.UpdateCategoryRequestDTO: properties: color: type: string description: maxLength: 500 type: string display_order: minimum: 0 type: integer image_url: type: string is_active: type: boolean is_featured: type: boolean meta_description: maxLength: 1000 type: string meta_title: maxLength: 255 type: string name: maxLength: 100 minLength: 2 type: string slug: maxLength: 100 minLength: 2 type: string synonyms: description: |- Synonyms is a whole-list replacement, not an append. Omitting the key leaves the existing aliases alone; sending [] clears them. items: type: string maxItems: 25 type: array type: object category.UploadCategoryImageResponse: properties: message: type: string queued_at: type: string status: type: string upload_id: type: string type: object dispute.ActivityResponse: properties: action: type: string created_at: type: string description: type: string dispute_id: type: string id: type: string metadata: additionalProperties: true type: object new_value: type: string old_value: type: string performed_by: type: string performer_type: type: string type: object dispute.AdminAssignRequest: properties: assign_to_id: type: string required: - assign_to_id type: object dispute.AdminDisputeDetailResponse: properties: activities: items: $ref: '#/definitions/dispute.ActivityResponse' type: array assigned_to: type: string buyer_expected_resolution: type: string buyer_id: type: string buyer_info: $ref: '#/definitions/dispute.UserSummaryDTO' created_at: type: string currency: type: string description: type: string dispute_number: type: string disputed_amount: type: string escalated_at: type: string evidence: items: $ref: '#/definitions/dispute.EvidenceResponse' type: array first_response_at: type: string id: type: string last_activity_at: type: string messages: items: $ref: '#/definitions/dispute.MessageResponse' type: array order_amount: type: string order_id: type: string order_info: $ref: '#/definitions/dispute.OrderSummaryDTO' order_number: type: string outcome: type: string priority: type: string reason: type: string refund_amount: type: string refunds: items: $ref: '#/definitions/dispute.RefundResponse' type: array resolution_summary: type: string resolved_at: type: string seller_id: type: string seller_info: $ref: '#/definitions/dispute.UserSummaryDTO' seller_response: type: string sla_breached: type: boolean sla_deadline: type: string sla_paused: type: boolean status: type: string store_id: type: string updated_at: type: string type: object dispute.AdminEscalateRequest: properties: reason: type: string required: - reason type: object dispute.AdminPauseSLARequestDTO: properties: reason: type: string required: - reason type: object dispute.AdminProcessRefundRequestDTO: properties: refund_id: type: string required: - refund_id type: object dispute.AdminResolveRequest: properties: outcome: type: string refund_amount: type: string refund_type: type: string resolution_summary: type: string required: - outcome - resolution_summary type: object dispute.AdminSendMessageRequestDTO: properties: content: type: string is_internal: type: boolean required: - content type: object dispute.AdminUpdateStatusRequestDTO: properties: reason: type: string status: type: string required: - status type: object dispute.CreateDisputeRequestDTO: properties: description: minLength: 20 type: string disputed_amount: type: string expected_resolution: type: string order_id: type: string reason: type: string required: - description - disputed_amount - order_id - reason type: object dispute.DisputeResponse: properties: assigned_to: type: string buyer_expected_resolution: type: string buyer_id: type: string created_at: type: string currency: type: string description: type: string dispute_number: type: string disputed_amount: type: string escalated_at: type: string first_response_at: type: string id: type: string last_activity_at: type: string order_amount: type: string order_id: type: string order_number: type: string outcome: type: string priority: type: string reason: type: string refund_amount: type: string resolution_summary: type: string resolved_at: type: string seller_id: type: string seller_response: type: string sla_breached: type: boolean sla_deadline: type: string sla_paused: type: boolean status: type: string store_id: type: string updated_at: type: string type: object dispute.EvidenceResponse: properties: created_at: type: string description: type: string dispute_id: type: string file_name: type: string file_size: type: integer file_type: type: string file_url: type: string id: type: string mime_type: type: string uploaded_by: type: string uploader_type: type: string type: object dispute.EvidenceUploadURLRequest: properties: content_type: type: string file_name: type: string file_size: description: Max 50MB maximum: 52428800 minimum: 1 type: integer required: - content_type - file_name - file_size type: object dispute.EvidenceUploadURLResponse: properties: content_type: type: string expires_at: type: string form_data: additionalProperties: type: string type: object max_size: type: integer method: type: string path: type: string upload_id: type: string url: type: string type: object dispute.MessageResponse: properties: attachments: items: type: string type: array content: type: string created_at: type: string dispute_id: type: string id: type: string is_internal: type: boolean read_at: type: string sender_id: type: string sender_type: type: string type: object dispute.MessageResponseSimple: properties: message: type: string type: object dispute.OrderSummaryDTO: properties: id: type: string order_number: type: string status: type: string type: object dispute.ProposeResolutionRequestDTO: properties: message: type: string proposal_type: type: string refund_amount: type: string required: - message - proposal_type type: object dispute.RefundResponse: properties: amount: type: string created_at: type: string currency: type: string dispute_id: type: string failure_reason: type: string gateway_refund_id: type: string id: type: string processed_at: type: string processed_by: type: string refund_type: type: string status: type: string updated_at: type: string type: object dispute.RespondToDisputeRequestDTO: properties: accept_fault: type: boolean response: minLength: 10 type: string required: - response type: object dispute.SellerAnalyticsResponse: properties: avg_resolution_time_hours: type: number dispute_rate: type: number lost_disputes: type: integer open_disputes: type: integer partial_disputes: type: integer resolved_disputes: type: integer response_rate: type: number total_disputes: type: integer total_refund_amount: type: string won_disputes: type: integer type: object dispute.SendMessageRequestDTO: properties: attachments: items: type: string type: array content: minLength: 1 type: string required: - content type: object dispute.StatisticsResponse: properties: avg_resolution_time_hours: type: number buyer_win_rate: type: number by_outcome: additionalProperties: format: int64 type: integer type: object by_priority: additionalProperties: format: int64 type: integer type: object by_reason: additionalProperties: format: int64 type: integer type: object closed_disputes: type: integer escalated_disputes: type: integer open_disputes: type: integer partial_resolution_rate: type: number resolved_disputes: type: integer seller_win_rate: type: number sla_breach_rate: type: number total_disputes: type: integer total_refund_amount: type: string under_review_disputes: type: integer type: object dispute.SubmitEvidenceRequestDTO: properties: description: type: string file_name: type: string file_size: type: integer file_type: type: string file_url: type: string mime_type: type: string required: - file_name - file_type - file_url type: object dispute.UserSummaryDTO: properties: email: type: string id: type: string name: type: string type: object featuring.BulkExtendFeaturesRequest: properties: async: description: 'Optional: force async processing' type: boolean feature_ids: items: type: string maxItems: 50 minItems: 1 type: array new_ends_at: type: string reason: maxLength: 500 minLength: 10 type: string required: - feature_ids - new_ends_at - reason type: object featuring.BulkFeatureStoresRequest: properties: async: description: 'Optional: force async processing' type: boolean campaign_id: maxLength: 100 type: string custom_description: maxLength: 500 type: string custom_label: maxLength: 50 type: string display_position: minimum: 1 type: integer ends_at: type: string priority: maximum: 10 minimum: 1 type: integer reason: maxLength: 500 minLength: 10 type: string starts_at: type: string store_ids: items: type: string maxItems: 50 minItems: 1 type: array required: - ends_at - priority - reason - starts_at - store_ids type: object featuring.FeaturingBulkActionJobResponse: properties: job_id: type: string message: type: string status: description: '"queued", "processing", "completed", "failed"' type: string type: object following.AdminStatisticsResponseDTO: properties: growth_rate: example: 12.5 type: number new_this_month: example: 4500 type: integer new_this_week: example: 1200 type: integer new_today: example: 150 type: integer total_follows: example: 50000 type: integer total_store_follows: example: 45000 type: integer total_user_follows: example: 5000 type: integer type: object following.AdminTopFollowedResponseDTO: properties: stores: items: $ref: '#/definitions/following.TopFollowedStoreDTO' type: array type: object following.AdminTrendsResponseDTO: properties: end_date: example: "2023-12-15" type: string granularity: example: day type: string start_date: example: "2023-11-15" type: string trends: items: $ref: '#/definitions/following.TrendPointDTO' type: array type: object following.DailyFollowerCountDTO: properties: date: example: "2023-12-15" type: string follower_count: example: 1234 type: integer lost_followers: example: 2 type: integer net_change: example: 8 type: integer new_followers: example: 10 type: integer type: object following.FavoriteProductInfoDTO: properties: favorited_at: example: "2023-12-10T10:00:00Z" type: string is_in_stock: example: true type: boolean notify_back_in_stock: example: true type: boolean notify_price_drop: example: true type: boolean original_price: example: 39.99 type: number price: example: 29.99 type: number product_id: example: 123e4567-e89b-12d3-a456-426614174001 type: string product_image_url: example: https://example.com/image.jpg type: string product_name: example: Awesome Product type: string product_slug: example: awesome-product type: string type: object following.FavoriteProductRequestDTO: properties: notify_back_in_stock: type: boolean notify_price_drop: type: boolean type: object following.FavoriteProductResponseDTO: properties: favorite_id: example: 123e4567-e89b-12d3-a456-426614174000 type: string favorited_at: example: "2023-12-15T10:00:00Z" type: string message: example: Product added to favorites type: string notify_back_in_stock: example: true type: boolean notify_price_drop: example: true type: boolean product_id: example: 123e4567-e89b-12d3-a456-426614174001 type: string success: example: true type: boolean type: object following.FavoriteServiceResponseDTO: properties: favorited_at: example: "2023-12-15T10:00:00Z" type: string message: example: Service added to favorites type: string service_id: example: 123e4567-e89b-12d3-a456-426614174000 type: string success: example: true type: boolean type: object following.FollowStatusResponseDTO: properties: followed_at: example: "2023-12-10T10:00:00Z" type: string is_following: example: true type: boolean type: object following.FollowStoreResponseDTO: properties: followed_at: example: "2023-12-15T10:00:00Z" type: string follower_count: example: 679 type: integer message: example: Successfully followed the store type: string store_id: example: 123e4567-e89b-12d3-a456-426614174000 type: string success: example: true type: boolean type: object following.FollowedStoreDTO: properties: followed_at: example: "2023-12-10T10:00:00Z" type: string is_verified: example: true type: boolean item_count: example: 45 type: integer rating: example: 4.5 type: number review_count: example: 123 type: integer store_avatar_url: example: https://example.com/avatar.jpg type: string store_id: example: 123e4567-e89b-12d3-a456-426614174000 type: string store_name: example: My Awesome Store type: string store_slug: example: my-awesome-store type: string type: object following.FollowerAnalyticsResponseDTO: properties: daily_growth: items: $ref: '#/definitions/following.DailyFollowerCountDTO' type: array growth_rate: example: 15.5 type: number new_followers_month: example: 320 type: integer new_followers_today: example: 12 type: integer new_followers_week: example: 85 type: integer total_followers: example: 1234 type: integer type: object following.FollowerDTO: properties: display_name: example: John Doe type: string email: example: john@example.com type: string first_name: example: John type: string followed_at: example: "2023-12-10T10:00:00Z" type: string last_name: example: Doe type: string user_id: example: 123e4567-e89b-12d3-a456-426614174001 type: string type: object following.ListFavoritesResponseDTO: properties: favorites: items: $ref: '#/definitions/following.FavoriteProductInfoDTO' type: array pagination: $ref: '#/definitions/pagination.Pagination' type: object following.ListFollowedStoresResponseDTO: properties: pagination: $ref: '#/definitions/pagination.Pagination' stores: items: $ref: '#/definitions/following.FollowedStoreDTO' type: array type: object following.ListFollowersResponseDTO: properties: followers: items: $ref: '#/definitions/following.FollowerDTO' type: array pagination: $ref: '#/definitions/pagination.Pagination' type: object following.RecentFollowerDTO: properties: display_name: example: John Doe type: string email: example: john@example.com type: string first_name: example: John type: string followed_at: example: "2023-12-15T10:00:00Z" type: string last_name: example: Doe type: string user_id: example: 123e4567-e89b-12d3-a456-426614174001 type: string type: object following.RecentFollowersResponseDTO: properties: followers: items: $ref: '#/definitions/following.RecentFollowerDTO' type: array type: object following.TopFollowedStoreDTO: properties: follower_count: example: 5000 type: integer is_verified: example: true type: boolean new_followers: example: 250 type: integer owner_id: example: 123e4567-e89b-12d3-a456-426614174002 type: string rank: example: 1 type: integer store_avatar_url: example: https://example.com/avatar.jpg type: string store_id: example: 123e4567-e89b-12d3-a456-426614174000 type: string store_name: example: Popular Store type: string store_slug: example: popular-store type: string type: object following.TrendPointDTO: properties: date: example: "2023-12-15" type: string net_change: example: 130 type: integer new_follows: example: 150 type: integer total_follows: example: 50000 type: integer unfollows: example: 20 type: integer type: object following.UnfavoriteProductResponseDTO: properties: message: example: Product removed from favorites type: string product_id: example: 123e4567-e89b-12d3-a456-426614174001 type: string success: example: true type: boolean type: object following.UnfavoriteServiceResponseDTO: properties: message: example: Service removed from favorites type: string service_id: example: 123e4567-e89b-12d3-a456-426614174000 type: string success: example: true type: boolean type: object following.UnfollowStoreResponseDTO: properties: follower_count: example: 678 type: integer message: example: Successfully unfollowed the store type: string store_id: example: 123e4567-e89b-12d3-a456-426614174000 type: string success: example: true type: boolean type: object github_com_shoppie_backend_internal_handlers_booking.ReplyToReviewRequest: properties: reply: maxLength: 1000 minLength: 1 type: string required: - reply type: object github_com_shoppie_backend_internal_handlers_boost.CreateBoostRequest: properties: callback_url: type: string package_id: type: string target_id: type: string target_type: enum: - product - service type: string required: - package_id - target_id - target_type type: object github_com_shoppie_backend_internal_handlers_boost.CreatePackageRequest: properties: currency: type: string description: maxLength: 500 type: string duration_days: maximum: 365 minimum: 1 type: integer name: maxLength: 100 minLength: 2 type: string price: type: number tier_weight: maximum: 100 minimum: 1 type: integer required: - duration_days - name - tier_weight type: object github_com_shoppie_backend_internal_handlers_boost.GrantBoostRequest: properties: override_eligibility: type: boolean package_id: type: string reason: maxLength: 500 minLength: 3 type: string store_id: type: string target_id: type: string target_type: enum: - product - service type: string required: - package_id - reason - store_id - target_id - target_type type: object github_com_shoppie_backend_internal_handlers_boost.RecordClickRequest: properties: target_id: type: string target_type: enum: - product - service type: string required: - target_id - target_type type: object github_com_shoppie_backend_internal_handlers_boost.UpdatePackageRequest: properties: currency: type: string description: maxLength: 500 type: string duration_days: maximum: 365 minimum: 1 type: integer name: maxLength: 100 minLength: 2 type: string price: type: number tier_weight: maximum: 100 minimum: 1 type: integer required: - duration_days - name - tier_weight type: object github_com_shoppie_backend_internal_handlers_boost.UpdateRankingConfigRequest: properties: cap_fraction: maximum: 1 minimum: 0 type: number min_rating: maximum: 5 minimum: 0 type: number min_slots: minimum: 0 type: integer required: - cap_fraction - min_rating - min_slots type: object github_com_shoppie_backend_internal_handlers_featuring.ActivateFeaturedConfigRequest: properties: reason: maxLength: 500 minLength: 10 type: string required: - reason type: object github_com_shoppie_backend_internal_handlers_featuring.ActivateTrendingConfigRequest: properties: reason: maxLength: 500 minLength: 10 type: string required: - reason type: object github_com_shoppie_backend_internal_handlers_featuring.CreateFeaturedConfigRequest: properties: description: maxLength: 500 type: string max_dispute_rate: maximum: 100 minimum: 0 type: number min_active_products: minimum: 0 type: integer min_follower_count: minimum: 0 type: integer min_fulfillment_rate: maximum: 100 minimum: 0 type: number min_monthly_revenue: minimum: 0 type: number min_order_count: minimum: 0 type: integer min_rating: description: Quality criteria maximum: 5 minimum: 0 type: number min_response_rate: maximum: 100 minimum: 0 type: number min_review_count: minimum: 0 type: integer min_store_age_days: minimum: 0 type: integer must_be_verified: type: boolean name: maxLength: 100 minLength: 2 type: string sort_by: enum: - rating - follower_count - order_count - revenue - created_at type: string sort_order: enum: - asc - desc type: string required: - max_dispute_rate - min_active_products - min_follower_count - min_fulfillment_rate - min_order_count - min_rating - min_response_rate - min_review_count - min_store_age_days - name - sort_by - sort_order type: object github_com_shoppie_backend_internal_handlers_featuring.CreateTrendingConfigRequest: properties: conversion_rate_weight: maximum: 100 minimum: 0 type: integer description: maxLength: 500 type: string engagement_boost_multiplier: description: Multipliers maximum: 2 minimum: 1 type: number follower_growth_weight: maximum: 100 minimum: 0 type: integer min_age_days: minimum: 0 type: integer min_follower_count: minimum: 0 type: integer min_order_count: minimum: 0 type: integer min_view_count: description: Minimum thresholds minimum: 0 type: integer name: maxLength: 100 minLength: 2 type: string new_store_boost_multiplier: maximum: 2 minimum: 1 type: number order_growth_weight: maximum: 100 minimum: 0 type: integer period_days: enum: - 7 - 30 type: integer revenue_growth_weight: maximum: 100 minimum: 0 type: integer view_growth_weight: description: Weights (must sum to 100) maximum: 100 minimum: 0 type: integer required: - conversion_rate_weight - engagement_boost_multiplier - follower_growth_weight - min_age_days - min_follower_count - min_order_count - min_view_count - name - new_store_boost_multiplier - order_growth_weight - period_days - revenue_growth_weight - view_growth_weight type: object github_com_shoppie_backend_internal_handlers_featuring.FeatureStoreManuallyRequest: properties: custom_description: maxLength: 500 type: string custom_label: maxLength: 50 type: string display_position: minimum: 1 type: integer ends_at: description: RFC3339 format type: string priority: maximum: 10 minimum: 1 type: integer reason: maxLength: 500 minLength: 10 type: string starts_at: description: RFC3339 format type: string store_id: type: string required: - ends_at - priority - reason - starts_at - store_id type: object github_com_shoppie_backend_internal_handlers_featuring.RemoveManualFeatureRequest: properties: reason: maxLength: 500 minLength: 10 type: string required: - reason type: object github_com_shoppie_backend_internal_handlers_product.BulkLinkImagesRequest: properties: image_ids: items: type: string minItems: 1 type: array primary_image_id: type: string required: - image_ids type: object github_com_shoppie_backend_internal_handlers_store.StoreActivityDTO: properties: action: type: string actor_id: type: string created_at: type: string details: type: string id: type: string ip_address: type: string store_id: type: string user_agent: type: string type: object github_com_shoppie_backend_internal_handlers_store.UpdateStoreResponse: properties: message: type: string store: $ref: '#/definitions/store.StoreDetailDTO' type: object image.ConfirmUploadRequestDTO: properties: content_type: description: ContentType is the MIME type of the file type: string entity_id: description: EntityID is the ID of the entity this image belongs to type: string entity_type: description: EntityType is the type of entity this image belongs to (e.g., "store", "product", "user") type: string file_name: description: FileName is the original file name type: string file_size: description: FileSize is the size of the file in bytes type: integer image_type: description: ImageType is the type of image (e.g., "avatar", "banner", "gallery") type: string key: description: Key is the S3/MinIO object key where the file was uploaded type: string required: - content_type - entity_id - entity_type - file_name - file_size - image_type - key type: object image.GenerateUploadURLRequestDTO: properties: content_type: type: string entity_id: type: string entity_type: enum: - store - category - product - user - service - campaign - chat - message - report - dispute type: string file_name: type: string file_size: description: Max 50MB for evidence maximum: 52428800 minimum: 1 type: integer image_type: type: string required: - content_type - entity_id - entity_type - file_name - file_size - image_type type: object image.GenerateUploadURLResponseDTO: properties: expires_at: type: string form_data: additionalProperties: type: string type: object path: type: string upload_id: type: string url: type: string type: object image.ImageStatusResponse: properties: created_at: type: string entity_id: type: string entity_type: type: string error_message: type: string id: type: string image_type: type: string is_processed: type: boolean processed_at: type: string scan_result: type: string status: type: string virus_clean: type: boolean virus_scanned: type: boolean type: object image.UploadResponse: properties: image_id: type: string message: type: string original_url: type: string status: $ref: '#/definitions/storage.UploadStatus' type: object notification.AnalyticsResponseDTO: properties: by_category: additionalProperties: format: int64 type: integer type: object by_priority: additionalProperties: format: int64 type: integer type: object by_type: additionalProperties: format: int64 type: integer type: object daily_stats: items: $ref: '#/definitions/notification.DailyStatDTO' type: array generated_at: type: string period: type: string read_rate: type: number top_notifications: items: $ref: '#/definitions/notification.TopNotificationDTO' type: array total_read: type: integer total_sent: type: integer total_unread: type: integer type: object notification.ArchiveNotificationResponseDTO: properties: success: type: boolean type: object notification.BroadcastHistoryItemResponseDTO: properties: admin_id: type: string channels: items: type: string type: array created_at: type: string failed_count: type: integer id: type: string message: type: string sent_count: type: integer success_rate: type: number title: type: string type: object notification.BroadcastHistoryResponseDTO: properties: broadcasts: items: $ref: '#/definitions/notification.BroadcastHistoryItemResponseDTO' type: array page: type: integer page_size: type: integer total: type: integer total_pages: type: integer type: object notification.BroadcastRequestDTO: properties: channels: items: type: string minItems: 1 type: array message: maxLength: 500 minLength: 1 type: string segment: $ref: '#/definitions/notification.SegmentFilterDTO' title: maxLength: 100 minLength: 1 type: string required: - channels - message - title type: object notification.BroadcastResponseDTO: properties: broadcast_id: type: string queued_count: type: integer type: object notification.CategoryPreferenceDTO: properties: email: type: boolean enabled: type: boolean in_app: type: boolean push: type: boolean type: object notification.CreateTemplateRequestDTO: properties: body_template: maxLength: 2000 minLength: 1 type: string email_enabled: type: boolean email_template_id: type: integer name: maxLength: 100 minLength: 1 type: string push_enabled: type: boolean title_template: maxLength: 200 minLength: 1 type: string type: type: string variables: items: $ref: '#/definitions/notification.TemplateVariableDTO' type: array required: - body_template - name - title_template - type type: object notification.DailyStatDTO: properties: date: type: string read: type: integer read_rate: type: number sent: type: integer type: object notification.DeleteNotificationResponseDTO: properties: success: type: boolean type: object notification.DeviceTokenResponseDTO: properties: registered: type: boolean token_id: type: string type: object notification.DraftBroadcastResponseDTO: properties: admin_id: type: string channels: items: type: string type: array created_at: type: string id: type: string message: type: string segment: $ref: '#/definitions/notification.SegmentFilterDTO' status: type: string title: type: string updated_at: type: string type: object notification.ListDraftBroadcastsResponseDTO: properties: drafts: items: $ref: '#/definitions/notification.DraftBroadcastResponseDTO' type: array page: type: integer page_size: type: integer total: type: integer total_pages: type: integer type: object notification.ListTemplatesResponseDTO: properties: page: type: integer page_size: type: integer templates: items: $ref: '#/definitions/notification.TemplateResponseDTO' type: array total: type: integer total_pages: type: integer type: object notification.MarkReadResponseDTO: properties: success: type: boolean type: object notification.NotificationDetailDTO: properties: action_url: type: string archived: type: boolean archived_at: type: string category: type: string created_at: type: string data: additionalProperties: true description: action payload type: object id: type: string image_url: type: string message: description: full message type: string preview: description: 120-char truncation (for consistency) type: string priority: type: string read: type: boolean read_at: type: string snoozed_until: type: string title: type: string type: type: string type: object notification.NotificationStatsResponseDTO: properties: total_broadcasts: type: integer total_devices: type: integer total_notifications: type: integer total_unread: type: integer type: object notification.PreferencesResponseDTO: properties: categories: additionalProperties: $ref: '#/definitions/notification.CategoryPreferenceDTO' type: object quiet_hours_end: type: string quiet_hours_start: type: string timezone: type: string type: object notification.RegisterDeviceRequest: properties: app_version: maxLength: 50 type: string device_model: maxLength: 100 type: string platform: enum: - ios - android type: string token: minLength: 1 type: string required: - platform - token type: object notification.SaveDraftBroadcastRequestDTO: properties: channels: items: type: string type: array message: maxLength: 500 minLength: 1 type: string segment: $ref: '#/definitions/notification.SegmentFilterDTO' title: maxLength: 100 minLength: 1 type: string required: - message - title type: object notification.SaveDraftBroadcastResponseDTO: properties: broadcast_id: type: string status: type: string type: object notification.ScheduleBroadcastRequestDTO: properties: channels: items: type: string minItems: 1 type: array message: maxLength: 500 minLength: 1 type: string scheduled_for: description: RFC3339 format type: string segment: $ref: '#/definitions/notification.SegmentFilterDTO' title: maxLength: 100 minLength: 1 type: string required: - channels - message - scheduled_for - title type: object notification.ScheduleBroadcastResponseDTO: properties: broadcast_id: type: string scheduled_for: type: string status: type: string type: object notification.SegmentFilterDTO: properties: roles: items: type: string type: array user_ids: items: type: string type: array verified: type: boolean type: object notification.SnoozeNotificationRequestDTO: properties: snoozed_until: description: RFC3339 format type: string required: - snoozed_until type: object notification.SnoozeNotificationResponseDTO: properties: snoozed_until: type: string success: type: boolean type: object notification.TemplateResponseDTO: properties: body_template: type: string created_at: type: string email_enabled: type: boolean email_template_id: type: integer id: type: string is_active: type: boolean name: type: string push_enabled: type: boolean title_template: type: string type: type: string updated_at: type: string variables: items: $ref: '#/definitions/notification.TemplateVariableDTO' type: array type: object notification.TemplateVariableDTO: properties: default_val: maxLength: 200 type: string description: maxLength: 200 type: string example: maxLength: 100 type: string name: maxLength: 50 minLength: 1 type: string required: type: boolean required: - name type: object notification.TopNotificationDTO: properties: count: type: integer read_rate: type: number type: type: string type: object notification.UnreadCountResponseDTO: properties: count: type: integer type: object notification.UpdatePreferencesRequestDTO: properties: categories: additionalProperties: $ref: '#/definitions/notification.CategoryPreferenceDTO' type: object quiet_hours_end: type: string quiet_hours_start: type: string timezone: maxLength: 50 type: string type: object notification.UpdateTemplateRequestDTO: properties: body_template: maxLength: 2000 minLength: 1 type: string email_enabled: type: boolean email_template_id: type: integer is_active: type: boolean name: maxLength: 100 minLength: 1 type: string push_enabled: type: boolean title_template: maxLength: 200 minLength: 1 type: string variables: items: $ref: '#/definitions/notification.TemplateVariableDTO' type: array type: object pagination.Pagination: properties: current_page: type: integer has_next: type: boolean has_prev: type: boolean page_size: type: integer skip: type: integer total: type: integer total_pages: type: integer type: object pagination.Response: properties: data: {} pagination: $ref: '#/definitions/pagination.Pagination' type: object product.AddOptionValueRequestDTO: properties: position: type: integer value: maxLength: 100 minLength: 1 type: string required: - value type: object product.AdjustInventoryRequestDTO: properties: adjustment: type: integer notes: maxLength: 500 type: string reason: enum: - sale - return - restock - correction - damaged - expired type: string reference_id: type: string variant_id: type: string required: - adjustment - reason type: object product.AdjustInventoryResponseDTO: properties: adjustment: type: integer came_back_in_stock: type: boolean new_quantity: type: integer previous_quantity: type: integer product_id: type: string went_out_of_stock: type: boolean type: object product.AdminBulkDeleteRequestDTO: properties: hard_delete: type: boolean product_ids: items: type: string maxItems: 100 minItems: 1 type: array reason: maxLength: 500 type: string required: - product_ids type: object product.AdminBulkUpdateFieldsDTO: properties: category_id: type: string is_available: type: boolean is_featured: type: boolean status: type: string type: object product.AdminBulkUpdateRequestDTO: properties: product_ids: items: type: string maxItems: 100 minItems: 1 type: array updates: $ref: '#/definitions/product.AdminBulkUpdateFieldsDTO' required: - product_ids - updates type: object product.AdminProductResponse: properties: category: allOf: - $ref: '#/definitions/product.CategoryRefDTO' description: |- Category is the leaf the product is filed under -- the one thing a vendor picked. category_ancestry: description: |- CategoryAncestry is that leaf together with every category above it, root first, which is breadcrumb order. It is derived from the leaf's path, not stored: an iPhone filed under "Smartphones & Handsets" reports "Tech, Hardware & Gadgets" here without that ever having been written down. items: $ref: '#/definitions/product.CategoryRefDTO' type: array compare_at_price: type: number condition: type: string cost_price: type: number created_at: type: string deleted_at: type: string description: type: string dimensions: type: string id: type: string images: items: $ref: '#/definitions/product.ProductImageDTO' type: array interested_count: type: integer is_available: type: boolean is_featured: type: boolean likes: type: integer option_types: items: $ref: '#/definitions/product.OptionTypeDTO' type: array price: type: number published_at: type: string quantity: type: integer rating: type: number review_count: type: integer short_description: type: string sku: type: string slug: type: string sold_count: type: integer specifications: items: $ref: '#/definitions/product.SpecificationDTO' type: array status: type: string store_id: type: string store_preview: $ref: '#/definitions/product.StorePreviewDTO' suspended_at: type: string suspended_by: type: string suspension_reason: type: string title: type: string updated_at: type: string variants: items: $ref: '#/definitions/product.VariantDTO' type: array view_count: type: integer weight: type: number type: object product.AltTextUpdate: properties: alt_text: type: string image_id: type: string type: object product.BulkOperationResponse: properties: failed_ids: items: type: string type: array failure_count: type: integer message: type: string success_count: type: integer total_count: type: integer type: object product.BulkUpdateImageAltTextRequest: properties: updates: items: $ref: '#/definitions/product.AltTextUpdate' minItems: 1 type: array required: - updates type: object product.CategoryRefDTO: properties: id: type: string name: type: string slug: type: string type: object product.CategoryStatDTO: properties: category_id: type: string category_name: type: string product_count: type: integer type: object product.CreateOptionTypeRequestDTO: properties: attribute_id: description: |- AttributeID names the category attribute this axis realises, sent by a form that offered the category's own attributes. Omitted when the vendor named the axis themselves. type: string name: maxLength: 50 minLength: 1 type: string position: type: integer required: - name type: object product.CreateProductRequestDTO: properties: category_id: type: string compare_at_price: type: number condition: enum: - new - like_new - used - refurbished - for_parts type: string cost_price: type: number description: maxLength: 2000 type: string dimensions: maxLength: 50 type: string image_ids: description: |- ImageIDs are the UUIDs of pre-uploaded images (from presigned URL endpoint) Images are linked to the product in order - first image becomes primary items: type: string maxItems: 10 type: array low_stock_threshold: minimum: 0 type: integer price: type: number quantity: minimum: 0 type: integer short_description: maxLength: 300 type: string sku: maxLength: 100 type: string title: maxLength: 200 minLength: 3 type: string weight: type: number required: - category_id - price - title type: object product.CreateVariantRequestDTO: properties: compare_at_price: type: number image_id: type: string is_available: type: boolean option_value_id_1: type: string option_value_id_2: type: string option_value_id_3: type: string position: type: integer price: type: number quantity: type: integer sku: type: string title: type: string required: - price type: object product.FeatureProductRequestDTO: properties: featured: type: boolean type: object product.GetUploadURLRequestDTO: properties: content_type: type: string file_name: type: string file_size: description: Max 5MB for product images maximum: 5242880 minimum: 1 type: integer image_type: type: string required: - content_type - file_name - file_size - image_type type: object product.GetUploadURLResponseDTO: properties: expires_at: type: string form_data: additionalProperties: type: string type: object path: type: string upload_id: type: string url: type: string type: object product.ImageStatusResponse: properties: error: type: string image_id: type: string progress: type: integer status: type: string step: type: string urls: $ref: '#/definitions/storage.ProcessedURLs' type: object product.ListOptionTypesResponseDTO: properties: option_types: items: $ref: '#/definitions/product.OptionTypeDTO' type: array product_id: type: string type: object product.ListSpecificationsResponseDTO: properties: product_id: type: string specifications: items: $ref: '#/definitions/product.SpecificationDTO' type: array type: object product.ListVariantsResponseDTO: properties: product_id: type: string variants: items: $ref: '#/definitions/product.VariantDTO' type: array type: object product.OptionDTO: properties: name: type: string value: type: string type: object product.OptionTypeDTO: properties: attribute_id: description: |- AttributeID is the category attribute this axis realises, absent when the vendor named it themselves. The editor needs it to reopen the listing on the same attribute rather than treating a template axis as free text. type: string id: type: string name: type: string position: type: integer values: items: $ref: '#/definitions/product.OptionValueDTO' type: array type: object product.OptionValueDTO: properties: id: type: string position: type: integer value: type: string type: object product.ProductAnalyticsResponse: properties: end_date: type: string generated_at: type: string period: type: string sales_trend: items: $ref: '#/definitions/product.TimeSeriesDataPointDTO' type: array start_date: type: string top_products: items: $ref: '#/definitions/product.ProductResponse' type: array views_trend: items: $ref: '#/definitions/product.TimeSeriesDataPointDTO' type: array type: object product.ProductImageDTO: properties: alt_text: type: string display_order: type: integer id: type: string is_primary: type: boolean large_url: type: string medium_url: type: string thumbnail_url: type: string url: type: string type: object product.ProductPublicDTO: properties: compare_at_price: type: number condition: type: string created_at: type: string description: type: string id: type: string is_featured: type: boolean is_liked: description: null if user not authenticated, true/false if authenticated type: boolean price: type: number primary_image: $ref: '#/definitions/product.ProductImageDTO' rating: type: number review_count: type: integer slug: type: string sponsored: description: |- Sponsored marks a product surfaced via a paid boost in this listing, so the frontend can render a "Sponsored" label. type: boolean store_id: description: |- StoreID is the store selling the product. Cards need it to tell a vendor their own listing is not buyable, matching the backend's own-product guard. type: string title: type: string type: object product.ProductResponse: properties: category: allOf: - $ref: '#/definitions/product.CategoryRefDTO' description: |- Category is the leaf the product is filed under -- the one thing a vendor picked. category_ancestry: description: |- CategoryAncestry is that leaf together with every category above it, root first, which is breadcrumb order. It is derived from the leaf's path, not stored: an iPhone filed under "Smartphones & Handsets" reports "Tech, Hardware & Gadgets" here without that ever having been written down. items: $ref: '#/definitions/product.CategoryRefDTO' type: array compare_at_price: type: number condition: type: string cost_price: type: number created_at: type: string description: type: string dimensions: type: string id: type: string images: items: $ref: '#/definitions/product.ProductImageDTO' type: array interested_count: type: integer is_available: type: boolean is_featured: type: boolean likes: type: integer option_types: items: $ref: '#/definitions/product.OptionTypeDTO' type: array price: type: number published_at: type: string quantity: type: integer rating: type: number review_count: type: integer short_description: type: string sku: type: string slug: type: string sold_count: type: integer specifications: items: $ref: '#/definitions/product.SpecificationDTO' type: array status: type: string store_id: type: string store_preview: $ref: '#/definitions/product.StorePreviewDTO' title: type: string updated_at: type: string variants: items: $ref: '#/definitions/product.VariantDTO' type: array view_count: type: integer weight: type: number type: object product.ProductStatisticsResponse: properties: active_products: type: integer archived_products: type: integer average_price: type: number by_store: items: $ref: '#/definitions/product.StoreStatDTO' type: array draft_products: type: integer featured_count: type: integer generated_at: type: string low_stock_count: type: integer out_of_stock_count: type: integer suspended_products: type: integer top_categories: items: $ref: '#/definitions/product.CategoryStatDTO' type: array total_products: type: integer total_value: type: number type: object product.ReorderProductImagesRequest: properties: image_ids: description: |- ImageIDs in desired display order — the FIRST entry becomes the primary image (display_order = 0) shown in product listings and search results. All image IDs belonging to this product must be included. To change the primary image: put the desired image ID first in the list. items: type: string minItems: 1 type: array required: - image_ids type: object product.ReorderProductItemDTO: properties: display_order: minimum: 0 type: integer product_id: type: string required: - product_id type: object product.ReorderProductsRequestDTO: properties: orders: items: $ref: '#/definitions/product.ReorderProductItemDTO' minItems: 1 type: array required: - orders type: object product.SetSpecificationsRequestDTO: properties: specifications: items: $ref: '#/definitions/product.SpecificationInputDTO' maxItems: 50 type: array type: object product.SetSpecificationsResponseDTO: properties: product_id: type: string specifications: items: $ref: '#/definitions/product.SpecificationDTO' type: array type: object product.SpecificationDTO: properties: attribute_id: description: |- AttributeID is the category attribute this spec answers, absent when the vendor wrote it themselves. The editor needs it to reopen the listing on the same attribute rather than treating a template spec as free text. type: string id: type: string name: type: string position: type: integer unit: type: string value: type: string type: object product.SpecificationInputDTO: properties: attribute_id: description: |- AttributeID names the category attribute this spec answers, sent by a form that offered the category's own specs. Omitted when the vendor wrote a spec of their own. type: string name: maxLength: 100 minLength: 1 type: string position: type: integer unit: type: string value: maxLength: 500 minLength: 1 type: string required: - name - value type: object product.StorePreviewDTO: properties: avatar_url: type: string id: type: string name: type: string slug: type: string type: object product.StoreStatDTO: properties: product_count: type: integer store_id: type: string store_name: type: string type: object product.SuspendProductRequestDTO: properties: reason: maxLength: 500 minLength: 10 type: string required: - reason type: object product.TimeSeriesDataPointDTO: properties: date: type: string value: type: integer type: object product.UpdateImageAltTextRequest: properties: alt_text: type: string type: object product.UpdateOptionTypeRequestDTO: properties: name: maxLength: 50 minLength: 1 type: string position: type: integer required: - name type: object product.UpdateOptionValueRequestDTO: properties: position: type: integer value: maxLength: 100 minLength: 1 type: string required: - value type: object product.UpdateProductRequestDTO: properties: category_id: type: string compare_at_price: type: number condition: enum: - new - like_new - used - refurbished - for_parts type: string cost_price: type: number description: maxLength: 2000 type: string dimensions: maxLength: 50 type: string is_available: type: boolean low_stock_threshold: minimum: 0 type: integer price: type: number quantity: minimum: 0 type: integer short_description: maxLength: 300 type: string sku: maxLength: 100 type: string title: maxLength: 200 minLength: 3 type: string weight: type: number type: object product.UpdateVariantRequestDTO: properties: compare_at_price: type: number image_id: type: string is_available: type: boolean option_value_id_1: type: string option_value_id_2: type: string option_value_id_3: type: string position: type: integer price: type: number quantity: type: integer sku: type: string title: type: string type: object product.VariantDTO: properties: compare_at_price: type: number id: type: string image_id: type: string is_available: type: boolean options: description: resolved name+value pairs items: $ref: '#/definitions/product.OptionDTO' type: array position: type: integer price: type: number quantity: type: integer sku: type: string title: type: string type: object promotion.AdminApprovePromotionRequestDTO: properties: note: maxLength: 500 type: string type: object promotion.AdminBulkActionRequestDTO: properties: action: enum: - approve - reject - disable - pause - resume type: string note: maxLength: 500 type: string promotion_ids: items: type: string maxItems: 100 minItems: 1 type: array reason: maxLength: 500 type: string required: - action - promotion_ids type: object promotion.AdminBulkActionResponseDTO: properties: results: items: $ref: '#/definitions/promotion.BulkActionResultDTO' type: array total_failed: type: integer total_requested: type: integer total_successful: type: integer type: object promotion.AdminCreatePlatformPromotionRequestDTO: properties: applicable_to: enum: - all_products - specific_products - specific_categories type: string buy_quantity: type: integer category_ids: items: type: string type: array code: maxLength: 50 minLength: 3 type: string description: maxLength: 1000 type: string discount_type: enum: - percentage - fixed_amount - buy_x_get_y - free_shipping type: string discount_value: type: number ends_at: type: string get_quantity: type: integer is_featured: type: boolean max_discount_amount: type: number min_order_amount: type: number priority: maximum: 10 minimum: 1 type: integer product_ids: items: type: string type: array starts_at: type: string title: maxLength: 200 minLength: 3 type: string usage_limit: type: integer usage_limit_per_user: type: integer required: - applicable_to - discount_type - discount_value - ends_at - starts_at - title type: object promotion.AdminDisablePromotionRequestDTO: properties: reason: maxLength: 500 minLength: 10 type: string required: - reason type: object promotion.AdminPausePromotionRequestDTO: properties: reason: maxLength: 500 type: string type: object promotion.AdminRejectPromotionRequestDTO: properties: reason: maxLength: 500 minLength: 10 type: string required: - reason type: object promotion.AdminResumePromotionRequestDTO: properties: note: maxLength: 500 type: string type: object promotion.ApplyPromoCodeRequestDTO: properties: category_ids: items: type: string type: array code: maxLength: 50 minLength: 1 type: string order_amount: type: number order_id: type: string product_ids: items: type: string type: array required: - code - order_amount - order_id type: object promotion.ApplyPromoCodeResponseDTO: properties: applied: type: boolean discount_amount: type: string discount_description: type: string error: type: string error_code: type: string promotion: $ref: '#/definitions/promotion.PublicPromotionDTO' type: object promotion.BulkActionResultDTO: properties: error: type: string promotion_id: type: string success: type: boolean type: object promotion.CreatePromotionRequestDTO: properties: applicable_to: enum: - all_products - specific_products - specific_categories type: string buy_quantity: type: integer category_ids: items: type: string type: array code: maxLength: 50 minLength: 3 type: string description: maxLength: 1000 type: string discount_type: enum: - percentage - fixed_amount - buy_x_get_y - free_shipping type: string discount_value: type: number ends_at: type: string get_quantity: type: integer max_discount_amount: type: number min_order_amount: type: number product_ids: items: type: string type: array requires_approval: type: boolean starts_at: type: string submit_for_approval: type: boolean title: maxLength: 200 minLength: 3 type: string usage_limit: type: integer usage_limit_per_user: type: integer required: - applicable_to - discount_type - discount_value - ends_at - starts_at - title type: object promotion.DailyUsageDTO: properties: date: type: string revenue: type: string usage_count: type: integer type: object promotion.ListPromotionsResponseDTO: properties: pagination: $ref: '#/definitions/pagination.Pagination' promotions: items: $ref: '#/definitions/promotion.PromotionDTO' type: array type: object promotion.ListPublicPromotionsResponseDTO: properties: pagination: $ref: '#/definitions/pagination.Pagination' promotions: items: $ref: '#/definitions/promotion.PublicPromotionDTO' type: array type: object promotion.PromotionAnalyticsDTO: properties: average_order_value: type: string conversion_rate: type: string daily_usage: items: $ref: '#/definitions/promotion.DailyUsageDTO' type: array promotion_id: type: string title: type: string total_discount_given: type: string total_revenue: type: string total_uses: type: integer unique_users: type: integer type: object promotion.PromotionDTO: properties: applicable_to: type: string approved_at: type: string approved_by: type: string buy_quantity: type: integer category_ids: items: type: string type: array code: type: string created_at: type: string created_by: type: string description: type: string discount_description: type: string discount_type: type: string discount_value: type: string ends_at: type: string fraud_reason: type: string get_quantity: type: integer id: type: string is_active: type: boolean is_featured: type: boolean is_platform_wide: type: boolean max_discount_amount: type: string min_order_amount: type: string priority: type: integer product_ids: items: type: string type: array rejection_reason: type: string requires_approval: type: boolean starts_at: type: string status: type: string store_id: type: string title: type: string total_discount_given: type: string total_revenue: type: string unique_users: type: integer updated_at: type: string usage_count: type: integer usage_limit: type: integer usage_limit_per_user: type: integer type: object promotion.PromotionStatisticsDTO: properties: active_promotions: type: integer average_discount_value: type: string pending_approval: type: integer promotions_by_status: additionalProperties: format: int64 type: integer type: object promotions_by_type: additionalProperties: format: int64 type: integer type: object top_discount_type: type: string total_discount_given: type: string total_promotions: type: integer total_revenue: type: string total_usage: type: integer type: object promotion.PublicPromotionDTO: properties: code: type: string description: type: string discount_description: type: string discount_type: type: string ends_at: type: string id: type: string is_featured: type: boolean min_order_amount: type: string starts_at: type: string store_id: type: string title: type: string type: object promotion.TimelineEventDTO: properties: actor_id: type: string actor_type: type: string created_at: type: string description: type: string event_type: type: string id: type: string metadata: additionalProperties: true type: object promotion_id: type: string type: object promotion.TimelineResponseDTO: properties: events: items: $ref: '#/definitions/promotion.TimelineEventDTO' type: array pagination: $ref: '#/definitions/pagination.Pagination' type: object promotion.TopPromotionDTO: properties: discount_type: type: string id: type: string status: type: string store_id: type: string title: type: string total_discount_given: type: string total_revenue: type: string unique_users: type: integer usage_count: type: integer type: object promotion.TopPromotionsResponseDTO: properties: period: type: string promotions: items: $ref: '#/definitions/promotion.TopPromotionDTO' type: array type: object promotion.UpdatePromotionRequestDTO: properties: applicable_to: enum: - all_products - specific_products - specific_categories type: string category_ids: items: type: string type: array code: maxLength: 50 minLength: 3 type: string description: maxLength: 1000 type: string discount_value: type: number ends_at: type: string max_discount_amount: type: number min_order_amount: type: number product_ids: items: type: string type: array starts_at: type: string title: maxLength: 200 minLength: 3 type: string usage_limit: type: integer usage_limit_per_user: type: integer type: object promotion.ValidatePromoCodeRequestDTO: properties: category_ids: items: type: string type: array code: maxLength: 50 minLength: 1 type: string order_amount: type: number product_ids: items: type: string type: array required: - code - order_amount type: object promotion.ValidatePromoCodeResponseDTO: properties: discount_amount: type: string discount_description: type: string error: type: string error_code: type: string is_valid: type: boolean promotion: $ref: '#/definitions/promotion.PublicPromotionDTO' type: object report.ActivityResponse: properties: action: type: string created_at: type: string description: type: string id: type: string metadata: additionalProperties: true type: object new_value: type: string old_value: type: string performed_by: type: string report_id: type: string type: object report.AddCommentRequestDTO: properties: content: minLength: 1 type: string is_internal: description: Admin only type: boolean required: - content type: object report.AddEvidenceRequestDTO: properties: description: type: string evidence_type: type: string file_name: type: string file_size: type: integer file_url: type: string mime_type: type: string required: - evidence_type - file_name - file_url type: object report.AdminAssignRequest: properties: assign_to_id: type: string required: - assign_to_id type: object report.AdminBulkAssignRequestDTO: properties: assign_to_id: type: string report_ids: items: type: string minItems: 1 type: array required: - assign_to_id - report_ids type: object report.AdminEscalateRequest: properties: reason: type: string required: - reason type: object report.AdminMarkDuplicateRequestDTO: properties: parent_report_id: type: string required: - parent_report_id type: object report.AdminRejectRequest: properties: reason: type: string required: - reason type: object report.AdminReportDetailResponse: properties: activities: items: $ref: '#/definitions/report.ActivityResponse' type: array assigned_at: type: string assigned_to: type: string category: type: string comments: items: $ref: '#/definitions/report.CommentResponse' type: array created_at: type: string description: type: string duplicate_count: type: integer duplicate_reports: items: $ref: '#/definitions/report.ReportResponse' type: array evidence: items: $ref: '#/definitions/report.EvidenceResponse' type: array id: type: string is_duplicate: type: boolean parent_report: $ref: '#/definitions/report.ReportResponse' parent_report_id: type: string priority: type: string report_number: type: string report_type: type: string reporter_id: type: string resolution_action: type: string resolution_note: type: string resolved_at: type: string resolved_by: type: string status: type: string target_id: type: string target_owner_id: type: string title: type: string updated_at: type: string type: object report.AdminResolveRequest: properties: resolution_action: type: string resolution_note: type: string required: - resolution_action - resolution_note type: object report.AdminUpdatePriorityRequestDTO: properties: priority: type: string reason: type: string required: - priority type: object report.AppealEvidenceDTO: properties: description: type: string evidence_type: type: string file_name: type: string file_size: type: integer file_url: type: string mime_type: type: string type: object report.AppealReportRequestDTO: properties: appeal_reason: minLength: 20 type: string evidence: items: $ref: '#/definitions/report.AppealEvidenceDTO' type: array required: - appeal_reason type: object report.BulkAssignResponse: properties: errors: items: type: string type: array failed_ids: items: type: string type: array success_count: type: integer type: object report.CommentResponse: properties: author_id: type: string content: type: string created_at: type: string id: type: string is_internal: type: boolean report_id: type: string updated_at: type: string type: object report.CreateReportRequestDTO: properties: category: type: string description: minLength: 20 type: string report_type: description: product, service, review, user, store type: string target_id: type: string title: maxLength: 200 minLength: 5 type: string required: - category - description - report_type - target_id - title type: object report.EvidenceResponse: properties: created_at: type: string description: type: string file_name: type: string file_size: type: integer file_type: type: string file_url: type: string id: type: string mime_type: type: string report_id: type: string uploaded_by: type: string type: object report.EvidenceUploadURLRequest: properties: content_type: type: string file_name: type: string file_size: description: Max 50MB maximum: 52428800 minimum: 1 type: integer required: - content_type - file_name - file_size type: object report.EvidenceUploadURLResponse: properties: content_type: type: string expires_at: type: string form_data: additionalProperties: type: string type: object max_size: type: integer method: type: string path: type: string upload_id: type: string url: type: string type: object report.MessageResponse: properties: message: type: string type: object report.ReportResponse: properties: assigned_at: type: string assigned_to: type: string category: type: string comments: items: $ref: '#/definitions/report.CommentResponse' type: array created_at: type: string description: type: string duplicate_count: type: integer evidence: items: $ref: '#/definitions/report.EvidenceResponse' type: array id: type: string is_duplicate: type: boolean parent_report_id: type: string priority: type: string report_number: type: string report_type: type: string reporter_id: type: string resolution_action: type: string resolution_note: type: string resolved_at: type: string resolved_by: type: string status: type: string target_id: type: string target_owner_id: type: string title: type: string updated_at: type: string type: object report.StatisticsResponse: properties: by_category: additionalProperties: format: int64 type: integer type: object by_priority: additionalProperties: format: int64 type: integer type: object by_resolution_action: additionalProperties: format: int64 type: integer type: object by_type: additionalProperties: format: int64 type: integer type: object duplicate_reports: type: integer escalated_reports: type: integer investigating_reports: type: integer pending_reports: type: integer rejected_reports: type: integer resolved_reports: type: integer total_reports: type: integer under_review_reports: type: integer type: object report.StoreRespondRequest: properties: action_taken: type: string response: minLength: 10 type: string required: - response type: object response.ErrorInfo: properties: code: type: string details: additionalProperties: type: string type: object field: type: string message: type: string type: object response.Meta: properties: page: type: integer per_page: type: integer total: type: integer total_pages: type: integer type: object response.StandardResponse: properties: data: {} error: $ref: '#/definitions/response.ErrorInfo' meta: $ref: '#/definitions/response.Meta' request_id: type: string success: type: boolean timestamp: type: string type: object review.AdminFlagDTO: properties: reason: maxLength: 500 minLength: 10 type: string required: - reason type: object review.AdminModerationDTO: properties: notes: maxLength: 500 type: string reason: maxLength: 500 type: string type: object review.AdminRejectDTO: properties: reason: maxLength: 500 minLength: 10 type: string required: - reason type: object review.BulkDeleteDTO: properties: reason: maxLength: 500 minLength: 10 type: string review_ids: items: type: string maxItems: 100 minItems: 1 type: array required: - reason - review_ids type: object review.BulkRejectDTO: properties: reason: maxLength: 500 minLength: 10 type: string review_ids: items: type: string maxItems: 100 minItems: 1 type: array required: - reason - review_ids type: object review.BulkReviewIDsDTO: properties: review_ids: items: type: string maxItems: 100 minItems: 1 type: array required: - review_ids type: object review.RejectReplyDTO: properties: reason: maxLength: 500 minLength: 10 type: string required: - reason type: object review.SubmitReviewDTO: properties: order_id: type: string photos: items: type: string maxItems: 5 type: array product_id: type: string rating: maximum: 5 minimum: 1 type: integer text: maxLength: 2000 minLength: 10 type: string vendor_id: type: string required: - order_id - product_id - rating - text - vendor_id type: object review.UpdateReviewDTO: properties: photos: items: type: string maxItems: 5 type: array rating: maximum: 5 minimum: 1 type: integer text: maxLength: 2000 minLength: 10 type: string required: - rating - text type: object review.VendorReplyDTO: properties: reply: maxLength: 1000 minLength: 10 type: string required: - reply type: object service.AdminAuditProviderRequestDTO: properties: provider_id: type: string required: - provider_id type: object service.AdminEditServiceRequest: properties: base_price: type: number booking_mode: type: string category_id: type: string cover_url: type: string description: type: string duration_minutes: type: integer location_type: type: string reason: maxLength: 500 minLength: 10 type: string title: type: string required: - reason type: object service.AdminRelistRequestDTO: properties: reason: maxLength: 500 minLength: 10 type: string required: - reason type: object service.BulkDeleteRequestDTO: properties: service_ids: items: type: string maxItems: 100 minItems: 1 type: array required: - service_ids type: object service.BulkUpdateStatusRequestDTO: properties: is_active: type: boolean service_ids: items: type: string maxItems: 100 minItems: 1 type: array required: - service_ids type: object service.CreateServiceRequest: properties: base_price: description: BasePrice is the flat price (fixed) or the per-unit rate (unit). type: number category_id: type: string cover_url: type: string description: maxLength: 2000 minLength: 10 type: string duration_minutes: maximum: 480 minimum: 15 type: integer location_type: enum: - in_person - online - hybrid type: string max_quantity: type: number min_quantity: type: number portfolio_urls: items: type: string maxItems: 5 type: array price_unit: description: |- PriceUnit names what the rate is charged per; MinQuantity/MaxQuantity bound how many units may be bought. Unit pricing only. maxLength: 30 type: string pricing_model: description: |- PricingModel selects how the service is sold; defaults to fixed when omitted. Which of the fields below are required follows from it, and is enforced by the domain rather than restated here. enum: - fixed - unit - tiered - menu - quote - ticketed type: string requires_slot: description: |- RequiresSlot declares that the service takes a scheduled time. It is the only thing that makes DurationMinutes required — no pricing model does. type: boolean store_id: type: string title: maxLength: 200 minLength: 3 type: string required: - category_id - description - location_type - store_id - title type: object service.GetServiceUploadURLRequest: properties: content_type: type: string file_name: type: string file_size: description: max 5MB maximum: 5242880 minimum: 1 type: integer image_type: enum: - cover - gallery - portfolio - primary type: string required: - content_type - file_name - file_size - image_type type: object service.SuspendRequestDTO: properties: reason: maxLength: 500 minLength: 10 type: string required: - reason type: object service.UpdateServiceRequest: properties: base_price: minimum: 0 type: number booking_mode: description: |- BookingMode controls how new bookings are confirmed: "instant" = auto-confirmed immediately (default) "manual" = vendor must confirm within 24h or booking auto-cancels enum: - instant - manual type: string category_id: type: string cover_url: type: string description: maxLength: 2000 minLength: 10 type: string duration_minutes: maximum: 480 minimum: 15 type: integer is_active: type: boolean location_type: enum: - in_person - online - hybrid type: string max_quantity: type: number min_quantity: type: number portfolio_urls: items: type: string maxItems: 5 type: array price_unit: maxLength: 30 type: string pricing_model: description: |- PricingModel switches how the service is sold. The switch is validated against the fields it leaves behind: a service moved to tiered may not keep a base price, and one moved to unit must gain a unit. enum: - fixed - unit - tiered - menu - quote - ticketed type: string requires_slot: description: |- RequiresSlot toggles whether the service takes a scheduled time, and with it whether DurationMinutes is required. type: boolean title: maxLength: 200 minLength: 3 type: string type: object storage.ProcessedURLs: properties: large: description: Large size (1200x1200) type: string medium: description: Medium size (800x800) type: string original: description: Original/optimized type: string thumbnail: description: Small preview (200x200) type: string type: object storage.UploadStatus: enum: - pending - uploading - uploaded - processing - ready - failed - quarantined - expired - uploading - processing - ready - failed type: string x-enum-varnames: - UploadStatusPending - UploadStatusUploading - UploadStatusUploaded - UploadStatusProcessing - UploadStatusReady - UploadStatusFailed - UploadStatusQuarantined - UploadStatusExpired - ImageStatusUploading - ImageStatusProcessing - ImageStatusReady - ImageStatusFailed store.AdminSuspendStoreRequestDTO: properties: admin_note: example: Multiple user reports received maxLength: 1000 type: string notify_owner: example: true type: boolean reason: example: Violation of community guidelines maxLength: 500 minLength: 10 type: string required: - reason type: object store.AdminUnverifyStoreRequestDTO: properties: admin_note: example: Business license expired maxLength: 1000 type: string reason: example: No longer meets verification requirements maxLength: 500 minLength: 10 type: string required: - reason type: object store.AdminUpdateStoreRequestDTO: properties: address: example: 123 Main St, City, Country type: string avatar_url: example: http://... type: string bio: example: Updated store description maxLength: 500 type: string cover_url: example: http://... type: string email: example: newcontact@store.com type: string name: example: Updated Store Name maxLength: 50 minLength: 2 type: string phone: example: "+1234567890" type: string type: object store.AdminVerifyStoreRequestDTO: properties: admin_note: example: Store meets verification criteria maxLength: 1000 type: string type: object store.AnalyticsSummaryDTO: properties: average_stores_per_day: type: number suspension_rate: type: number total_new_stores: type: integer total_suspensions: type: integer total_verifications: type: integer verification_rate: type: number type: object store.AnalyticsTrendDTO: properties: change: type: number data_points: items: $ref: '#/definitions/store.TimeSeriesDataPointDTO' type: array label: type: string total: type: integer type: object store.BulkOperationResponseDTO: properties: processed_at: type: string results: items: $ref: '#/definitions/store.BulkOperationResultDTO' type: array total_failed: type: integer total_requested: type: integer total_successful: type: integer type: object store.BulkOperationResultDTO: properties: error: type: string store_id: type: string store_name: type: string success: type: boolean type: object store.BulkVerifyStoresRequestDTO: properties: async: description: Async forces async processing via RabbitMQ (optional, auto-async for >20 stores) type: boolean notes: maxLength: 500 type: string notify_owner: type: boolean store_ids: items: type: string maxItems: 100 minItems: 1 type: array required: - store_ids type: object store.CloseStoreRequestDTO: properties: admin_note: example: Vendor requested temporary closure maxLength: 1000 type: string reason: example: Taking a break for vacation maxLength: 500 minLength: 1 type: string type: object store.CreateStoreRequestDTO: properties: accepts_returns: example: true type: boolean address: example: Legon Hall, Room 234, University of Ghana maxLength: 200 type: string bio: example: We sell the best products on campus maxLength: 500 type: string custom_refund_policy: example: Custom refund terms maxLength: 1000 type: string email: example: contact@mystore.com type: string name: example: My Awesome Store maxLength: 50 minLength: 2 type: string phone: example: "+233501234567" type: string refund_conditions: example: Items must be unused and in original packaging maxLength: 500 type: string refund_policy_type: description: Refund & Return Policy enum: - no_refunds - exchange_only - store_credit_only - partial_refund - full_refund example: full_refund type: string refund_window_days: example: 14 maximum: 365 minimum: 1 type: integer restocking_fee_percentage: example: 10 maximum: 100 minimum: 0 type: number return_shipping_paid_by: enum: - buyer - seller - shared example: buyer type: string slug: example: my-awesome-store maxLength: 30 minLength: 2 type: string required: - name type: object store.DeactivateMyStoreRequestDTO: properties: reason: example: Closing for personal reasons maxLength: 500 type: string type: object store.ErrorDetail: properties: code: example: STORE_NOT_FOUND type: string details: example: Store with ID 123e4567-e89b-12d3-a456-426614174000 does not exist type: string message: example: The requested store was not found type: string type: object store.ErrorResponseDTO: properties: error: $ref: '#/definitions/store.ErrorDetail' success: example: false type: boolean type: object store.GetPublicStoreResponseDTO: properties: store: $ref: '#/definitions/store.PublicStoreDetailDTO' type: object store.ListPublicStoresResponseDTO: properties: pagination: $ref: '#/definitions/pagination.Pagination' stores: items: $ref: '#/definitions/store.PublicStoreItemDTO' type: array type: object store.ProductImagePreviewDTO: properties: alt_text: example: Product image type: string display_order: example: 0 type: integer id: example: 123e4567-e89b-12d3-a456-426614174000 type: string is_primary: example: true type: boolean large_url: example: https://example.com/product_large.jpg type: string medium_url: example: https://example.com/product_medium.jpg type: string thumbnail_url: example: https://example.com/product_thumb.jpg type: string url: example: https://example.com/product.jpg type: string type: object store.ProductPreviewDTO: properties: compare_at_price: example: 39.99 type: number condition: example: new type: string created_at: example: "2023-12-15T10:00:00Z" type: string description: example: A great product type: string id: example: 123e4567-e89b-12d3-a456-426614174000 type: string is_featured: example: false type: boolean price: example: 29.99 type: number primary_image: $ref: '#/definitions/store.ProductImagePreviewDTO' rating: example: 4.5 type: number review_count: example: 10 type: integer slug: example: cool-product type: string title: example: Cool Product type: string type: object store.PublicStoreDetailDTO: properties: accepts_returns: example: true type: boolean address: example: 123 Store Street type: string avatar_url: example: https://example.com/avatar.jpg type: string bio: example: We sell the best products on campus type: string conversion_rate: description: '% of visitors who purchase' example: 3.5 type: number cover_url: example: https://example.com/cover.jpg type: string created_at: example: "2023-12-01T10:00:00Z" type: string custom_refund_policy: example: See our website for details type: string follower_count: example: 678 type: integer id: description: Basic info example: 123e4567-e89b-12d3-a456-426614174000 type: string is_closed: description: Temporary closure example: false type: boolean is_following: description: Viewer-specific example: false type: boolean is_verified: example: true type: boolean item_count: example: 45 type: integer name: example: My Awesome Store type: string owner_id: example: 123e4567-e89b-12d3-a456-426614174001 type: string phone: description: Contact info (NO sensitive data like email in public view) example: "+1234567890" type: string product_previews: description: Enriched data items: $ref: '#/definitions/store.ProductPreviewDTO' type: array rating: example: 4.5 type: number refund_conditions: example: Items must be unused and in original packaging type: string refund_policy_type: description: Refund & Return Policy (PUBLIC - customers need to see this) example: full_refund type: string refund_window_days: example: 14 type: integer restocking_fee_percentage: example: 10 type: number return_shipping_paid_by: example: buyer type: string review_count: example: 123 type: integer review_summary: $ref: '#/definitions/store.ReviewSummaryDTO' slug: example: my-awesome-store type: string status: description: active, suspended, closed example: active type: string type: object store.PublicStoreItemDTO: properties: avatar_url: example: https://example.com/avatar.jpg type: string bio: example: We sell the best products type: string cover_url: example: https://example.com/cover.jpg type: string follower_count: example: 678 type: integer id: example: 123e4567-e89b-12d3-a456-426614174000 type: string is_closed: description: Temporary closure example: false type: boolean is_following: description: Whether current user follows this store example: false type: boolean is_verified: example: true type: boolean item_count: example: 45 type: integer name: example: My Awesome Store type: string rating: example: 4.5 type: number review_count: example: 123 type: integer slug: example: my-awesome-store type: string status: description: active, suspended, closed example: active type: string type: object store.ReviewPreviewDTO: properties: author_id: example: 123e4567-e89b-12d3-a456-426614174001 type: string comment: example: Great store! type: string created_at: example: "2023-12-15T10:00:00Z" type: string id: example: 123e4567-e89b-12d3-a456-426614174000 type: string rating: example: 5 type: integer type: object store.ReviewSummaryDTO: properties: average_rating: example: 4.5 type: number distribution: additionalProperties: type: integer description: '"5" -> 50, "4" -> 30, etc.' type: object recent_reviews: items: $ref: '#/definitions/store.ReviewPreviewDTO' type: array total_count: example: 123 type: integer type: object store.StoreActivitiesResponseDTO: properties: activities: items: $ref: '#/definitions/github_com_shoppie_backend_internal_handlers_store.StoreActivityDTO' type: array pagination: $ref: '#/definitions/pagination.Pagination' type: object store.StoreAnalyticsResponseDTO: properties: interval: type: string period: type: string stores_created: $ref: '#/definitions/store.AnalyticsTrendDTO' summary: $ref: '#/definitions/store.AnalyticsSummaryDTO' suspension_trend: $ref: '#/definitions/store.AnalyticsTrendDTO' verification_trend: $ref: '#/definitions/store.AnalyticsTrendDTO' type: object store.StoreBulkActionJobResponse: properties: job_id: type: string message: type: string status: description: '"queued", "processing", "completed", "failed"' type: string store_count: type: integer type: object store.StoreDTO: properties: accepts_returns: type: boolean address: type: string avatar_url: type: string bio: type: string closed_at: type: string closure_reason: type: string conversion_rate: type: number cover_url: type: string created_at: type: string custom_refund_policy: type: string email: type: string engagement_rate: type: number follower_count: type: integer growth_rate: type: number id: type: string is_closed: type: boolean is_suspended: type: boolean is_verified: type: boolean item_count: type: integer name: type: string order_count: type: integer orders_last_30_days: type: integer owner_id: type: string phone: type: string rating: type: number refund_conditions: type: string refund_policy_type: type: string refund_window_days: type: integer restocking_fee_percentage: type: number return_shipping_paid_by: type: string revenue_last_30_days: type: number review_count: type: integer slug: type: string status: type: string suspended_at: type: string suspended_until: type: string suspension_reason: type: string updated_at: type: string verification_notes: type: string verified_at: type: string views_last_30_days: type: integer type: object store.StoreDetailDTO: properties: accepts_returns: type: boolean address: type: string avatar_url: type: string bio: type: string closed_at: type: string closure_reason: type: string conversion_rate: type: number cover_url: type: string created_at: type: string custom_refund_policy: type: string email: type: string engagement_rate: type: number follower_count: type: integer growth_rate: type: number id: type: string is_closed: type: boolean is_suspended: type: boolean is_verified: type: boolean item_count: type: integer name: type: string order_count: type: integer orders_last_30_days: type: integer owner_id: type: string phone: type: string rating: type: number refund_conditions: type: string refund_policy_type: type: string refund_window_days: type: integer restocking_fee_percentage: type: number return_shipping_paid_by: type: string revenue_last_30_days: type: number review_count: type: integer slug: type: string status: type: string suspended_at: type: string suspended_until: type: string suspension_reason: type: string updated_at: type: string verification_notes: type: string verified_at: type: string views_last_30_days: type: integer type: object store.StoreStatisticsDTO: properties: active_today: example: 450 type: integer average_rating: example: 4.2 type: number new_this_month: example: 340 type: integer new_this_week: example: 85 type: integer new_today: example: 12 type: integer stores_with_followers: example: 980 type: integer stores_with_items: example: 1180 type: integer suspended_stores: example: 15 type: integer total_followers: example: 123456 type: integer total_items: example: 45678 type: integer total_stores: example: 1250 type: integer verified_stores: example: 890 type: integer type: object store.TimeSeriesDataPointDTO: properties: count: type: integer date: type: string type: object store.UpdateMyStoreRequestDTO: properties: accepts_returns: example: true type: boolean address: example: 123 Store Street, City type: string bio: example: Updated store description maxLength: 500 type: string custom_refund_policy: example: Custom refund terms maxLength: 1000 type: string email: example: store@example.com type: string name: example: My Updated Store maxLength: 50 minLength: 2 type: string phone: example: "+1234567890" type: string refund_conditions: example: Items must be unused and in original packaging maxLength: 500 type: string refund_policy_type: description: Refund & Return Policy enum: - no_refunds - exchange_only - store_credit_only - partial_refund - full_refund example: full_refund type: string refund_window_days: example: 14 maximum: 365 minimum: 1 type: integer restocking_fee_percentage: example: 10 maximum: 100 minimum: 0 type: number return_shipping_paid_by: enum: - buyer - seller - shared example: buyer type: string type: object store.UpdateStoreRequestDTO: properties: bio: example: Updated store description maxLength: 500 type: string name: example: Updated Store Name maxLength: 50 minLength: 2 type: string slug: example: updated-store-slug maxLength: 30 minLength: 2 type: string type: object store.UploadURLRequestDTO: properties: content_type: example: image/jpeg type: string file_name: example: store-avatar.jpg type: string file_size: example: 1048576 maximum: 10485760 minimum: 1 type: integer image_type: enum: - avatar - cover example: avatar type: string required: - content_type - file_name - file_size - image_type type: object store.UploadURLResponseDTO: properties: content_type: example: image/jpeg type: string expires_at: example: "2024-01-15T15:30:00Z" type: string form_data: additionalProperties: type: string type: object max_size: example: 10485760 type: integer method: example: PUT type: string path: example: stores/550e8400/2024/01/uuid_original.jpg type: string upload_id: example: 550e8400-e29b-41d4-a716-446655440000 type: string url: example: https://storage.example.com/stores/550e8400/avatar.jpg?signature=... type: string type: object support.CreateTicketRequestDTO: properties: email: type: string message: maxLength: 5000 minLength: 10 type: string name: maxLength: 255 minLength: 2 type: string subject: type: string website: type: string required: - email - message - name - subject type: object support.MessageResponse: properties: author_type: type: string body: type: string created_at: type: string id: type: string type: object support.ReplyRequestDTO: properties: body: maxLength: 5000 minLength: 1 type: string required: - body type: object support.ReplyResponse: properties: message: $ref: '#/definitions/support.MessageResponse' reopened: type: boolean status: type: string type: object support.TicketDetailResponse: properties: category: type: string created_at: type: string id: type: string last_reply_at: type: string messages: items: $ref: '#/definitions/support.MessageResponse' type: array priority: type: string status: type: string ticket_number: type: string type: object support.TicketResponse: properties: category: type: string created_at: type: string id: type: string status: type: string ticket_number: type: string type: object user.UpdateUserRequestDTO: properties: first_name: type: string last_name: type: string phone: type: string type: object user.UserProfileDTO: properties: email: type: string email_verified: type: boolean first_name: type: string id: type: string last_name: type: string role: type: string type: object user.UserResponse: properties: created_at: type: string email: type: string email_verified: type: boolean email_verified_at: type: string first_name: type: string id: type: string last_login_at: type: string last_name: type: string role: type: string two_factor_enabled: type: boolean updated_at: type: string type: object host: localhost:8080 info: contact: email: support@shoppie.com name: Shoppie API Support url: http://www.shopryte.com/support description: Shoppie backend API license: name: Apache 2.0 url: http://www.apache.org/licenses/LICENSE-2.0.html termsOfService: http://swagger.io/terms/ title: Shoppie API version: "1.0" paths: /admin/audit-logs: get: description: 'Returns paginated, filterable audit events. Read-only: this route has no create, update or delete surface. Requires moderator, admin or super_admin. Every successful query is itself recorded as an `admin.audit_log_viewed` audit event naming the viewer and the filters they applied ("audit the auditors", #683); if that record cannot be written the results are withheld and the request fails.' parameters: - description: Filter by actor user ID format: uuid in: query name: user_id type: string - description: Filter by actor email in: query name: user_email type: string - description: Filter by the role the actor held enum: - customer - vendor - moderator - admin - super_admin in: query name: actor_role type: string - description: Filter by event type, e.g. admin.user_banned in: query name: event_type type: string - description: Filter by event category enum: - auth - admin - store - dispute - report - payment - payout - security in: query name: category type: string - description: Filter by target kind, e.g. user or store in: query name: target_type type: string - description: Filter by target ID format: uuid in: query name: target_id type: string - description: Only events at or after this time (RFC3339) in: query name: date_from type: string - description: Only events at or before this time (RFC3339) in: query name: date_to type: string - default: 1 description: Page number, 1-based in: query name: page type: integer - default: 50 description: Page size, capped at 100 in: query name: limit type: integer produces: - application/json responses: "200": description: Matching audit events schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/audit.AuditLogsResponseDTO' type: object "400": description: Bad request - invalid query parameters schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized - invalid or missing token schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden - moderator, admin or super_admin required schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal server error, or the access could not be recorded and the results were withheld schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Query the audit trail tags: - Admin - Audit /admin/auth/logout: post: consumes: - application/json description: Logout admin user produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: additionalProperties: type: string type: object type: object "401": description: Unauthorized - admin authentication required schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal server error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Admin logout tags: - Admin Authentication x-admin-only: true /admin/auth/me: get: description: Get the authenticated admin user's profile information. Requires admin, moderator, or super_admin role. produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/auth.AdminMeResponse' type: object "401": description: Not authenticated schema: $ref: '#/definitions/response.StandardResponse' "403": description: Not an admin user schema: $ref: '#/definitions/response.StandardResponse' "404": description: User not found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal server error schema: $ref: '#/definitions/response.StandardResponse' security: - Bearer: [] summary: Get current admin user profile tags: - Admin Authentication /admin/auth/otp/send: post: consumes: - application/json description: Sends a 6-digit OTP code to admin users for authentication. Returns generic success message to prevent user enumeration. Only active admin users will receive the code. parameters: - description: OTP request containing admin email in: body name: request required: true schema: $ref: '#/definitions/auth.OTPRequest' produces: - application/json responses: "200": description: OTP request processed (generic response for security) schema: $ref: '#/definitions/auth.OTPResponse' "400": description: Invalid request format schema: $ref: '#/definitions/response.StandardResponse' "429": description: Rate limit exceeded schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal server error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Request Admin OTP Authentication tags: - Admin Authentication /admin/auth/otp/verify: post: consumes: - application/json description: Verifies a 6-digit OTP code and authenticates the admin user. Returns authentication tokens and sets HttpOnly cookies. If 2FA is enabled, returns a two_factor_token for the 2FA verification step. parameters: - description: OTP verification request with email and code in: body name: request required: true schema: $ref: '#/definitions/auth.OTPVerifyRequest' produces: - application/json responses: "200": description: Authentication successful schema: $ref: '#/definitions/auth.OTPVerifyResponse' "400": description: Invalid request format schema: $ref: '#/definitions/response.StandardResponse' "401": description: Invalid, expired, or already used code schema: $ref: '#/definitions/response.StandardResponse' "403": description: User no longer has admin privileges or account is banned schema: $ref: '#/definitions/response.StandardResponse' "429": description: Too many attempts - account temporarily locked schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal server error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Verify Admin OTP Code tags: - Admin Authentication /admin/auth/otp/verify-2fa: post: consumes: - application/json description: Completes 2FA authentication after OTP verification. Accepts a two_factor_token from the OTP verify step along with a TOTP code or backup code. parameters: - description: 2FA verification with token and code in: body name: request required: true schema: $ref: '#/definitions/auth.OTPWith2FAVerifyRequest' produces: - application/json responses: "200": description: Authentication successful schema: $ref: '#/definitions/auth.OTPVerifyResponse' "400": description: Invalid request format schema: $ref: '#/definitions/response.StandardResponse' "401": description: Invalid or expired 2FA token schema: $ref: '#/definitions/response.StandardResponse' "403": description: 2FA not enabled or invalid code schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal server error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Verify Admin OTP 2FA Code tags: - Admin Authentication /admin/bookings: get: consumes: - application/json description: List all bookings with filters (admin only) parameters: - description: Filter by service ID in: query name: service_id type: string - description: Filter by customer ID in: query name: customer_id type: string - description: Filter by provider ID in: query name: provider_id type: string - description: Filter by status in: query name: status type: string - description: Filter by payment status in: query name: payment_status type: string - description: Filter from date (YYYY-MM-DD) in: query name: date_from type: string - description: Filter to date (YYYY-MM-DD) in: query name: date_to type: string - description: Filter by booking code in: query name: booking_code type: string - default: 1 description: Page number in: query name: page type: integer - default: 20 description: Page size in: query name: limit type: integer produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: items: $ref: '#/definitions/booking.BookingResponseDTO' type: array type: object "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: List all bookings (Admin) tags: - Admin Bookings /admin/bookings/{id}: get: consumes: - application/json description: Get booking details by ID with admin privileges parameters: - description: Booking ID in: path name: id required: true type: string produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/booking.BookingResponseDTO' type: object "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Get booking by ID (Admin) tags: - Admin Bookings /admin/bookings/{id}/cancel: post: consumes: - application/json description: Cancel a booking as admin with optional override refund amount parameters: - description: Booking ID in: path name: id required: true type: string - description: Cancel request in: body name: request required: true schema: $ref: '#/definitions/booking.AdminCancelRequestDTO' produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/booking.AdminCancelResponseDTO' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Admin cancel a booking tags: - Admin Bookings /admin/bookings/{id}/flag: post: consumes: - application/json description: |- Marks a booking as flagged with a reason and severity. Flagging does not change the booking's status or payment state — the booking keeps working normally — it only surfaces the booking in the anomaly queue for review. parameters: - description: Booking ID in: path name: id required: true type: string - description: Flag request in: body name: request required: true schema: $ref: '#/definitions/booking.AdminFlagBookingRequestDTO' produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/booking.BookingFlagResponseDTO' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' "409": description: Conflict schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Flag a booking for admin review tags: - Admin Bookings /admin/bookings/{id}/refund: post: consumes: - application/json description: Issue a standalone refund for a paid booking parameters: - description: Booking ID in: path name: id required: true type: string - description: Refund request in: body name: request required: true schema: $ref: '#/definitions/booking.AdminRefundRequestDTO' produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/booking.AdminRefundResponseDTO' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Admin refund a booking tags: - Admin Bookings /admin/bookings/{id}/unflag: post: consumes: - application/json description: |- Resolves the booking's active admin flag. The flag is retained as an audit record; the unflag action itself is audit-logged. parameters: - description: Booking ID in: path name: id required: true type: string produces: - application/json responses: "200": description: OK schema: $ref: '#/definitions/response.StandardResponse' "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Remove a booking's active flag tags: - Admin Bookings /admin/bookings/anomalies: get: consumes: - application/json description: Returns bookings with admin flags, sorted by severity then recency. parameters: - description: Filter by severity (low|medium|high) in: query name: severity type: string - description: Filter by flag reason (substring match) in: query name: flag_reason type: string - description: Filter flags created from date (YYYY-MM-DD) in: query name: date_from type: string - description: Filter flags created to date (YYYY-MM-DD) in: query name: date_to type: string - description: Filter by resolution state; omit for all in: query name: resolved type: boolean - default: 1 description: Page number in: query name: page type: integer - default: 20 description: Page size in: query name: limit type: integer produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: items: $ref: '#/definitions/booking.FlaggedBookingResponseDTO' type: array type: object "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: List flagged/anomalous bookings tags: - Admin Bookings /admin/bookings/bulk-refund: post: consumes: - application/json description: Process refunds for multiple bookings with partial success model parameters: - description: Bulk refund request in: body name: request required: true schema: $ref: '#/definitions/booking.AdminBulkRefundRequestDTO' produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/booking.AdminBulkRefundResponseDTO' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Bulk refund bookings tags: - Admin Bookings /admin/bookings/bulk-status: post: consumes: - application/json description: Update multiple booking statuses at once (admin only) parameters: - description: Bulk update request in: body name: request required: true schema: $ref: '#/definitions/booking.BulkUpdateStatusRequestDTO' produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/booking.BulkUpdateResponseDTO' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Bulk update booking statuses tags: - Admin Bookings /admin/bookings/disputes: get: consumes: - application/json description: |- Disputes on this platform are tracked against orders, not bookings, so a booking "dispute" is a flagged booking whose payment_status is failed or refunded (e.g. after a chargeback). Returns active flags only. parameters: - description: Filter by severity (low|medium|high) in: query name: severity type: string - description: Filter flags created from date (YYYY-MM-DD) in: query name: date_from type: string - description: Filter flags created to date (YYYY-MM-DD) in: query name: date_to type: string - default: 1 description: Page number in: query name: page type: integer - default: 20 description: Page size in: query name: limit type: integer produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: items: $ref: '#/definitions/booking.FlaggedBookingResponseDTO' type: array type: object "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: List bookings with dispute indicators tags: - Admin Bookings /admin/bookings/stats: get: consumes: - application/json description: Get overall booking statistics (admin only) parameters: - description: Filter by service ID in: query name: service_id type: string - description: Filter by provider ID in: query name: provider_id type: string - description: Start date (YYYY-MM-DD) in: query name: date_from type: string - description: End date (YYYY-MM-DD) in: query name: date_to type: string produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/booking.StatsResponseDTO' type: object "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Get booking statistics (Admin) tags: - Admin Bookings /admin/boost/analytics: get: description: 'Returns program-wide boost metrics: retained revenue, refunded amount, active and total boost counts, and the top boosted listings.' parameters: - description: Number of top boosted listings to return (1-50, default 10) in: query name: top type: integer produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: type: object type: object "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Get boost program analytics (admin) tags: - Admin - Boost /admin/boost/boosts: get: description: Lists boosts across every store for moderation, optionally filtered by status, newest first. parameters: - description: Filter by lifecycle status enum: - pending_payment - active - paused - ended - refunded in: query name: status type: string - description: Filter by target type enum: - product - service in: query name: target_type type: string - description: Filter by store ID in: query name: store_id type: string - description: Page number in: query name: page type: integer - description: Page size in: query name: limit type: integer produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: type: object type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: List all boosts (admin) tags: - Admin - Boost /admin/boost/boosts/{id}/pause: post: description: Pauses an active boost so it stops surfacing in discovery immediately. parameters: - description: Boost ID in: path name: id required: true type: string produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: type: object type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' "409": description: Conflict schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Pause a boost (admin) tags: - Admin - Boost /admin/boost/boosts/{id}/resume: post: description: Lifts a moderation pause, extending the boost's end date by the paused duration so no paid days are lost. Only a boost an admin paused can be resumed here. parameters: - description: Boost ID in: path name: id required: true type: string produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: type: object type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' "409": description: Conflict schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Resume an admin-paused boost (admin) tags: - Admin - Boost /admin/boost/config: get: description: Returns the admin-tunable sponsored-slot cap and minimum rating gate. produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: type: object type: object "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Get boost ranking config (admin) tags: - Admin - Boost put: consumes: - application/json description: Tunes the sponsored-slot cap fraction, minimum sponsored slots, and minimum rating gate. parameters: - description: Ranking config in: body name: request required: true schema: $ref: '#/definitions/github_com_shoppie_backend_internal_handlers_boost.UpdateRankingConfigRequest' produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: type: object type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Update boost ranking config (admin) tags: - Admin - Boost /admin/boost/grants: post: consumes: - application/json description: Grants a vendor a free boost on one of their listings, bypassing the purchase/payment flow. The boost activates immediately, is excluded from revenue, and cannot be refunded. A reason is required; a failed eligibility gate may be consciously overridden. parameters: - description: Grant details in: body name: request required: true schema: $ref: '#/definitions/github_com_shoppie_backend_internal_handlers_boost.GrantBoostRequest' produces: - application/json responses: "201": description: Created schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: type: object type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' "409": description: Conflict schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Grant a complimentary boost (admin) tags: - Admin - Boost /admin/boost/packages: get: description: Lists all boost packages (active and inactive) for admins parameters: - description: Page number in: query name: page type: integer - description: Page size in: query name: limit type: integer produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: type: object type: object "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: List all boost packages tags: - Admin - Boost post: consumes: - application/json description: Creates a new admin-configured boost package (tier weight, duration, price) parameters: - description: Boost package data in: body name: request required: true schema: $ref: '#/definitions/github_com_shoppie_backend_internal_handlers_boost.CreatePackageRequest' produces: - application/json responses: "201": description: Created schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: type: object type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Create a boost package tags: - Admin - Boost /admin/boost/packages/{id}: delete: description: Hides a boost package from the catalogue without deleting it parameters: - description: Package ID in: path name: id required: true type: string produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: type: object type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Deactivate a boost package tags: - Admin - Boost put: consumes: - application/json description: Updates an existing boost package's catalogue values parameters: - description: Package ID in: path name: id required: true type: string - description: Boost package data in: body name: request required: true schema: $ref: '#/definitions/github_com_shoppie_backend_internal_handlers_boost.UpdatePackageRequest' produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: type: object type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Update a boost package tags: - Admin - Boost /admin/boost/packages/{id}/activate: post: description: Makes a boost package purchasable again after deactivation parameters: - description: Package ID in: path name: id required: true type: string produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: type: object type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Reactivate a boost package tags: - Admin - Boost /admin/carts: get: description: List all carts with filters (admin only) parameters: - description: Cart status filter in: query name: status type: string - description: User ID filter in: query name: user_id type: string - description: Store ID filter in: query name: store_id type: string - description: Flagged filter in: query name: flagged type: boolean - description: Page number in: query name: page type: integer - description: Items per page in: query name: limit type: integer produces: - application/json responses: "200": description: Carts list schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: items: $ref: '#/definitions/cart.CartResponse' type: array type: object "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal server error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: List all carts tags: - Cart - Admin /admin/carts/{cartId}: get: description: Get detailed cart information (admin only) parameters: - description: Cart ID in: path name: cartId required: true type: string produces: - application/json responses: "200": description: Cart details schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/cart.CartDetailResponse' type: object "400": description: Bad request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: Cart not found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal server error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Get cart details tags: - Cart - Admin /admin/carts/{cartId}/flag: post: consumes: - application/json description: Flag a cart for review (admin only) parameters: - description: Cart ID in: path name: cartId required: true type: string - description: Flag cart request in: body name: request required: true schema: $ref: '#/definitions/cart.FlagCartRequest' produces: - application/json responses: "200": description: Cart flagged schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/cart.MessageResponse' type: object "400": description: Bad request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: Cart not found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal server error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Flag a cart tags: - Cart - Admin /admin/carts/{cartId}/history: get: description: Get cart action history (admin only) parameters: - description: Cart ID in: path name: cartId required: true type: string - description: Page number in: query name: page type: integer - description: Items per page in: query name: limit type: integer produces: - application/json responses: "200": description: Cart history schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: items: $ref: '#/definitions/cart.CartActionHistory' type: array type: object "400": description: Bad request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: Cart not found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal server error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Get cart history tags: - Cart - Admin /admin/carts/{cartId}/notes: post: consumes: - application/json description: Add an admin note to a cart (admin only) parameters: - description: Cart ID in: path name: cartId required: true type: string - description: Add note request in: body name: request required: true schema: $ref: '#/definitions/cart.AddNoteRequest' produces: - application/json responses: "201": description: Note added schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/cart.MessageResponse' type: object "400": description: Bad request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: Cart not found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal server error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Add note to cart tags: - Cart - Admin /admin/carts/{cartId}/recovery: post: consumes: - application/json description: Send a cart recovery email to the user (admin only) parameters: - description: Cart ID in: path name: cartId required: true type: string - description: Recovery email request in: body name: request required: true schema: $ref: '#/definitions/cart.SendRecoveryRequest' produces: - application/json responses: "200": description: Recovery email sent schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/cart.MessageResponse' type: object "400": description: Bad request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: Cart not found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal server error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Send recovery email tags: - Cart - Admin /admin/carts/{cartId}/unflag: post: description: Remove flag from a cart (admin only) parameters: - description: Cart ID in: path name: cartId required: true type: string produces: - application/json responses: "200": description: Cart unflagged schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/cart.MessageResponse' type: object "400": description: Bad request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: Cart not found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal server error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Unflag a cart tags: - Cart - Admin /admin/carts/analytics: get: description: Get platform-wide cart analytics (admin only) parameters: - description: Date from (RFC3339) in: query name: date_from type: string - description: Date to (RFC3339) in: query name: date_to type: string produces: - application/json responses: "200": description: Platform analytics retrieved schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/cart.CartAnalyticsResponse' type: object "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal server error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Get platform cart analytics tags: - Cart - Admin /admin/carts/export: get: description: Export carts data as CSV (admin only) parameters: - description: Cart status filter in: query name: status type: string - description: Date from (RFC3339) in: query name: date_from type: string - description: Date to (RFC3339) in: query name: date_to type: string produces: - text/csv responses: "200": description: CSV file schema: type: file "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal server error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Export carts tags: - Cart - Admin /admin/carts/most-abandoned: get: description: Get products most frequently left in abandoned carts (admin only) parameters: - description: Page number in: query name: page type: integer - description: Items per page in: query name: limit type: integer produces: - application/json responses: "200": description: Most abandoned products schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: items: $ref: '#/definitions/cart.AbandonedProductResponse' type: array type: object "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal server error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Get most abandoned products tags: - Cart - Admin /admin/carts/search: get: description: Search carts by various criteria (admin only) parameters: - description: Search query in: query name: q type: string - description: User email in: query name: email type: string - description: Page number in: query name: page type: integer - description: Items per page in: query name: limit type: integer produces: - application/json responses: "200": description: Search results schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: items: $ref: '#/definitions/cart.CartResponse' type: array type: object "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal server error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Search carts tags: - Cart - Admin /admin/categories: get: consumes: - application/json description: List all categories with filtering options including soft-deleted ones (admin only) parameters: - default: 1 description: Page number in: query name: page type: integer - default: 20 description: Page size in: query name: page_size type: integer - description: Category type filter enum: - product - service in: query name: type type: string - description: Parent category ID filter in: query name: parent_id type: string - description: Deleted status filter enum: - all - active - deleted in: query name: deleted_status type: string - description: Search query in: query name: search type: string - description: Only root categories in: query name: root_only type: boolean produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/category.AdminListCategoriesResponse' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' summary: List all categories for admin (includes deleted) tags: - admin-categories post: consumes: - application/json description: Create a new category (admin only) parameters: - description: Create category request in: body name: request required: true schema: $ref: '#/definitions/category.CreateCategoryRequestDTO' produces: - application/json responses: "201": description: Created schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/category.CategoryResponse' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "409": description: Conflict schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' summary: Create a new category tags: - admin-categories /admin/categories/{id}: delete: consumes: - application/json description: Soft-delete a category (admin only) parameters: - description: Category ID in: path name: id required: true type: string - description: Force delete even if has children in: query name: force type: boolean produces: - application/json responses: "200": description: OK schema: $ref: '#/definitions/response.StandardResponse' "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' "409": description: Conflict schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' summary: Delete a category tags: - admin-categories get: consumes: - application/json description: Get a category by ID including soft-deleted ones (admin only) parameters: - description: Category ID in: path name: id required: true type: string produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/category.CategoryResponse' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' summary: Get category by ID for admin (includes deleted) tags: - admin-categories patch: consumes: - application/json description: Update an existing category (admin only) parameters: - description: Category ID in: path name: id required: true type: string - description: Update category request in: body name: request required: true schema: $ref: '#/definitions/category.UpdateCategoryRequestDTO' produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/category.CategoryResponse' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' "409": description: Conflict schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' summary: Update a category tags: - admin-categories /admin/categories/{id}/attributes: post: consumes: - application/json description: Adds an attribute definition to a category; every category beneath it inherits the attribute (admin only) parameters: - description: Category ID in: path name: id required: true type: string - description: Attribute definition in: body name: request required: true schema: $ref: '#/definitions/category.DeclareAttributeRequest' produces: - application/json responses: "201": description: Created schema: $ref: '#/definitions/response.StandardResponse' "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' summary: Declare an attribute on a category tags: - admin-categories /admin/categories/{id}/attributes/{attributeId}: delete: description: Withdraws an attribute from new listings without deleting values existing listings carry. Only the category that declared the attribute may archive it; a category that merely inherits it is rejected (admin only) parameters: - description: Category ID in: path name: id required: true type: string - description: Attribute ID in: path name: attributeId required: true type: string produces: - application/json responses: "200": description: OK schema: $ref: '#/definitions/response.StandardResponse' "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' summary: Archive an attribute tags: - admin-categories patch: consumes: - application/json description: Changes an attribute's name, display type, unit or flags. Renaming propagates immediately to every listing and saved filter that references the attribute, since both read it by identifier rather than by label. Only the category that declared the attribute may edit it (admin only) parameters: - description: Category ID in: path name: id required: true type: string - description: Attribute ID in: path name: attributeId required: true type: string - description: Fields to change in: body name: request required: true schema: $ref: '#/definitions/category.UpdateAttributeRequest' produces: - application/json responses: "200": description: OK schema: $ref: '#/definitions/response.StandardResponse' "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' "409": description: Conflict schema: $ref: '#/definitions/response.StandardResponse' summary: Edit an attribute declared on a category tags: - admin-categories /admin/categories/{id}/attributes/{attributeId}/narrowing: put: consumes: - application/json description: Replaces the set of values this category permits for an inherited attribute; an empty set is rejected because that would remove the attribute, which inheritance forbids (admin only) parameters: - description: Category ID in: path name: id required: true type: string - description: Attribute ID in: path name: attributeId required: true type: string - description: Permitted value IDs in: body name: request required: true schema: $ref: '#/definitions/category.NarrowAttributeRequest' produces: - application/json responses: "200": description: OK schema: $ref: '#/definitions/response.StandardResponse' "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' summary: Restrict an inherited attribute's values for a category tags: - admin-categories /admin/categories/{id}/attributes/{attributeId}/values: post: consumes: - application/json description: Adds a value an administrator authored, which is filterable immediately. Only the category that declared the attribute may add one (admin only) parameters: - description: Category ID in: path name: id required: true type: string - description: Attribute ID in: path name: attributeId required: true type: string - description: Value to add in: body name: request required: true schema: $ref: '#/definitions/category.AddAttributeValueRequest' produces: - application/json responses: "201": description: Created schema: $ref: '#/definitions/response.StandardResponse' "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' "409": description: Conflict schema: $ref: '#/definitions/response.StandardResponse' summary: Add an admin-curated permitted value to an attribute tags: - admin-categories /admin/categories/{id}/attributes/reorder: post: consumes: - application/json description: Sets the position of every named attribute in one transaction. Only attributes this category itself declared may be reordered here; an inherited attribute's order is set on the category that declared it (admin only) parameters: - description: Category ID in: path name: id required: true type: string - description: New positions in: body name: request required: true schema: $ref: '#/definitions/category.ReorderAttributesRequest' produces: - application/json responses: "200": description: OK schema: $ref: '#/definitions/response.StandardResponse' "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' "409": description: Conflict schema: $ref: '#/definitions/response.StandardResponse' summary: Reorder the attributes a category declared tags: - admin-categories /admin/categories/{id}/image: delete: consumes: - application/json description: Delete the main image for a category (admin only) parameters: - description: Category ID in: path name: id required: true type: string produces: - application/json responses: "200": description: OK schema: $ref: '#/definitions/response.StandardResponse' "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' summary: Delete a category image tags: - admin-categories post: consumes: - multipart/form-data description: Upload a main image for a category (admin only) parameters: - description: Category ID in: path name: id required: true type: string - description: Image file in: formData name: image required: true type: file produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/category.UploadCategoryImageResponse' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' summary: Upload a category image tags: - admin-categories /admin/categories/{id}/move: post: consumes: - application/json description: Move a category to a new parent (admin only) parameters: - description: Category ID in: path name: id required: true type: string - description: Move category request in: body name: request required: true schema: $ref: '#/definitions/category.MoveCategoryRequestDTO' produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/category.CategoryResponse' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' summary: Move a category tags: - admin-categories /admin/categories/{id}/permanent: delete: consumes: - application/json description: Permanently delete a category from the database (admin only) parameters: - description: Category ID in: path name: id required: true type: string produces: - application/json responses: "200": description: OK schema: $ref: '#/definitions/response.StandardResponse' "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' "409": description: Conflict schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' summary: Permanently delete a category tags: - admin-categories /admin/categories/{id}/restore: post: consumes: - application/json description: Restore a soft-deleted category (admin only) parameters: - description: Category ID in: path name: id required: true type: string produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/category.CategoryResponse' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' summary: Restore a deleted category tags: - admin-categories /admin/categories/{id}/statistics: get: consumes: - application/json description: Get statistics for a specific category (admin only) parameters: - description: Category ID in: path name: id required: true type: string produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/category.CategoryStatisticsResponse' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' summary: Get category statistics tags: - admin-categories /admin/categories/bulk/activate: post: consumes: - application/json description: Activate multiple categories at once (admin only) parameters: - description: Bulk action request in: body name: request required: true schema: $ref: '#/definitions/category.BulkActionRequestDTO' produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/category.BulkActionResponseDTO' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' summary: Bulk activate categories tags: - admin-categories /admin/categories/bulk/deactivate: post: consumes: - application/json description: Deactivate multiple categories at once (admin only) parameters: - description: Bulk action request in: body name: request required: true schema: $ref: '#/definitions/category.BulkActionRequestDTO' produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/category.BulkActionResponseDTO' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' summary: Bulk deactivate categories tags: - admin-categories /admin/categories/bulk/delete: post: consumes: - application/json description: Soft-delete multiple categories at once (admin only) parameters: - description: Bulk action request in: body name: request required: true schema: $ref: '#/definitions/category.BulkActionRequestDTO' produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/category.BulkActionResponseDTO' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' summary: Bulk delete categories tags: - admin-categories /admin/categories/bulk/feature: post: consumes: - application/json description: Mark multiple categories as featured (admin only) parameters: - description: Bulk action request in: body name: request required: true schema: $ref: '#/definitions/category.BulkActionRequestDTO' produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/category.BulkActionResponseDTO' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' summary: Bulk feature categories tags: - admin-categories /admin/categories/bulk/restore: post: consumes: - application/json description: Restore multiple soft-deleted categories at once (admin only) parameters: - description: Bulk action request in: body name: request required: true schema: $ref: '#/definitions/category.BulkActionRequestDTO' produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/category.BulkActionResponseDTO' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' summary: Bulk restore categories tags: - admin-categories /admin/categories/bulk/unfeature: post: consumes: - application/json description: Remove featured status from multiple categories (admin only) parameters: - description: Bulk action request in: body name: request required: true schema: $ref: '#/definitions/category.BulkActionRequestDTO' produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/category.BulkActionResponseDTO' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' summary: Bulk unfeature categories tags: - admin-categories /admin/categories/health: get: description: 'Sweeps the taxonomy for ancestry corruption: mismatched paths, mismatched levels, orphaned parents and cycles (admin only)' produces: - application/json responses: "200": description: OK schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "503": description: Service Unavailable schema: $ref: '#/definitions/response.StandardResponse' summary: Check category tree invariants tags: - admin-categories /admin/categories/reorder: post: consumes: - application/json description: Reorder multiple categories at once (admin only) parameters: - description: Reorder request in: body name: request required: true schema: $ref: '#/definitions/category.ReorderCategoriesRequestDTO' produces: - application/json responses: "200": description: OK schema: $ref: '#/definitions/response.StandardResponse' "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' summary: Batch reorder categories tags: - admin-categories /admin/categories/search: get: consumes: - application/json description: Search categories using database query (name and description) parameters: - description: Search query (searches name and description) in: query name: q type: string - description: Category type (product, service) in: query name: type type: string - description: Filter by active status in: query name: is_active type: boolean - description: Filter by featured status in: query name: is_featured type: boolean - description: Filter by parent ID in: query name: parent_id type: string - default: false description: Include soft-deleted categories in: query name: include_deleted type: boolean - default: 1 description: Page number in: query name: page type: integer - default: 20 description: Page size in: query name: page_size type: integer produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/category.SearchCategoriesResponseDTO' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Search categories (Admin) tags: - admin-categories /admin/categories/stats: get: consumes: - application/json description: Get aggregated statistics for all categories (admin only) produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/category.GlobalStatisticsResponseDTO' type: object "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' summary: Get global category statistics tags: - admin-categories /admin/disputes: get: description: Admin retrieves list of all disputes with filters parameters: - description: Filter by status in: query name: status type: string - description: Filter by priority in: query name: priority type: string - description: Filter by reason in: query name: reason type: string - description: Filter by assigned admin ID in: query name: assigned_to type: string - description: Filter unassigned disputes in: query name: unassigned type: boolean - description: Filter SLA breached disputes in: query name: sla_breached type: boolean - description: Filter by store ID in: query name: store_id type: string - description: Filter by buyer ID in: query name: buyer_id type: string - description: Filter by seller ID in: query name: seller_id type: string - description: Start date (YYYY-MM-DD) in: query name: date_from type: string - description: End date (YYYY-MM-DD) in: query name: date_to type: string - description: Search term in: query name: search type: string - description: Page number in: query name: page type: integer - description: Items per page in: query name: limit type: integer produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: items: $ref: '#/definitions/dispute.DisputeResponse' type: array type: object "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: List all disputes (Admin) tags: - Disputes - Admin /admin/disputes/{disputeId}: get: description: Admin retrieves full details of a dispute including messages, evidence, and activities parameters: - description: Dispute ID in: path name: disputeId required: true type: string produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/dispute.AdminDisputeDetailResponse' type: object "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Get dispute details (Admin) tags: - Disputes - Admin /admin/disputes/{disputeId}/assign: post: consumes: - application/json description: Admin assigns a dispute to themselves or another admin parameters: - description: Dispute ID in: path name: disputeId required: true type: string - description: Assign request in: body name: request required: true schema: $ref: '#/definitions/dispute.AdminAssignRequest' produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/dispute.DisputeResponse' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Assign dispute to admin tags: - Disputes - Admin /admin/disputes/{disputeId}/escalate: post: consumes: - application/json description: Admin escalates a dispute for senior review parameters: - description: Dispute ID in: path name: disputeId required: true type: string - description: Escalate request in: body name: request required: true schema: $ref: '#/definitions/dispute.AdminEscalateRequest' produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/dispute.DisputeResponse' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Escalate dispute (Admin) tags: - Disputes - Admin /admin/disputes/{disputeId}/messages: post: consumes: - application/json description: Admin sends a message in a dispute (can be internal note) parameters: - description: Dispute ID in: path name: disputeId required: true type: string - description: Send message request in: body name: request required: true schema: $ref: '#/definitions/dispute.AdminSendMessageRequestDTO' produces: - application/json responses: "201": description: Created schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/dispute.MessageResponse' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Send message as admin tags: - Disputes - Admin /admin/disputes/{disputeId}/pause-sla: post: consumes: - application/json description: Admin pauses the SLA timer for a dispute parameters: - description: Dispute ID in: path name: disputeId required: true type: string - description: Pause SLA request in: body name: request required: true schema: $ref: '#/definitions/dispute.AdminPauseSLARequestDTO' produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/dispute.DisputeResponse' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Pause SLA timer (Admin) tags: - Disputes - Admin /admin/disputes/{disputeId}/refund: post: consumes: - application/json description: Admin processes a refund for a dispute parameters: - description: Dispute ID in: path name: disputeId required: true type: string - description: Process refund request in: body name: request required: true schema: $ref: '#/definitions/dispute.AdminProcessRefundRequestDTO' produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/dispute.RefundResponse' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Process refund (Admin) tags: - Disputes - Admin /admin/disputes/{disputeId}/resolve: post: consumes: - application/json description: Admin resolves a dispute with an outcome parameters: - description: Dispute ID in: path name: disputeId required: true type: string - description: Resolve request in: body name: request required: true schema: $ref: '#/definitions/dispute.AdminResolveRequest' produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/dispute.DisputeResponse' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Resolve dispute (Admin) tags: - Disputes - Admin /admin/disputes/{disputeId}/resume-sla: post: description: Admin resumes the SLA timer for a dispute parameters: - description: Dispute ID in: path name: disputeId required: true type: string produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/dispute.DisputeResponse' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Resume SLA timer (Admin) tags: - Disputes - Admin /admin/disputes/{disputeId}/status: put: consumes: - application/json description: Admin updates the status of a dispute parameters: - description: Dispute ID in: path name: disputeId required: true type: string - description: Update status request in: body name: request required: true schema: $ref: '#/definitions/dispute.AdminUpdateStatusRequestDTO' produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/dispute.DisputeResponse' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Update dispute status (Admin) tags: - Disputes - Admin /admin/disputes/statistics: get: description: Admin retrieves platform-wide dispute statistics parameters: - description: Filter by store ID in: query name: store_id type: string - description: Start date (YYYY-MM-DD) in: query name: date_from type: string - description: End date (YYYY-MM-DD) in: query name: date_to type: string produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/dispute.StatisticsResponse' type: object "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Get dispute statistics (Admin) tags: - Disputes - Admin /admin/featuring/featured-configs: get: consumes: - application/json description: Lists all featured configs with pagination parameters: - default: 1 description: Page number in: query name: page type: integer - default: 20 description: Page size in: query maximum: 100 name: page_size type: integer produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: type: object type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: List featured store configurations tags: - Admin - Featuring post: consumes: - application/json description: Creates a new featured store configuration with quality criteria parameters: - description: Featured config data in: body name: request required: true schema: $ref: '#/definitions/github_com_shoppie_backend_internal_handlers_featuring.CreateFeaturedConfigRequest' produces: - application/json responses: "201": description: Created schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: type: object type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Create a new featured store configuration tags: - Admin - Featuring /admin/featuring/featured-configs/{id}/activate: post: consumes: - application/json description: Activates a featured config (deactivates all others atomically) parameters: - description: Config ID format: uuid in: path name: id required: true type: string - description: Activation reason in: body name: request required: true schema: $ref: '#/definitions/github_com_shoppie_backend_internal_handlers_featuring.ActivateFeaturedConfigRequest' produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: type: object type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' "409": description: Conflict schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Activate a featured store configuration tags: - Admin - Featuring /admin/featuring/manual-features: get: consumes: - application/json description: Lists all manual features with pagination and optional store filter parameters: - default: 1 description: Page number in: query name: page type: integer - default: 20 description: Page size in: query maximum: 100 name: page_size type: integer - description: Filter by store ID format: uuid in: query name: store_id type: string produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: type: object type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: List manual features tags: - Admin - Featuring post: consumes: - application/json description: Manually features a store for campaigns/promotions (max 10 active) parameters: - description: Manual feature data in: body name: request required: true schema: $ref: '#/definitions/github_com_shoppie_backend_internal_handlers_featuring.FeatureStoreManuallyRequest' produces: - application/json responses: "201": description: Created schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: type: object type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' "409": description: Conflict schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Manually feature a store tags: - Admin - Featuring /admin/featuring/manual-features/{id}: delete: consumes: - application/json description: Deactivates a manual featured store parameters: - description: Feature ID format: uuid in: path name: id required: true type: string - description: Removal reason in: body name: request required: true schema: $ref: '#/definitions/github_com_shoppie_backend_internal_handlers_featuring.RemoveManualFeatureRequest' produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: type: object type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Remove a manual feature tags: - Admin - Featuring /admin/featuring/manual/bulk: post: consumes: - application/json description: |- Features multiple stores for campaigns/promotions. For small operations (≤10 stores), processing is synchronous unless async=true. For large operations (>10 stores), processing is always async (returns 202 Accepted). parameters: - description: Bulk featuring details in: body name: request required: true schema: $ref: '#/definitions/featuring.BulkFeatureStoresRequest' produces: - application/json responses: "200": description: Bulk feature completed (sync mode) schema: $ref: '#/definitions/response.StandardResponse' "202": description: Bulk feature queued (async mode) schema: $ref: '#/definitions/featuring.FeaturingBulkActionJobResponse' "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "409": description: Max manual features limit reached schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Bulk feature multiple stores tags: - Admin - Featuring /admin/featuring/manual/bulk-extend: patch: consumes: - application/json description: |- Extends the end date for multiple manual features at once (useful for successful campaigns). For small operations (≤10 features), processing is synchronous unless async=true. For large operations (>10 features), processing is always async (returns 202 Accepted). parameters: - description: Bulk extend details in: body name: request required: true schema: $ref: '#/definitions/featuring.BulkExtendFeaturesRequest' produces: - application/json responses: "200": description: Bulk extend completed (sync mode) schema: $ref: '#/definitions/response.StandardResponse' "202": description: Bulk extend queued (async mode) schema: $ref: '#/definitions/featuring.FeaturingBulkActionJobResponse' "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: One or more features not found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Bulk extend manual features tags: - Admin - Featuring /admin/featuring/trending-configs: get: consumes: - application/json description: Lists all trending configs with pagination parameters: - default: 1 description: Page number in: query name: page type: integer - default: 20 description: Page size in: query maximum: 100 name: page_size type: integer produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: type: object type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: List trending algorithm configurations tags: - Admin - Featuring post: consumes: - application/json description: Creates a new trending algorithm configuration with custom weights and thresholds parameters: - description: Trending config data in: body name: request required: true schema: $ref: '#/definitions/github_com_shoppie_backend_internal_handlers_featuring.CreateTrendingConfigRequest' produces: - application/json responses: "201": description: Created schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: type: object type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Create a new trending algorithm configuration tags: - Admin - Featuring /admin/featuring/trending-configs/{id}/activate: post: consumes: - application/json description: Activates a trending config (deactivates all others atomically) parameters: - description: Config ID format: uuid in: path name: id required: true type: string - description: Activation reason in: body name: request required: true schema: $ref: '#/definitions/github_com_shoppie_backend_internal_handlers_featuring.ActivateTrendingConfigRequest' produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: type: object type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' "409": description: Conflict schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Activate a trending algorithm configuration tags: - Admin - Featuring /admin/images/{id}/status: get: consumes: - application/json description: Get the processing status of any uploaded image. Bypasses user ownership checks. parameters: - description: Image ID in: path name: id required: true type: string produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/image.ImageStatusResponse' type: object "400": description: Invalid image ID schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "404": description: Image not found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal server error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Get image upload status (admin) tags: - Images /admin/notifications/analytics: get: consumes: - application/json description: Retrieves notification analytics for the admin dashboard parameters: - default: 30d description: Time period (24h, 7d, 30d, 90d) in: query name: period type: string produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/notification.AnalyticsResponseDTO' type: object "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Get notification analytics tags: - admin-notifications /admin/notifications/broadcast: post: consumes: - application/json description: Sends a notification to all users or a specific segment parameters: - description: Broadcast details in: body name: request required: true schema: $ref: '#/definitions/notification.BroadcastRequestDTO' produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/notification.BroadcastResponseDTO' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Send a broadcast notification tags: - admin-notifications /admin/notifications/broadcast/draft: post: consumes: - application/json description: Saves a broadcast notification as a draft for later editing parameters: - description: Draft details in: body name: request required: true schema: $ref: '#/definitions/notification.SaveDraftBroadcastRequestDTO' produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/notification.SaveDraftBroadcastResponseDTO' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Save a broadcast as draft tags: - admin-notifications /admin/notifications/broadcast/drafts: get: consumes: - application/json description: Retrieves all draft broadcasts for the admin parameters: - description: 'Page number (default: 1)' in: query name: page type: integer - description: 'Page size (default: 20, max: 100)' in: query name: page_size type: integer produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/notification.ListDraftBroadcastsResponseDTO' type: object "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: List draft broadcasts tags: - admin-notifications /admin/notifications/broadcast/schedule: post: consumes: - application/json description: Schedules a broadcast notification to be sent at a future time parameters: - description: Schedule details in: body name: request required: true schema: $ref: '#/definitions/notification.ScheduleBroadcastRequestDTO' produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/notification.ScheduleBroadcastResponseDTO' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Schedule a broadcast for later tags: - admin-notifications /admin/notifications/history: get: consumes: - application/json description: Retrieves a paginated list of past broadcast notifications parameters: - description: 'Page number (default: 1)' in: query name: page type: integer - description: 'Page size (default: 20, max: 100)' in: query name: page_size type: integer produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/notification.BroadcastHistoryResponseDTO' type: object "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Get broadcast history tags: - admin-notifications /admin/notifications/stats: get: consumes: - application/json description: Retrieves overall notification system statistics (placeholder) produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/notification.NotificationStatsResponseDTO' type: object "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Get notification statistics tags: - admin-notifications /admin/notifications/templates: get: consumes: - application/json description: Retrieves a paginated list of notification templates parameters: - description: 'Page number (default: 1)' in: query name: page type: integer - description: 'Page size (default: 20, max: 100)' in: query name: page_size type: integer - description: Only return active templates in: query name: active_only type: boolean produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/notification.ListTemplatesResponseDTO' type: object "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: List notification templates tags: - admin-notifications post: consumes: - application/json description: Creates a new notification template parameters: - description: Template details in: body name: request required: true schema: $ref: '#/definitions/notification.CreateTemplateRequestDTO' produces: - application/json responses: "201": description: Created schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/notification.TemplateResponseDTO' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "409": description: Conflict schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Create a notification template tags: - admin-notifications /admin/notifications/templates/{id}: delete: consumes: - application/json description: Deletes a notification template parameters: - description: Template ID (UUID) in: path name: id required: true type: string produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/notification.MarkReadResponseDTO' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Delete a notification template tags: - admin-notifications get: consumes: - application/json description: Retrieves a notification template by ID parameters: - description: Template ID (UUID) in: path name: id required: true type: string produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/notification.TemplateResponseDTO' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Get a notification template tags: - admin-notifications put: consumes: - application/json description: Updates an existing notification template parameters: - description: Template ID (UUID) in: path name: id required: true type: string - description: Template updates in: body name: request required: true schema: $ref: '#/definitions/notification.UpdateTemplateRequestDTO' produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/notification.TemplateResponseDTO' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' "409": description: Conflict schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Update a notification template tags: - admin-notifications /admin/promotions: get: description: List all promotions with filters (admin only) parameters: - default: 1 description: Page number in: query name: page type: integer - default: 20 description: Items per page in: query name: limit type: integer - description: Filter by status (comma-separated) in: query name: status type: string - description: Filter by discount type (comma-separated) in: query name: discount_type type: string - description: Filter by store ID in: query name: store_id type: string - description: Search in title in: query name: search type: string - description: Filter by start date (RFC3339) in: query name: date_from type: string - description: Filter by end date (RFC3339) in: query name: date_to type: string - description: Filter by requires approval in: query name: requires_approval type: boolean - description: Filter by platform-wide in: query name: is_platform_wide type: boolean - description: Filter by featured in: query name: is_featured type: boolean - description: Filter by minimum usage count in: query name: min_usage type: integer - description: Filter by maximum usage count in: query name: max_usage type: integer - description: Sort by field in: query name: sort_by type: string - description: Sort order in: query name: sort_order type: string produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/promotion.ListPromotionsResponseDTO' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: List all promotions (admin) tags: - admin - promotions /admin/promotions/{id}: get: description: Get detailed information about a specific promotion (admin only) parameters: - description: Promotion ID in: path name: id required: true type: string produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/promotion.PromotionDTO' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Get a promotion (admin) tags: - admin - promotions /admin/promotions/{id}/approve: post: consumes: - application/json description: Approve a pending promotion (admin only) parameters: - description: Promotion ID in: path name: id required: true type: string - description: Approval data in: body name: request required: true schema: $ref: '#/definitions/promotion.AdminApprovePromotionRequestDTO' produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/promotion.PromotionDTO' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Approve a promotion (admin) tags: - admin - promotions /admin/promotions/{id}/disable: post: consumes: - application/json description: Disable a promotion due to fraud or policy violation (admin only) parameters: - description: Promotion ID in: path name: id required: true type: string - description: Disable data in: body name: request required: true schema: $ref: '#/definitions/promotion.AdminDisablePromotionRequestDTO' produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/promotion.PromotionDTO' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Disable a promotion (admin) tags: - admin - promotions /admin/promotions/{id}/pause: post: consumes: - application/json description: Pause an active promotion (admin only) parameters: - description: Promotion ID in: path name: id required: true type: string - description: Pause data in: body name: request schema: $ref: '#/definitions/promotion.AdminPausePromotionRequestDTO' produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/promotion.PromotionDTO' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Pause a promotion (admin) tags: - admin - promotions /admin/promotions/{id}/reject: post: consumes: - application/json description: Reject a pending promotion (admin only) parameters: - description: Promotion ID in: path name: id required: true type: string - description: Rejection data in: body name: request required: true schema: $ref: '#/definitions/promotion.AdminRejectPromotionRequestDTO' produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/promotion.PromotionDTO' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Reject a promotion (admin) tags: - admin - promotions /admin/promotions/{id}/resume: post: consumes: - application/json description: Resume a paused promotion (admin only) parameters: - description: Promotion ID in: path name: id required: true type: string - description: Resume data in: body name: request schema: $ref: '#/definitions/promotion.AdminResumePromotionRequestDTO' produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/promotion.PromotionDTO' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Resume a promotion (admin) tags: - admin - promotions /admin/promotions/{id}/timeline: get: description: Get the activity timeline for a specific promotion (admin only) parameters: - description: Promotion ID in: path name: id required: true type: string - default: 1 description: Page number in: query name: page type: integer - default: 20 description: Items per page in: query name: limit type: integer produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/promotion.TimelineResponseDTO' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Get promotion timeline (admin) tags: - admin - promotions /admin/promotions/analytics: get: description: Get time-series analytics for promotions (admin only) parameters: - default: day description: Aggregation interval enum: - day - week - month in: query name: interval type: string - description: Start date (RFC3339) in: query name: date_from required: true type: string - description: End date (RFC3339) in: query name: date_to required: true type: string - description: Filter by store ID in: query name: store_id type: string produces: - application/json responses: "200": description: OK schema: $ref: '#/definitions/response.StandardResponse' "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Get promotion analytics (admin) tags: - admin - promotions /admin/promotions/bulk: post: consumes: - application/json description: Perform bulk actions on multiple promotions (admin only) parameters: - description: Bulk action data in: body name: request required: true schema: $ref: '#/definitions/promotion.AdminBulkActionRequestDTO' produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/promotion.AdminBulkActionResponseDTO' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Bulk action on promotions (admin) tags: - admin - promotions /admin/promotions/export: get: description: Export promotions to CSV format (admin only) parameters: - description: Filter by status (comma-separated) in: query name: status type: string - description: Filter by discount type (comma-separated) in: query name: discount_type type: string - description: Filter by store ID in: query name: store_id type: string - description: Search in title in: query name: search type: string - description: Filter by start date (RFC3339) in: query name: date_from type: string - description: Filter by end date (RFC3339) in: query name: date_to type: string - description: Filter by requires approval in: query name: requires_approval type: boolean - description: Filter by platform-wide in: query name: is_platform_wide type: boolean - description: Filter by featured in: query name: is_featured type: boolean - default: 1000 description: Maximum records to export in: query name: max_records type: integer produces: - text/csv responses: "200": description: CSV file schema: type: file "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Export promotions to CSV (admin) tags: - admin - promotions /admin/promotions/platform: post: consumes: - application/json description: Create a promotion that applies across all stores (admin only) parameters: - description: Platform promotion data in: body name: request required: true schema: $ref: '#/definitions/promotion.AdminCreatePlatformPromotionRequestDTO' produces: - application/json responses: "201": description: Created schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/promotion.PromotionDTO' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "409": description: Conflict schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Create a platform-wide promotion (admin) tags: - admin - promotions /admin/promotions/statistics: get: description: Get platform-wide promotion statistics (admin only) parameters: - description: Filter by status (comma-separated) in: query name: status type: string - description: Filter by store ID in: query name: store_id type: string - description: Filter by start date (RFC3339) in: query name: date_from type: string - description: Filter by end date (RFC3339) in: query name: date_to type: string produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/promotion.PromotionStatisticsDTO' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Get promotion statistics (admin) tags: - admin - promotions /admin/promotions/top: get: description: Get top performing promotions (admin only) parameters: - default: 10 description: Number of promotions to return in: query name: limit type: integer - default: usage_count description: Sort by metric enum: - usage_count - total_discount - total_revenue in: query name: sort_by type: string - description: Filter by start date (RFC3339) in: query name: date_from type: string - description: Filter by end date (RFC3339) in: query name: date_to type: string produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/promotion.TopPromotionsResponseDTO' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Get top promotions (admin) tags: - admin - promotions /admin/reports: get: description: Admin retrieves list of all reports with comprehensive filters parameters: - description: Filter by status in: query name: status type: string - description: Filter by priority in: query name: priority type: string - description: Filter by category in: query name: category type: string - description: Filter by report type in: query name: report_type type: string - description: Filter by assigned admin ID in: query name: assigned_to type: string - description: Filter unassigned reports only in: query name: unassigned type: boolean - description: Filter escalated reports in: query name: is_escalated type: boolean - description: Filter SLA breached reports in: query name: sla_breached type: boolean - description: Filter by reporter ID in: query name: reporter_id type: string - description: Filter by target owner ID in: query name: target_owner_id type: string - description: Start date (YYYY-MM-DD) in: query name: date_from type: string - description: End date (YYYY-MM-DD) in: query name: date_to type: string - description: Search in title/description in: query name: search type: string - description: Page number in: query name: page type: integer - description: Items per page in: query name: limit type: integer produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: items: $ref: '#/definitions/report.ReportResponse' type: array type: object "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: List all reports (Admin) tags: - Reports - Admin /admin/reports/{reportId}: get: description: Admin retrieves full details of a report including internal notes and all comments parameters: - description: Report ID in: path name: reportId required: true type: string produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/report.AdminReportDetailResponse' type: object "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Get report details (Admin) tags: - Reports - Admin /admin/reports/{reportId}/assign: post: consumes: - application/json description: Admin assigns a report to themselves or another admin parameters: - description: Report ID in: path name: reportId required: true type: string - description: Assign request in: body name: request required: true schema: $ref: '#/definitions/report.AdminAssignRequest' produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/report.ReportResponse' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Assign report to admin tags: - Reports - Admin /admin/reports/{reportId}/duplicate: post: consumes: - application/json description: Admin marks a report as duplicate of another report parameters: - description: Report ID in: path name: reportId required: true type: string - description: Mark duplicate request in: body name: request required: true schema: $ref: '#/definitions/report.AdminMarkDuplicateRequestDTO' produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/report.ReportResponse' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Mark report as duplicate tags: - Reports - Admin /admin/reports/{reportId}/escalate: post: consumes: - application/json description: Admin escalates a report for senior review parameters: - description: Report ID in: path name: reportId required: true type: string - description: Escalate request in: body name: request required: true schema: $ref: '#/definitions/report.AdminEscalateRequest' produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/report.ReportResponse' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Escalate a report tags: - Reports - Admin /admin/reports/{reportId}/priority: put: consumes: - application/json description: Admin updates the priority of a report parameters: - description: Report ID in: path name: reportId required: true type: string - description: Update priority request in: body name: request required: true schema: $ref: '#/definitions/report.AdminUpdatePriorityRequestDTO' produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/report.ReportResponse' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Update report priority tags: - Reports - Admin /admin/reports/{reportId}/reject: post: consumes: - application/json description: Admin rejects a report (no violation found) parameters: - description: Report ID in: path name: reportId required: true type: string - description: Reject request in: body name: request required: true schema: $ref: '#/definitions/report.AdminRejectRequest' produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/report.ReportResponse' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Reject a report tags: - Reports - Admin /admin/reports/{reportId}/resolve: post: consumes: - application/json description: Admin resolves a report with a specific action parameters: - description: Report ID in: path name: reportId required: true type: string - description: Resolve request in: body name: request required: true schema: $ref: '#/definitions/report.AdminResolveRequest' produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/report.ReportResponse' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Resolve a report tags: - Reports - Admin /admin/reports/bulk-assign: post: consumes: - application/json description: Admin bulk assigns multiple reports to an admin parameters: - description: Bulk assign request in: body name: request required: true schema: $ref: '#/definitions/report.AdminBulkAssignRequestDTO' produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/report.BulkAssignResponse' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Bulk assign reports tags: - Reports - Admin /admin/reports/statistics: get: description: Admin retrieves platform-wide report statistics parameters: - description: Filter by report type in: query name: report_type type: string - description: Filter by category in: query name: category type: string - description: Start date (YYYY-MM-DD) in: query name: date_from type: string - description: End date (YYYY-MM-DD) in: query name: date_to type: string produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/report.StatisticsResponse' type: object "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Get report statistics (Admin) tags: - Reports - Admin /admin/reviews: get: parameters: - default: 1 description: Page number in: query name: page type: integer - default: 20 description: Items per page in: query name: limit type: integer - description: Filter by status in: query name: status type: string - description: Minimum rating in: query name: min_rating type: integer - description: Maximum rating in: query name: max_rating type: integer produces: - application/json responses: "200": description: OK schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: List all reviews (admin) tags: - Reviews - Admin /admin/reviews/{id}/activity: get: parameters: - description: Review ID in: path name: id required: true type: string - default: 1 description: Page number in: query name: page type: integer - default: 20 description: Items per page in: query name: limit type: integer produces: - application/json responses: "200": description: OK schema: $ref: '#/definitions/response.StandardResponse' "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Get review activity log tags: - Reviews - Admin /admin/reviews/{id}/approve: post: consumes: - application/json parameters: - description: Review ID in: path name: id required: true type: string - description: Optional notes in: body name: request schema: $ref: '#/definitions/review.AdminModerationDTO' produces: - application/json responses: "200": description: OK schema: $ref: '#/definitions/response.StandardResponse' "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Approve a review tags: - Reviews - Admin /admin/reviews/{id}/flag: post: consumes: - application/json parameters: - description: Review ID in: path name: id required: true type: string - description: Flag reason in: body name: request required: true schema: $ref: '#/definitions/review.AdminFlagDTO' produces: - application/json responses: "200": description: OK schema: $ref: '#/definitions/response.StandardResponse' "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Flag a review for investigation tags: - Reviews - Admin /admin/reviews/{id}/reject: post: consumes: - application/json parameters: - description: Review ID in: path name: id required: true type: string - description: Rejection reason in: body name: request required: true schema: $ref: '#/definitions/review.AdminRejectDTO' produces: - application/json responses: "200": description: OK schema: $ref: '#/definitions/response.StandardResponse' "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Reject a review tags: - Reviews - Admin /admin/reviews/{id}/reply/approve: post: parameters: - description: Review ID in: path name: id required: true type: string produces: - application/json responses: "200": description: OK schema: $ref: '#/definitions/response.StandardResponse' "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Approve a vendor reply tags: - Reviews - Admin /admin/reviews/{id}/reply/reject: post: consumes: - application/json parameters: - description: Review ID in: path name: id required: true type: string - description: Rejection reason in: body name: request required: true schema: $ref: '#/definitions/review.RejectReplyDTO' produces: - application/json responses: "200": description: OK schema: $ref: '#/definitions/response.StandardResponse' "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Reject a vendor reply tags: - Reviews - Admin /admin/reviews/analytics: get: parameters: - description: Start date (YYYY-MM-DD) in: query name: start_date required: true type: string - description: End date (YYYY-MM-DD) in: query name: end_date required: true type: string - default: day description: Granularity (day, week, month) in: query name: granularity type: string produces: - application/json responses: "200": description: OK schema: $ref: '#/definitions/response.StandardResponse' "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Get review analytics tags: - Reviews - Admin /admin/reviews/bulk/approve: post: consumes: - application/json parameters: - description: Review IDs in: body name: request required: true schema: $ref: '#/definitions/review.BulkReviewIDsDTO' produces: - application/json responses: "200": description: OK schema: $ref: '#/definitions/response.StandardResponse' "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Bulk approve reviews tags: - Reviews - Admin /admin/reviews/bulk/delete: post: consumes: - application/json parameters: - description: Review IDs and reason in: body name: request required: true schema: $ref: '#/definitions/review.BulkDeleteDTO' produces: - application/json responses: "200": description: OK schema: $ref: '#/definitions/response.StandardResponse' "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Bulk delete reviews tags: - Reviews - Admin /admin/reviews/bulk/reject: post: consumes: - application/json parameters: - description: Review IDs and reason in: body name: request required: true schema: $ref: '#/definitions/review.BulkRejectDTO' produces: - application/json responses: "200": description: OK schema: $ref: '#/definitions/response.StandardResponse' "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Bulk reject reviews tags: - Reviews - Admin /admin/reviews/flagged: get: parameters: - default: 1 description: Page number in: query name: page type: integer - default: 20 description: Items per page in: query name: limit type: integer produces: - application/json responses: "200": description: OK schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: List flagged reviews for investigation tags: - Reviews - Admin /admin/reviews/pending: get: parameters: - default: 1 description: Page number in: query name: page type: integer - default: 20 description: Items per page in: query name: limit type: integer produces: - application/json responses: "200": description: OK schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: List pending reviews for moderation tags: - Reviews - Admin /admin/reviews/statistics: get: parameters: - description: Start date (YYYY-MM-DD) in: query name: start_date type: string - description: End date (YYYY-MM-DD) in: query name: end_date type: string produces: - application/json responses: "200": description: OK schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Get review statistics tags: - Reviews - Admin /admin/services: get: consumes: - application/json description: List all services across all statuses with extended filters parameters: - description: Page number in: query name: page type: integer - description: Items per page in: query name: limit type: integer - description: Filter by store ID in: query name: store_id type: string - description: Filter by category ID in: query name: category_id type: string - description: Filter by status in: query name: status type: string - description: Filter by location type in: query name: location_type type: string - description: Minimum price in: query name: min_price type: number - description: Maximum price in: query name: max_price type: number - description: Search query in: query name: search type: string - description: Created from (ISO 8601) in: query name: created_from type: string - description: Created to (ISO 8601) in: query name: created_to type: string produces: - application/json responses: "200": description: OK schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: List all services (admin) tags: - admin - services /admin/services/{id}: get: consumes: - application/json description: Get full service detail with admin-only join data parameters: - description: Service ID in: path name: id required: true type: string produces: - application/json responses: "200": description: OK schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Get service detail (admin) tags: - admin - services patch: consumes: - application/json description: Admin can modify any field of a service, requires reason parameters: - description: Service ID in: path name: id required: true type: string - description: Admin edit request in: body name: request required: true schema: $ref: '#/definitions/service.AdminEditServiceRequest' produces: - application/json responses: "200": description: OK schema: $ref: '#/definitions/response.StandardResponse' "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Admin override edit service tags: - admin - services /admin/services/{id}/feature: post: description: Mark a service as featured parameters: - description: Service ID in: path name: id required: true type: string produces: - application/json responses: "200": description: OK schema: $ref: '#/definitions/response.StandardResponse' "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' "409": description: Conflict schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Feature a service (admin) tags: - admin - services /admin/services/{id}/moderation-history: get: consumes: - application/json description: Returns chronological admin actions on a service parameters: - description: Service ID in: path name: id required: true type: string produces: - application/json responses: "200": description: OK schema: $ref: '#/definitions/response.StandardResponse' "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Get service moderation history (admin) tags: - admin - services /admin/services/{id}/relist: post: consumes: - application/json description: Relist an archived or suspended service back to active parameters: - description: Service ID in: path name: id required: true type: string - description: Rellist reason in: body name: request required: true schema: $ref: '#/definitions/service.AdminRelistRequestDTO' produces: - application/json responses: "200": description: OK schema: $ref: '#/definitions/response.StandardResponse' "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Relist a service (admin) tags: - admin - services /admin/services/{id}/suspend: post: consumes: - application/json description: Suspend a service with a reason parameters: - description: Service ID in: path name: id required: true type: string - description: Suspension reason in: body name: request required: true schema: $ref: '#/definitions/service.SuspendRequestDTO' produces: - application/json responses: "200": description: OK schema: $ref: '#/definitions/response.StandardResponse' "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Suspend a service (admin) tags: - admin - services /admin/services/{id}/unfeature: post: description: Remove featured status from a service parameters: - description: Service ID in: path name: id required: true type: string produces: - application/json responses: "200": description: OK schema: $ref: '#/definitions/response.StandardResponse' "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Unfeature a service (admin) tags: - admin - services /admin/services/{id}/unsuspend: post: description: Remove suspension from a service parameters: - description: Service ID in: path name: id required: true type: string produces: - application/json responses: "200": description: OK schema: $ref: '#/definitions/response.StandardResponse' "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Unsuspend a service (admin) tags: - admin - services /admin/services/analytics: get: description: Get time-series analytics for services parameters: - description: Start date (YYYY-MM-DD) in: query name: date_from required: true type: string - description: End date (YYYY-MM-DD) in: query name: date_to required: true type: string - default: day description: Grouping period (day, week, month) in: query name: group_by type: string produces: - application/json responses: "200": description: OK schema: $ref: '#/definitions/response.StandardResponse' "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Get service analytics (admin) tags: - admin - services /admin/services/audit: post: consumes: - application/json description: Returns all services for a provider with booking, revenue, and rating stats parameters: - description: Provider ID in: body name: request required: true schema: $ref: '#/definitions/service.AdminAuditProviderRequestDTO' produces: - application/json responses: "200": description: OK schema: $ref: '#/definitions/response.StandardResponse' "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Audit provider services (admin) tags: - admin - services /admin/services/bulk/delete: post: consumes: - application/json description: Soft delete multiple services at once parameters: - description: Bulk delete request in: body name: request required: true schema: $ref: '#/definitions/service.BulkDeleteRequestDTO' produces: - application/json responses: "200": description: OK schema: $ref: '#/definitions/response.StandardResponse' "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Bulk soft delete services (admin) tags: - admin - services /admin/services/bulk/status: post: consumes: - application/json description: Update the status of multiple services at once parameters: - description: Bulk update request in: body name: request required: true schema: $ref: '#/definitions/service.BulkUpdateStatusRequestDTO' produces: - application/json responses: "200": description: OK schema: $ref: '#/definitions/response.StandardResponse' "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Bulk update service status (admin) tags: - admin - services /admin/services/moderation: get: description: Get services that need moderation review, sorted by status priority parameters: - default: 1 description: Page number in: query name: page type: integer - default: 20 description: Items per page in: query name: page_size type: integer produces: - application/json responses: "200": description: OK schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Get services for moderation (admin) tags: - admin - services /admin/services/statistics: get: description: Get comprehensive statistics for all services produces: - application/json responses: "200": description: OK schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Get platform-wide service statistics (admin) tags: - admin - services /admin/stores: get: description: Admin list all stores with search and filters (suspended, verified, closed, owner) parameters: - description: Filter by owner ID in: query name: owner_id type: string - description: Filter by suspended status in: query name: is_suspended type: boolean - description: Filter by verified status in: query name: is_verified type: boolean - description: Filter by closed status in: query name: is_closed type: boolean - description: Search query in: query name: search type: string - default: 1 description: Page number in: query name: page type: integer - default: 20 description: Items per page in: query name: limit type: integer produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: items: $ref: '#/definitions/store.StoreDTO' type: array type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: List all stores (admin) tags: - admin - stores /admin/stores/{id}: get: description: Get store detail with owner info (admin) parameters: - description: Store ID in: path name: id required: true type: string produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/store.StoreDTO' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Get store detail (admin) tags: - admin - stores put: consumes: - application/json description: Update store details as admin parameters: - description: Store ID in: path name: id required: true type: string - description: Store update data in: body name: request required: true schema: $ref: '#/definitions/store.AdminUpdateStoreRequestDTO' produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/store.StoreDTO' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Update store (admin) tags: - admin - stores /admin/stores/{id}/activities: get: description: Get activity/audit log for a specific store (admin only) parameters: - description: Store ID in: path name: id required: true type: string - default: 1 description: Page number in: query name: page type: integer - default: 20 description: Items per page in: query name: limit type: integer produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/store.StoreActivitiesResponseDTO' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Get store activities (admin) tags: - admin - stores /admin/stores/{id}/suspend: post: consumes: - application/json description: Suspend store with reason (admin) parameters: - description: Store ID in: path name: id required: true type: string - description: Suspension data in: body name: request required: true schema: $ref: '#/definitions/store.AdminSuspendStoreRequestDTO' produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/store.StoreDTO' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Suspend store (admin) tags: - admin - stores /admin/stores/{id}/unsuspend: post: description: Remove suspension from store (admin) parameters: - description: Store ID in: path name: id required: true type: string produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/store.StoreDTO' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Unsuspend store (admin) tags: - admin - stores /admin/stores/{id}/unverify: post: consumes: - application/json description: Remove verification status from a store (admin only) parameters: - description: Store ID in: path name: id required: true type: string - description: Unverification data in: body name: request required: true schema: $ref: '#/definitions/store.AdminUnverifyStoreRequestDTO' produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/store.StoreDTO' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Unverify store (admin) tags: - admin - stores /admin/stores/{id}/verify: post: consumes: - application/json description: Mark a store as verified (admin only) parameters: - description: Store ID in: path name: id required: true type: string - description: Verification data in: body name: request required: true schema: $ref: '#/definitions/store.AdminVerifyStoreRequestDTO' produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/store.StoreDTO' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Verify store (admin) tags: - admin - stores /admin/stores/analytics: get: description: Get time-series analytics data for admin dashboard (admin only) parameters: - description: Start date (YYYY-MM-DD) example: '"2024-01-01"' in: query name: start_date required: true type: string - description: End date (YYYY-MM-DD) example: '"2024-01-31"' in: query name: end_date required: true type: string - default: day description: Data interval (day, week, month) in: query name: interval type: string produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/store.StoreAnalyticsResponseDTO' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Get store analytics (admin) tags: - admin - stores /admin/stores/bulk/verify: post: consumes: - application/json description: |- Verify multiple stores at once (admin only, max 100 stores). For small operations (≤20 stores), processing is synchronous unless async=true. For large operations (>20 stores), processing is always async (returns 202 Accepted). parameters: - description: Bulk verification data in: body name: request required: true schema: $ref: '#/definitions/store.BulkVerifyStoresRequestDTO' produces: - application/json responses: "200": description: Sync processing completed schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/store.BulkOperationResponseDTO' type: object "202": description: Async processing queued schema: $ref: '#/definitions/store.StoreBulkActionJobResponse' "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' "503": description: Queue unavailable for async processing schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Bulk verify stores (admin) tags: - admin - stores /admin/stores/statistics: get: description: Get aggregated store statistics for admin dashboard (admin only) produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/store.StoreStatisticsDTO' type: object "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Get store statistics (admin) tags: - admin - stores /admin/users: get: consumes: - application/json description: Retrieves paginated list of users with filters. Results are cached for 45 seconds. parameters: - description: 'Page number (default: 1)' in: query minimum: 1 name: page type: integer - description: 'Items per page (default: 20, max: 100)' in: query maximum: 100 minimum: 1 name: per_page type: integer - description: Filter by role enum: - student - vendor - admin in: query name: role type: string - description: Filter by banned status in: query name: banned type: boolean - description: Search in name, username, email in: query maxLength: 100 name: search type: string produces: - application/json responses: "200": description: Paginated user list schema: $ref: '#/definitions/response.StandardResponse' "400": description: Bad request - invalid parameters schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized - invalid or missing token schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden - admin role required schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal server error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: List users with filters and pagination tags: - Admin - Users post: consumes: - application/json description: Allows admin to create a new user account with specified role. Only super_admin can create admin users. parameters: - description: User creation details in: body name: request required: true schema: $ref: '#/definitions/admin.CreateUserRequest' produces: - application/json responses: "201": description: User created successfully schema: $ref: '#/definitions/response.StandardResponse' "400": description: Bad request - validation error schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized - invalid or missing token schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden - insufficient privileges schema: $ref: '#/definitions/response.StandardResponse' "409": description: Conflict - email already exists schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal server error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Create a new user by admin tags: - Admin - Users /admin/users/{id}: delete: consumes: - application/json description: Soft deletes a user account (sets deleted_at timestamp). Invalidates all user sessions. parameters: - description: User ID format: uuid in: path name: id required: true type: string - description: Deletion details in: body name: request required: true schema: $ref: '#/definitions/admin.DeleteUserRequest' produces: - application/json responses: "200": description: User deleted successfully schema: $ref: '#/definitions/response.StandardResponse' "400": description: Bad request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized - invalid or missing token schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden - cannot delete this user schema: $ref: '#/definitions/response.StandardResponse' "404": description: User not found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal server error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Soft delete a user account tags: - Admin - Users get: consumes: - application/json description: Retrieves detailed user information with caching (2-5 minutes TTL) parameters: - description: User ID format: uuid in: path name: id required: true type: string produces: - application/json responses: "200": description: User details schema: $ref: '#/definitions/response.StandardResponse' "400": description: Bad request - invalid user ID schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized - invalid or missing token schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden - admin role required schema: $ref: '#/definitions/response.StandardResponse' "404": description: User not found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal server error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Get user details by ID tags: - Admin - Users patch: consumes: - application/json description: 'Updates user information including role changes. Role promotion/demotion rules: only super_admin can promote to admin/super_admin, admin/super_admin can promote to moderator. Only super_admin can demote admin/moderator.' parameters: - description: User ID format: uuid in: path name: id required: true type: string - description: User update data in: body name: request required: true schema: $ref: '#/definitions/admin.UpdateUserRequest' produces: - application/json responses: "200": description: User updated successfully schema: $ref: '#/definitions/response.StandardResponse' "400": description: Bad request - invalid input, invalid role, or email already exists schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized - invalid or missing token schema: $ref: '#/definitions/response.StandardResponse' "403": description: 'Forbidden - role restrictions: only super_admin can promote to admin/super_admin; only admin/super_admin can promote to moderator; only super_admin can demote admin/moderator; cannot modify users with higher privileges; cannot update yourself' schema: $ref: '#/definitions/response.StandardResponse' "404": description: User not found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal server error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Update user details tags: - Admin - Users /admin/users/{id}/activity: get: consumes: - application/json description: Retrieves user activity history with caching (2 minutes TTL). Activity log rarely changes so safe to cache. parameters: - description: User ID format: uuid in: path name: id required: true type: string produces: - application/json responses: "200": description: User activity logs schema: $ref: '#/definitions/response.StandardResponse' "400": description: Bad request - invalid user ID schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized - invalid or missing token schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden - admin role required schema: $ref: '#/definitions/response.StandardResponse' "404": description: User not found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal server error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Get user activity logs tags: - Admin - Users /admin/users/{id}/ban: post: consumes: - application/json description: 'Bans a user with specified reason and optional duration. Invalidates all user-related caches. Role restrictions apply: super_admin can ban anyone except other super_admins, admin/moderator can only ban customers and vendors.' parameters: - description: User ID format: uuid in: path name: id required: true type: string - description: Ban details in: body name: request required: true schema: $ref: '#/definitions/admin.BanUserRequest' produces: - application/json responses: "200": description: User banned successfully schema: $ref: '#/definitions/response.StandardResponse' "400": description: Bad request - invalid user ID, reason too short/long, or user already banned schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized - invalid or missing token schema: $ref: '#/definitions/response.StandardResponse' "403": description: 'Forbidden - cannot ban: admin/super_admin (only super_admin can), moderator (only super_admin can), yourself, or insufficient privileges' schema: $ref: '#/definitions/response.StandardResponse' "404": description: User not found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal server error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Ban a user account tags: - Admin - Users /admin/users/{id}/impersonate: post: consumes: - application/json description: Allows admin to impersonate a user for troubleshooting. Security-sensitive operation with audit logging. parameters: - description: User ID to impersonate format: uuid in: path name: id required: true type: string - description: Impersonation details in: body name: request required: true schema: $ref: '#/definitions/admin.ImpersonateRequest' produces: - application/json responses: "200": description: Impersonation token created schema: $ref: '#/definitions/response.StandardResponse' "400": description: Bad request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized - invalid or missing token schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden - admin role required or cannot impersonate admin schema: $ref: '#/definitions/response.StandardResponse' "404": description: User not found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal server error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Impersonate a user account tags: - Admin - Users /admin/users/{id}/reset-password: post: consumes: - application/json description: Allows admin to reset a user's password for security reasons. Security action - no cache. parameters: - description: User ID format: uuid in: path name: id required: true type: string - description: Password reset details in: body name: request required: true schema: $ref: '#/definitions/admin.ResetPasswordRequest' produces: - application/json responses: "200": description: Password reset successfully schema: $ref: '#/definitions/response.StandardResponse' "400": description: Bad request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized - invalid or missing token schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden - admin role required or cannot reset admin password schema: $ref: '#/definitions/response.StandardResponse' "404": description: User not found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal server error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Reset a user's password tags: - Admin - Users /admin/users/{id}/sessions: delete: consumes: - application/json description: Revokes (invalidates) all active sessions for a user, forcing them to re-authenticate on all devices. parameters: - description: User ID format: uuid in: path name: id required: true type: string - description: Optional reason for revocation in: body name: request schema: $ref: '#/definitions/admin.RevokeAllSessionsRequest' produces: - application/json responses: "200": description: All sessions revoked successfully schema: $ref: '#/definitions/response.StandardResponse' "400": description: Bad request - invalid user ID schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized - invalid or missing token schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden - cannot revoke this user's sessions schema: $ref: '#/definitions/response.StandardResponse' "404": description: User not found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal server error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Revoke all user sessions tags: - Admin - Users get: consumes: - application/json description: Retrieves user's active sessions with caching (60 seconds TTL). Sessions change slowly so safe to cache. parameters: - description: User ID format: uuid in: path name: id required: true type: string produces: - application/json responses: "200": description: User active sessions schema: $ref: '#/definitions/response.StandardResponse' "400": description: Bad request - invalid user ID schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized - invalid or missing token schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden - admin role required schema: $ref: '#/definitions/response.StandardResponse' "404": description: User not found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal server error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Get user active sessions tags: - Admin - Users /admin/users/{id}/sessions/{session_id}: delete: consumes: - application/json description: Revokes (deletes) a specific session for a user, forcing them to re-authenticate on that device. parameters: - description: User ID format: uuid in: path name: id required: true type: string - description: Session ID format: uuid in: path name: session_id required: true type: string - description: Optional reason for revocation in: body name: request schema: $ref: '#/definitions/admin.RevokeSessionRequest' produces: - application/json responses: "200": description: Session revoked successfully schema: $ref: '#/definitions/response.StandardResponse' "400": description: Bad request - invalid IDs schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized - invalid or missing token schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden - cannot revoke this user's sessions schema: $ref: '#/definitions/response.StandardResponse' "404": description: User or session not found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal server error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Revoke a specific user session tags: - Admin - Users /admin/users/{id}/unban: post: consumes: - application/json description: 'Removes ban from a user account and invalidates user-related caches. Role restrictions: if user was banned by super_admin, only super_admin can unban. Admin can unban users banned by admin or moderator. Moderator can only unban users they banned.' parameters: - description: User ID format: uuid in: path name: id required: true type: string produces: - application/json responses: "200": description: User unbanned successfully schema: additionalProperties: true type: object "400": description: Bad request - invalid user ID or user not banned schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized - invalid or missing token schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden - only super_admin can unban users banned by super_admin, or insufficient privileges schema: $ref: '#/definitions/response.StandardResponse' "404": description: User not found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal server error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Remove ban from a user account tags: - Admin - Users /admin/users/{id}/verify-email: post: consumes: - application/json description: Allows admin to manually mark a user's email as verified. Changes user state - real-time operation. parameters: - description: User ID format: uuid in: path name: id required: true type: string produces: - application/json responses: "200": description: Email verified successfully schema: $ref: '#/definitions/response.StandardResponse' "400": description: Bad request - invalid user ID or email already verified schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized - invalid or missing token schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden - admin role required schema: $ref: '#/definitions/response.StandardResponse' "404": description: User not found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal server error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Manually verify a user's email tags: - Admin - Users /admin/users/{id}/warn: post: consumes: - application/json description: Sends a warning to a user with specified reason and severity, triggers email notification parameters: - description: User ID format: uuid in: path name: id required: true type: string - description: Warning details in: body name: request required: true schema: $ref: '#/definitions/admin.WarnUserRequest' produces: - application/json responses: "200": description: User warned successfully schema: $ref: '#/definitions/response.StandardResponse' "400": description: Bad request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized - invalid or missing token schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden - admin role required schema: $ref: '#/definitions/response.StandardResponse' "404": description: User not found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal server error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Warn a user and send notification email tags: - Admin - Users /admin/users/{id}/warnings: get: consumes: - application/json description: Retrieves all warnings issued to a user with summary statistics. parameters: - description: User ID format: uuid in: path name: id required: true type: string produces: - application/json responses: "200": description: User warnings schema: $ref: '#/definitions/response.StandardResponse' "400": description: Bad request - invalid user ID schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized - invalid or missing token schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden - admin role required schema: $ref: '#/definitions/response.StandardResponse' "404": description: User not found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal server error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: List user warnings tags: - Admin - Users /admin/users/bulk-action: post: consumes: - application/json description: |- Performs bulk actions like ban, unban, verify email, or delete on multiple users. For small operations (≤20 users), processing is synchronous unless async=true. For large operations (>20 users), processing is always async (returns 202 Accepted). parameters: - description: Bulk action details in: body name: request required: true schema: $ref: '#/definitions/admin.BulkActionRequest' produces: - application/json responses: "200": description: Bulk action completed (sync mode) schema: $ref: '#/definitions/response.StandardResponse' "202": description: Bulk action queued (async mode) schema: $ref: '#/definitions/admin.BulkActionJobResponse' "400": description: Bad request - invalid request body or too many users schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized - invalid or missing token schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden - admin role required schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal server error schema: $ref: '#/definitions/response.StandardResponse' "503": description: Queue unavailable - async processing not available schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Perform bulk operations on multiple users tags: - Admin - Users /admin/users/export: get: consumes: - application/json description: Exports user data in specified format (CSV, JSON, XLSX). One-off export - no benefit caching. parameters: - default: csv description: Export format enum: - csv - json - xlsx in: query name: format type: string - description: Filter by role enum: - student - vendor - admin in: query name: role type: string - description: Filter by banned status in: query name: banned type: boolean produces: - application/octet-stream responses: "200": description: Exported user data file schema: type: file "400": description: Bad request - invalid parameters schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized - invalid or missing token schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden - admin role required schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal server error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Export user data tags: - Admin - Users /admin/users/impersonate/end: post: consumes: - application/json description: Ends an active impersonation session. Only the admin who started the session can end it. parameters: - description: Session ID to end in: body name: request required: true schema: $ref: '#/definitions/admin.EndImpersonateRequest' produces: - application/json responses: "200": description: Impersonation session ended schema: $ref: '#/definitions/response.StandardResponse' "400": description: Bad request - invalid session ID schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized - invalid or missing token schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden - can only end your own sessions schema: $ref: '#/definitions/response.StandardResponse' "404": description: Session not found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal server error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: End an impersonation session tags: - Admin - Users /admin/users/search: get: consumes: - application/json description: Performs full-text search on users with caching. Supports trigram search on name/username/email with filters for campus, role, banned status, etc. parameters: - description: Search query for name, username, or email in: query maxLength: 100 name: q type: string - description: Filter by role enum: - student - vendor - admin in: query name: role type: string - description: Filter by banned status in: query name: banned type: boolean - description: Filter by email verification status in: query name: email_verified type: boolean - description: 'Page number (default: 1)' in: query minimum: 1 name: page type: integer - description: 'Items per page (default: 20, max: 100)' in: query maximum: 100 minimum: 1 name: per_page type: integer produces: - application/json responses: "200": description: Search results with pagination schema: $ref: '#/definitions/response.StandardResponse' "400": description: Bad request - invalid parameters schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized - invalid or missing token schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden - admin role required schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal server error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Search users with full-text search and filters tags: - Admin - Users /admin/users/stats: get: consumes: - application/json description: Retrieves aggregate user statistics including totals, registrations, and ban statistics. Cached for 5 minutes. produces: - application/json responses: "200": description: User statistics schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized - invalid or missing token schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden - admin role required schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal server error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Get user statistics dashboard tags: - Admin - Users /api/v1/search/counts: get: description: Returns the total match count for products, stores, and services for a single query in one round-trip, used to populate search tab badges parameters: - description: Search query in: query name: q required: true type: string produces: - application/json responses: "200": description: OK schema: $ref: '#/definitions/response.StandardResponse' "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' summary: Result counts across all indices tags: - Search /api/v1/search/health: get: description: Reports whether the search service (Meilisearch) is reachable and healthy produces: - application/json responses: "200": description: OK schema: $ref: '#/definitions/response.StandardResponse' "503": description: Service Unavailable schema: $ref: '#/definitions/response.StandardResponse' summary: Search service health check tags: - Search /api/v1/search/products: get: consumes: - application/json description: Search the products index with faceting, filtering, and sorting support parameters: - description: Search query in: query name: q required: true type: string - description: Filter by category in: query name: category type: string - description: Filter by brand in: query name: brand type: string - description: Filter by condition in: query name: condition type: string - description: Minimum price filter in: query name: min_price type: number - description: Maximum price filter in: query name: max_price type: number - description: Sort order enum: - relevance - price_asc - price_desc - newest - rating in: query name: sort type: string - description: 'Page number (default: 1)' in: query name: page type: integer - description: 'Results per page (default: 20, max: 100)' in: query name: limit type: integer produces: - application/json responses: "200": description: OK schema: $ref: '#/definitions/response.StandardResponse' "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' summary: Search for products tags: - Search /api/v1/search/services: get: consumes: - application/json description: Search services with faceting and filtering support parameters: - description: Search query in: query name: q required: true type: string - description: Filter by service type in: query name: service_type type: string - description: Filter by availability in: query name: availability type: string - description: Minimum price filter in: query name: min_price type: number - description: Maximum price filter in: query name: max_price type: number - description: Filter by provider ID in: query name: provider_id type: string - description: Sort order enum: - relevance - price_asc - price_desc - newest - rating in: query name: sort type: string - description: 'Page number (default: 1)' in: query name: page type: integer - description: 'Results per page (default: 20, max: 100)' in: query name: limit type: integer produces: - application/json responses: "200": description: OK schema: $ref: '#/definitions/response.StandardResponse' "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' summary: Search for services tags: - Search /api/v1/search/stores: get: consumes: - application/json description: Search stores/suppliers with faceting and filtering support parameters: - description: Search query in: query name: q required: true type: string - description: Filter by verification status in: query name: verified type: boolean - description: Filter by country in: query name: country type: string - description: Minimum rating filter in: query name: min_rating type: number - description: Sort order (price tokens fall back to relevance for stores) enum: - relevance - newest - rating in: query name: sort type: string - description: 'Page number (default: 1)' in: query name: page type: integer - description: 'Results per page (default: 20, max: 100)' in: query name: limit type: integer produces: - application/json responses: "200": description: OK schema: $ref: '#/definitions/response.StandardResponse' "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' summary: Search for stores tags: - Search /api/v1/search/suggestions: get: consumes: - application/json description: Returns autocomplete suggestions as user types, with prefix matching and popularity ranking parameters: - description: Partial search query (e.g., 'iph' for 'iphone') in: query name: q required: true type: string - description: Index type enum: - products - stores - services in: query name: type required: true type: string - description: 'Max suggestions (default: 5, max: 10)' in: query name: limit type: integer produces: - application/json responses: "200": description: OK schema: $ref: '#/definitions/response.StandardResponse' "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' summary: Get search suggestions/autocomplete tags: - Search /api/v1/search/trending: get: consumes: - application/json description: Returns top search queries ranked by popularity from Redis sorted set parameters: - default: products description: Index type enum: - products - stores - services in: query name: type type: string - description: 'Max results (default: 10, max: 50)' in: query name: limit type: integer produces: - application/json responses: "200": description: OK schema: $ref: '#/definitions/response.StandardResponse' "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' summary: Get trending searches tags: - Search /bookings: post: consumes: - application/json description: Create a booking for a service parameters: - description: Booking details in: body name: request required: true schema: $ref: '#/definitions/booking.CreateBookingRequestDTO' produces: - application/json responses: "201": description: Created schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/booking.CreateBookingResponseDTO' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "409": description: Conflict schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Create a new booking tags: - Bookings /bookings/{id}: get: consumes: - application/json description: Get booking details by ID parameters: - description: Booking ID in: path name: id required: true type: string produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/booking.BookingResponseDTO' type: object "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Get booking by ID tags: - Bookings /bookings/{id}/cancel: post: consumes: - application/json description: Cancel a booking with refund calculation based on cancellation policy parameters: - description: Booking ID in: path name: id required: true type: string - description: Cancellation reason in: body name: request schema: $ref: '#/definitions/booking.CancelBookingRequestDTO' produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/booking.CancelBookingResponseDTO' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Cancel a booking tags: - Bookings /bookings/{id}/pay: post: consumes: - application/json description: |- Opens the gateway checkout for the customer's own booking. The amount and payment plan are derived server-side from the booking and its tier. parameters: - description: Booking ID in: path name: id required: true type: string - description: Callback URL in: body name: request required: true schema: $ref: '#/definitions/booking.PayBookingRequestDTO' produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/booking.PayBookingResponseDTO' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Pay for a booking tags: - Bookings /bookings/{id}/reschedule: post: consumes: - application/json description: Reschedule a booking to a new date/time (max 2 reschedules allowed) parameters: - description: Booking ID in: path name: id required: true type: string - description: New booking date/time in: body name: request required: true schema: $ref: '#/definitions/booking.RescheduleBookingRequestDTO' produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/booking.BookingResponseDTO' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' "409": description: Conflict schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Reschedule a booking tags: - Bookings /bookings/{id}/review: post: consumes: - application/json description: Add a review to a completed booking (customer only) parameters: - description: Booking ID in: path name: id required: true type: string - description: Review details in: body name: request required: true schema: $ref: '#/definitions/booking.AddReviewRequestDTO' produces: - application/json responses: "201": description: Created schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/booking.ReviewResponseDTO' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' "409": description: Conflict schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Add a review to a booking tags: - Bookings /bookings/availability/{service_id}: get: consumes: - application/json description: Check available time slots for a service on a given date parameters: - description: Service ID in: path name: service_id required: true type: string - description: Date (YYYY-MM-DD) in: query name: date required: true type: string produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/booking.CheckAvailabilityResponseDTO' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' summary: Check service availability tags: - Bookings /bookings/code/{code}: get: consumes: - application/json description: Get booking details by booking code parameters: - description: Booking Code in: path name: code required: true type: string produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/booking.BookingResponseDTO' type: object "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Get booking by code tags: - Bookings /bookings/my: get: consumes: - application/json description: List bookings for the authenticated customer parameters: - description: Filter by status in: query name: status type: string - description: Filter from date (YYYY-MM-DD) in: query name: date_from type: string - description: Filter to date (YYYY-MM-DD) in: query name: date_to type: string - default: 1 description: Page number in: query name: page type: integer - default: 20 description: Page size in: query name: limit type: integer produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: items: $ref: '#/definitions/booking.BookingResponseDTO' type: array type: object "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: List my bookings tags: - Bookings /bookings/reviews/{id}: delete: parameters: - description: Review UUID in: path name: id required: true type: string responses: "200": description: OK schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Delete a booking review tags: - Bookings patch: parameters: - description: Review UUID in: path name: id required: true type: string - description: Fields to update in: body name: request required: true schema: $ref: '#/definitions/booking.UpdateBookingReviewRequest' responses: "200": description: OK schema: $ref: '#/definitions/response.StandardResponse' "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Update a booking review tags: - Bookings /boost/click: post: consumes: - application/json description: Public, best-effort endpoint fired when a Sponsored card is tapped. Per-session/IP rate-limited and deduplicated; no user identity is stored. Returns whether the click was counted (false when deduplicated or rate-limited). parameters: - description: Click in: body name: request required: true schema: $ref: '#/definitions/github_com_shoppie_backend_internal_handlers_boost.RecordClickRequest' produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: type: object type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' summary: Record a click on a sponsored listing tags: - Boost /boost/packages: get: description: Lists only active boost packages available for purchase parameters: - description: Page number in: query name: page type: integer - description: Page size in: query name: limit type: integer produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: type: object type: object "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' summary: List active boost packages tags: - Boost /cart: delete: description: Remove all items from the shopping cart produces: - application/json responses: "200": description: Cart cleared schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/cart.CartResponse' type: object "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "404": description: Cart not found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal server error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Clear cart tags: - Cart get: description: Get the current user's shopping cart produces: - application/json responses: "200": description: Cart retrieved schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/cart.CartResponse' type: object "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "404": description: Cart not found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal server error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Get current cart tags: - Cart /cart/checkout: post: description: Start the checkout process for the current cart produces: - application/json responses: "200": description: Checkout initiated schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/cart.CheckoutSessionResponse' type: object "400": description: Bad request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "404": description: Cart not found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal server error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Initiate checkout tags: - Cart /cart/count: get: description: Get the total item count in the cart (for badge display) produces: - application/json responses: "200": description: Cart count retrieved schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: properties: count: type: integer type: object type: object "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal server error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Get cart item count tags: - Cart /cart/items: post: consumes: - application/json description: Add a product to the shopping cart parameters: - description: Add to cart request in: body name: request required: true schema: $ref: '#/definitions/cart.AddToCartRequestDTO' produces: - application/json responses: "201": description: Item added to cart schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/cart.CartResponse' type: object "400": description: Bad request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal server error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Add item to cart tags: - Cart /cart/items/{itemId}: delete: description: Remove an item from the shopping cart parameters: - description: Cart Item ID in: path name: itemId required: true type: string produces: - application/json responses: "200": description: Item removed from cart schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/cart.CartResponse' type: object "400": description: Bad request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "404": description: Cart item not found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal server error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Remove item from cart tags: - Cart put: consumes: - application/json description: Update the quantity of an item in the cart parameters: - description: Cart Item ID in: path name: itemId required: true type: string - description: Update cart item request in: body name: request required: true schema: $ref: '#/definitions/cart.UpdateCartItemRequestDTO' produces: - application/json responses: "200": description: Cart item updated schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/cart.CartResponse' type: object "400": description: Bad request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "404": description: Cart item not found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal server error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Update cart item quantity tags: - Cart /cart/items/bulk: post: consumes: - application/json description: Add multiple items to cart in one request (from favorites, wishlist, etc.) parameters: - description: Bulk add to cart request in: body name: request required: true schema: $ref: '#/definitions/cart.BulkAddToCartRequestDTO' produces: - application/json responses: "200": description: Items added to cart schema: $ref: '#/definitions/response.StandardResponse' "400": description: Bad request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal server error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Bulk add items to cart tags: - Cart /cart/merge: post: consumes: - application/json description: Merges items from a guest (session-based) cart into the authenticated user's cart. The guest cart is expired after a successful merge. Returns the merged cart with details on items merged and any quantity caps applied. parameters: - description: Guest session ID for the cart to merge in: header name: session_id required: true type: string produces: - application/json responses: "200": description: Guest cart merged schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/cart.MergeGuestCartResponseDTO' type: object "400": description: Bad request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "404": description: Guest cart not found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal server error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Merge guest cart into user cart tags: - Cart /cart/recommendations: get: parameters: - default: 6 description: Number of recommendations (max 12, default 6) in: query name: limit type: integer responses: "200": description: OK schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Get cart-based product recommendations tags: - Cart /cart/validate: get: description: Pre-checkout validation checking product availability, price changes, and stock produces: - application/json responses: "200": description: Cart validation result schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "404": description: Cart not found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal server error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Validate cart for checkout tags: - Cart /categories: get: consumes: - application/json description: List categories with optional filters and pagination parameters: - default: 1 description: Page number in: query name: page type: integer - default: 20 description: Page size in: query maximum: 100 name: page_size type: integer - description: Category type enum: - product - service in: query name: type type: string - description: Parent category ID in: query name: parent_id type: string - description: Filter by active status in: query name: is_active type: boolean - description: Filter by featured status in: query name: is_featured type: boolean - description: Search term in: query name: search type: string - description: Only return root categories in: query name: root_only type: boolean - description: Include child categories in: query name: with_children type: boolean produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: items: $ref: '#/definitions/category.CategoryResponse' type: array type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' summary: List categories tags: - categories /categories/{id}: get: consumes: - application/json description: Get a single category by its ID parameters: - description: Category ID in: path name: id required: true type: string produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/category.CategoryResponse' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' summary: Get category by ID tags: - categories /categories/{id}/breadcrumb: get: consumes: - application/json description: Get the breadcrumb trail for a category (ancestors path) parameters: - description: Category ID in: path name: id required: true type: string produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/category.BreadcrumbResponse' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' summary: Get category breadcrumb tags: - categories /categories/{id}/products/reorder: put: consumes: - application/json description: Reorder products within a category by setting their display order. Only store owner or admin can reorder. parameters: - description: Category ID in: path name: id required: true type: string - description: Reorder request in: body name: request required: true schema: $ref: '#/definitions/product.ReorderProductsRequestDTO' produces: - application/json responses: "200": description: OK schema: $ref: '#/definitions/response.StandardResponse' "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Reorder products within a category tags: - Products /categories/{id}/template: get: description: Returns every non-archived attribute declared anywhere on the category's ancestry, ordered by ancestor depth then position, with values restricted by any narrowing applied along the way parameters: - description: Category ID in: path name: id required: true type: string produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/category.EffectiveTemplateResponse' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' summary: Get a category's effective attribute template tags: - categories /categories/featured: get: consumes: - application/json description: Get a list of featured categories parameters: - description: Category type filter enum: - product - service in: query name: type type: string - default: 10 description: Maximum number of categories in: query maximum: 50 name: limit type: integer produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: items: $ref: '#/definitions/category.CategoryResponse' type: array type: object "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' summary: Get featured categories tags: - categories /categories/nav: get: description: Returns root categories with their immediate children and 9 trending products per root. parameters: - description: Category type filter enum: - product - service in: query name: type type: string produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/category.GetCategoryNavResponse' type: object "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' summary: Get category navigation tree with trending products tags: - categories /categories/select: get: description: Returns categories optimized for the cascading category picker on product creation. parameters: - default: product description: Category type enum: - product - service in: query name: type type: string - description: Parent category UUID — omit to load roots in: query name: parent_id type: string produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/category.GetCategorySelectResponse' type: object "400": description: Invalid parent_id format schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' summary: Get categories for product creation cascade picker tags: - categories /categories/slug/{slug}: get: consumes: - application/json description: Get a single category by its URL-friendly slug parameters: - description: Category slug in: path name: slug required: true type: string produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/category.CategoryResponse' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' summary: Get category by slug tags: - categories /categories/tree: get: consumes: - application/json description: Get the complete category hierarchy as a tree structure parameters: - description: Category type filter enum: - product - service in: query name: type type: string produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/category.CategoryTreeResponseDTO' type: object "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' summary: Get category tree tags: - categories /disputes: get: description: Buyer retrieves list of their disputes with optional filters parameters: - description: Filter by status in: query name: status type: string - description: Page number in: query name: page type: integer - description: Items per page in: query name: limit type: integer produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: items: $ref: '#/definitions/dispute.DisputeResponse' type: array type: object "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: List buyer's disputes tags: - Disputes - Buyer post: consumes: - application/json description: Buyer creates a new dispute for an order parameters: - description: Create dispute request in: body name: request required: true schema: $ref: '#/definitions/dispute.CreateDisputeRequestDTO' produces: - application/json responses: "201": description: Created schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/dispute.DisputeResponse' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "409": description: Conflict schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Create a new dispute tags: - Disputes - Buyer /disputes/{disputeId}: get: description: Buyer retrieves details of their dispute parameters: - description: Dispute ID in: path name: disputeId required: true type: string produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/dispute.DisputeResponse' type: object "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Get dispute details tags: - Disputes - Buyer /disputes/{disputeId}/accept-resolution: post: description: Buyer accepts the proposed resolution for a dispute parameters: - description: Dispute ID in: path name: disputeId required: true type: string produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/dispute.MessageResponseSimple' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Accept proposed resolution tags: - Disputes - Buyer /disputes/{disputeId}/evidence: post: consumes: - application/json description: Buyer submits evidence to support their dispute parameters: - description: Dispute ID in: path name: disputeId required: true type: string - description: Submit evidence request in: body name: request required: true schema: $ref: '#/definitions/dispute.SubmitEvidenceRequestDTO' produces: - application/json responses: "201": description: Created schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/dispute.EvidenceResponse' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Submit evidence for a dispute tags: - Disputes - Buyer /disputes/{disputeId}/evidence/upload-url: post: consumes: - application/json description: Generates a pre-signed URL for uploading evidence to a dispute (buyer or seller) parameters: - description: Dispute ID in: path name: disputeId required: true type: string - description: Upload URL request in: body name: request required: true schema: $ref: '#/definitions/dispute.EvidenceUploadURLRequest' produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/dispute.EvidenceUploadURLResponse' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Generate pre-signed upload URL for dispute evidence tags: - Disputes - Evidence /disputes/{disputeId}/messages: get: description: Retrieve all messages in a dispute conversation parameters: - description: Dispute ID in: path name: disputeId required: true type: string produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: items: $ref: '#/definitions/dispute.MessageResponse' type: array type: object "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Get messages for a dispute tags: - Disputes - Buyer post: consumes: - application/json description: Buyer or seller sends a message in a dispute conversation parameters: - description: Dispute ID in: path name: disputeId required: true type: string - description: Send message request in: body name: request required: true schema: $ref: '#/definitions/dispute.SendMessageRequestDTO' produces: - application/json responses: "201": description: Created schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/dispute.MessageResponse' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Send a message in a dispute tags: - Disputes - Buyer /images/{id}/status: get: consumes: - application/json description: Get the processing status of an uploaded image. Useful for polling after upload. parameters: - description: Image ID in: path name: id required: true type: string produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/image.ImageStatusResponse' type: object "400": description: Invalid image ID schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "404": description: Image not found schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Get image upload status tags: - Images /images/confirm: post: consumes: - application/json description: Called after successfully uploading a file via presigned URL to trigger processing parameters: - description: Upload confirmation data in: body name: request required: true schema: $ref: '#/definitions/image.ConfirmUploadRequestDTO' produces: - application/json responses: "200": description: Upload confirmed and queued for processing schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/image.UploadResponse' type: object "400": description: Invalid request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "404": description: File not found in storage schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal server error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Confirm presigned upload tags: - Images /images/upload-url: post: consumes: - application/json description: Generates a presigned URL for uploading images to stores, categories, products, or users parameters: - description: Upload URL request in: body name: request required: true schema: $ref: '#/definitions/image.GenerateUploadURLRequestDTO' produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/image.GenerateUploadURLResponseDTO' type: object "400": description: Invalid request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Access denied schema: $ref: '#/definitions/response.StandardResponse' "404": description: Entity not found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal server error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Generate presigned upload URL for any entity type tags: - Images /me/reviews: get: parameters: - default: 1 description: Page number in: query name: page type: integer - default: 20 description: Items per page in: query name: limit type: integer produces: - application/json responses: "200": description: OK schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: List current user's reviews tags: - Reviews /notifications/{id}: get: parameters: - description: Notification ID in: path name: id required: true type: string produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/notification.NotificationDetailDTO' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Get a single notification by ID (full detail) tags: - Notifications /products/{id}/like: post: consumes: - application/json description: Like a product (adds to public engagement, not wishlist) parameters: - description: Product ID (UUID) in: path name: id required: true type: string produces: - application/json responses: "200": description: OK schema: $ref: '#/definitions/response.StandardResponse' "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Like a product tags: - Products /products/{id}/rating: get: parameters: - description: Product UUID in: path name: id required: true type: string produces: - application/json responses: "200": description: OK schema: $ref: '#/definitions/response.StandardResponse' summary: Get rating summary for a product tags: - Products /products/{id}/related: get: consumes: - application/json description: Returns related products from other stores based on category parameters: - description: Product ID format: uuid in: path name: id required: true type: string - default: 12 description: Number of related products in: query maximum: 24 name: limit type: integer produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: items: $ref: '#/definitions/product.ProductPublicDTO' type: array type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' summary: Get related products from other stores tags: - Products (Public) /products/{id}/reviews: get: parameters: - description: Product UUID in: path name: id required: true type: string - default: 1 description: Page in: query name: page type: integer - default: 3 description: Page size (max 100) in: query name: page_size type: integer - description: Minimum rating (1-5) in: query name: min_rating type: integer - description: Maximum rating (1-5) in: query name: max_rating type: integer produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/pagination.Response' type: object summary: List reviews for a product tags: - Products /products/{id}/similar: get: consumes: - application/json description: Returns similar products from the same store based on category and price parameters: - description: Product ID format: uuid in: path name: id required: true type: string - default: 10 description: Number of similar products in: query maximum: 20 name: limit type: integer produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: items: $ref: '#/definitions/product.ProductPublicDTO' type: array type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' summary: Get similar products from the same store tags: - Products (Public) /products/{id}/unlike: post: consumes: - application/json description: Remove a like from a product parameters: - description: Product ID (UUID) in: path name: id required: true type: string produces: - application/json responses: "200": description: OK schema: $ref: '#/definitions/response.StandardResponse' "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Unlike a product tags: - Products /products/{productId}/rating: get: parameters: - description: Product ID in: path name: productId required: true type: string produces: - application/json responses: "200": description: OK schema: $ref: '#/definitions/response.StandardResponse' "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' summary: Get rating summary for a product tags: - Reviews /products/{productId}/reviews: get: parameters: - description: Product ID in: path name: productId required: true type: string - default: 1 description: Page number in: query name: page type: integer - default: 20 description: Items per page in: query name: limit type: integer - description: Minimum rating filter in: query name: min_rating type: integer - description: Maximum rating filter in: query name: max_rating type: integer - description: Filter by reviews with photos in: query name: has_photos type: boolean - description: Filter by reviews with vendor reply in: query name: has_vendor_reply type: boolean - description: Filter verified purchases only in: query name: is_verified_only type: boolean - description: Sort field enum: - created_at - rating - helpful_count in: query name: sort_by type: string - description: Sort order enum: - asc - desc in: query name: sort_order type: string produces: - application/json responses: "200": description: OK schema: $ref: '#/definitions/response.StandardResponse' "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' summary: List reviews for a product tags: - Reviews /products/reviews/{id}/helpful: delete: parameters: - description: Review UUID in: path name: id required: true type: string responses: "200": description: OK schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Remove helpful mark from a product review tags: - Products get: parameters: - description: Review UUID in: path name: id required: true type: string responses: "200": description: OK schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Check if the current user has marked a review as helpful tags: - Products post: parameters: - description: Review UUID in: path name: id required: true type: string responses: "200": description: OK schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Mark a product review as helpful tags: - Products /provider/bookings: get: consumes: - application/json description: List bookings for the authenticated provider parameters: - description: Filter by status in: query name: status type: string - description: Filter from date (YYYY-MM-DD) in: query name: date_from type: string - description: Filter to date (YYYY-MM-DD) in: query name: date_to type: string - default: 1 description: Page number in: query name: page type: integer - default: 20 description: Page size in: query name: limit type: integer produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: items: $ref: '#/definitions/booking.BookingResponseDTO' type: array type: object "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: List provider bookings tags: - Provider Bookings /provider/bookings/{id}/complete: post: consumes: - application/json description: Mark a booking as completed (provider only) parameters: - description: Booking ID in: path name: id required: true type: string produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/booking.BookingResponseDTO' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Complete a booking tags: - Provider Bookings /provider/bookings/{id}/confirm: post: consumes: - application/json description: Confirm a pending booking (provider only) parameters: - description: Booking ID in: path name: id required: true type: string produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/booking.BookingResponseDTO' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Confirm a booking tags: - Provider Bookings /provider/bookings/{id}/no-show: post: consumes: - application/json description: Mark a booking as no-show when customer doesn't appear (provider only) parameters: - description: Booking ID in: path name: id required: true type: string produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/booking.BookingResponseDTO' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Mark booking as no-show tags: - Provider Bookings /provider/bookings/{id}/start: post: consumes: - application/json description: Mark a booking as in progress (provider only) parameters: - description: Booking ID in: path name: id required: true type: string produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/booking.BookingResponseDTO' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Start a booking service tags: - Provider Bookings /provider/bookings/stats: get: consumes: - application/json description: Get booking statistics for the authenticated provider parameters: - description: Start date (YYYY-MM-DD) in: query name: date_from type: string - description: End date (YYYY-MM-DD) in: query name: date_to type: string produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/booking.StatsResponseDTO' type: object "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Get provider booking statistics tags: - Provider Bookings /provider/bookings/today: get: consumes: - application/json description: Get all bookings scheduled for today for the authenticated provider produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: items: $ref: '#/definitions/booking.BookingResponseDTO' type: array type: object "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Get today's bookings tags: - Provider Bookings /reports: get: description: User retrieves list of their submitted reports with optional filters parameters: - description: Filter by status in: query name: status type: string - description: Filter by report type in: query name: report_type type: string - description: Page number in: query name: page type: integer - description: Items per page in: query name: limit type: integer produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: items: $ref: '#/definitions/report.ReportResponse' type: array type: object "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: List user's reports tags: - Reports - User post: consumes: - application/json description: User creates a new report for content (product, service, review, user, store) parameters: - description: Create report request in: body name: request required: true schema: $ref: '#/definitions/report.CreateReportRequestDTO' produces: - application/json responses: "201": description: Created schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/report.ReportResponse' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "409": description: Conflict schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Create a new report tags: - Reports - User /reports/{reportId}: get: description: User retrieves details of their report parameters: - description: Report ID in: path name: reportId required: true type: string produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/report.ReportResponse' type: object "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Get report details tags: - Reports - User /reports/{reportId}/comments: post: consumes: - application/json description: User adds a comment to their report parameters: - description: Report ID in: path name: reportId required: true type: string - description: Add comment request in: body name: request required: true schema: $ref: '#/definitions/report.AddCommentRequestDTO' produces: - application/json responses: "201": description: Created schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/report.CommentResponse' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Add a comment to a report tags: - Reports - User /reports/{reportId}/evidence: post: consumes: - application/json description: User adds evidence to their report parameters: - description: Report ID in: path name: reportId required: true type: string - description: Add evidence request in: body name: request required: true schema: $ref: '#/definitions/report.AddEvidenceRequestDTO' produces: - application/json responses: "201": description: Created schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/report.EvidenceResponse' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Add evidence to a report tags: - Reports - User /reports/{reportId}/evidence/upload-url: post: consumes: - application/json description: Generates a pre-signed URL for uploading evidence to a report parameters: - description: Report ID in: path name: reportId required: true type: string - description: Upload URL request in: body name: request required: true schema: $ref: '#/definitions/report.EvidenceUploadURLRequest' produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/report.EvidenceUploadURLResponse' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Generate pre-signed upload URL for report evidence tags: - Reports - User /reviews: post: consumes: - application/json parameters: - description: Review data in: body name: request required: true schema: $ref: '#/definitions/review.SubmitReviewDTO' produces: - application/json responses: "201": description: Created schema: $ref: '#/definitions/response.StandardResponse' "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "409": description: Conflict schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Submit a new review tags: - Reviews /reviews/{id}: delete: parameters: - description: Review ID in: path name: id required: true type: string produces: - application/json responses: "200": description: OK schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Delete a review tags: - Reviews get: parameters: - description: Review ID in: path name: id required: true type: string produces: - application/json responses: "200": description: OK schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' summary: Get a review by ID tags: - Reviews put: consumes: - application/json parameters: - description: Review ID in: path name: id required: true type: string - description: Updated review data in: body name: request required: true schema: $ref: '#/definitions/review.UpdateReviewDTO' produces: - application/json responses: "200": description: OK schema: $ref: '#/definitions/response.StandardResponse' "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Update a review tags: - Reviews /reviews/{id}/helpful: delete: parameters: - description: Review ID in: path name: id required: true type: string produces: - application/json responses: "200": description: OK schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Remove helpful mark from a review tags: - Reviews get: parameters: - description: Review ID in: path name: id required: true type: string produces: - application/json responses: "200": description: OK schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Get helpful status for a review tags: - Reviews post: parameters: - description: Review ID in: path name: id required: true type: string produces: - application/json responses: "200": description: OK schema: $ref: '#/definitions/response.StandardResponse' "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "409": description: Conflict schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Mark a review as helpful tags: - Reviews /seller/disputes: get: description: Seller retrieves list of disputes against their stores parameters: - description: Filter by status in: query name: status type: string - description: Filter by store ID in: query name: store_id type: string - description: Page number in: query name: page type: integer - description: Items per page in: query name: limit type: integer produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: items: $ref: '#/definitions/dispute.DisputeResponse' type: array type: object "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: List seller's disputes tags: - Disputes - Seller /seller/disputes/{disputeId}: get: description: Seller retrieves details of a specific dispute parameters: - description: Dispute ID in: path name: disputeId required: true type: string produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/dispute.DisputeResponse' type: object "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Get seller's dispute details tags: - Disputes - Seller /seller/disputes/{disputeId}/evidence: post: consumes: - application/json description: Seller submits evidence to counter or support their position parameters: - description: Dispute ID in: path name: disputeId required: true type: string - description: Submit evidence request in: body name: request required: true schema: $ref: '#/definitions/dispute.SubmitEvidenceRequestDTO' produces: - application/json responses: "201": description: Created schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/dispute.EvidenceResponse' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Submit seller evidence tags: - Disputes - Seller /seller/disputes/{disputeId}/evidence/upload-url: post: consumes: - application/json description: Generates a pre-signed URL for seller to upload evidence to a dispute parameters: - description: Dispute ID in: path name: disputeId required: true type: string - description: Upload URL request in: body name: request required: true schema: $ref: '#/definitions/dispute.EvidenceUploadURLRequest' produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/dispute.EvidenceUploadURLResponse' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Generate pre-signed upload URL for seller dispute evidence tags: - Disputes - Seller /seller/disputes/{disputeId}/propose-resolution: post: consumes: - application/json description: Seller proposes a resolution to the dispute parameters: - description: Dispute ID in: path name: disputeId required: true type: string - description: Propose resolution request in: body name: request required: true schema: $ref: '#/definitions/dispute.ProposeResolutionRequestDTO' produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/dispute.DisputeResponse' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Propose a resolution tags: - Disputes - Seller /seller/disputes/{disputeId}/respond: post: consumes: - application/json description: Seller provides their initial response to a dispute parameters: - description: Dispute ID in: path name: disputeId required: true type: string - description: Respond to dispute request in: body name: request required: true schema: $ref: '#/definitions/dispute.RespondToDisputeRequestDTO' produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/dispute.DisputeResponse' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Respond to a dispute tags: - Disputes - Seller /seller/disputes/analytics: get: description: Seller retrieves analytics about their dispute history parameters: - description: Filter by store ID in: query name: store_id type: string - description: Start date (YYYY-MM-DD) in: query name: date_from type: string - description: End date (YYYY-MM-DD) in: query name: date_to type: string produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/dispute.SellerAnalyticsResponse' type: object "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Get seller dispute analytics tags: - Disputes - Seller /services/{id}/images/{imageID}: delete: parameters: - description: Service ID in: path name: id required: true type: string - description: Image ID in: path name: imageID required: true type: string produces: - application/json responses: "200": description: OK schema: $ref: '#/definitions/response.StandardResponse' "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Delete a service image tags: - Vendor Services /services/{id}/rating: get: parameters: - description: Service UUID in: path name: id required: true type: string produces: - application/json responses: "200": description: OK schema: $ref: '#/definitions/response.StandardResponse' "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' summary: Get rating stats for a service tags: - Services /services/{id}/related: get: parameters: - description: Service UUID in: path name: id required: true type: string - default: 12 description: Number of results (max 24, default 12) in: query name: limit type: integer produces: - application/json responses: "200": description: OK schema: $ref: '#/definitions/response.StandardResponse' "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' summary: Get related services tags: - Services /services/{id}/reviews: get: parameters: - description: Service UUID in: path name: id required: true type: string - default: 1 description: Page number in: query name: page type: integer - default: 20 description: Results per page (max 100) in: query name: page_size type: integer produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/pagination.Response' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' summary: List reviews for a service tags: - Services /services/{id}/reviews/{reviewId}/helpful: post: parameters: - description: Service UUID in: path name: id required: true type: string - description: Review UUID in: path name: reviewId required: true type: string responses: "200": description: OK schema: $ref: '#/definitions/response.StandardResponse' "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Mark a service review as helpful tags: - Services /services/{id}/upload-url: post: consumes: - application/json parameters: - description: Service ID in: path name: id required: true type: string - description: Upload URL request in: body name: request required: true schema: $ref: '#/definitions/service.GetServiceUploadURLRequest' produces: - application/json responses: "200": description: OK schema: $ref: '#/definitions/response.StandardResponse' "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Generate presigned image upload URL for a service tags: - Vendor Services /stores/{id}/carts/{cartId}/recovery: post: consumes: - application/json description: Send a cart recovery email to the user for a store's abandoned cart parameters: - description: Store ID in: path name: id required: true type: string - description: Cart ID in: path name: cartId required: true type: string produces: - application/json responses: "200": description: Recovery email sent schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/cart.MessageResponse' type: object "400": description: Bad request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: Cart not found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal server error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Send recovery email (store owner) tags: - Cart - Store /stores/{storeId}/carts/abandoned: get: description: Get abandoned carts for a specific store (store owner only) parameters: - description: Store ID in: path name: storeId required: true type: string - description: Minimum cart value in: query name: min_value type: number - description: Date from in: query name: date_from type: string - description: Date to in: query name: date_to type: string - description: Page number in: query name: page type: integer - description: Items per page in: query name: limit type: integer produces: - application/json responses: "200": description: Abandoned carts retrieved schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/cart.CartListResponse' type: object "400": description: Bad request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal server error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Get store abandoned carts tags: - Cart - Store /stores/{storeId}/carts/analytics: get: description: Get cart analytics for a specific store (store owner only) parameters: - description: Store ID in: path name: storeId required: true type: string produces: - application/json responses: "200": description: Store cart analytics retrieved schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/cart.StoreCartAnalyticsResponse' type: object "400": description: Bad request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal server error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Get store cart analytics tags: - Cart - Store /stores/{storeId}/reports: get: description: Store owner retrieves list of reports against their store's content parameters: - description: Store ID in: path name: storeId required: true type: string - description: Filter by status in: query name: status type: string - description: Filter by report type in: query name: report_type type: string - description: Start date (YYYY-MM-DD) in: query name: date_from type: string - description: End date (YYYY-MM-DD) in: query name: date_to type: string - description: Page number in: query name: page type: integer - description: Items per page in: query name: limit type: integer produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: items: $ref: '#/definitions/report.ReportResponse' type: array type: object "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: List reports against store's content tags: - Reports - Store Owner /stores/{storeId}/reports/{reportId}: get: description: Store owner retrieves details of a report against their content parameters: - description: Store ID in: path name: storeId required: true type: string - description: Report ID in: path name: reportId required: true type: string produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/report.ReportResponse' type: object "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Get report details for store owner tags: - Reports - Store Owner /stores/{storeId}/reports/{reportId}/appeal: post: consumes: - application/json description: Store owner appeals a resolved report against their content parameters: - description: Store ID in: path name: storeId required: true type: string - description: Report ID in: path name: reportId required: true type: string - description: Appeal report request in: body name: request required: true schema: $ref: '#/definitions/report.AppealReportRequestDTO' produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/report.MessageResponse' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Appeal a resolved report tags: - Reports - Store Owner /stores/{storeId}/reports/{reportId}/respond: post: consumes: - application/json description: Store owner provides their response to a report against their content parameters: - description: Store ID in: path name: storeId required: true type: string - description: Report ID in: path name: reportId required: true type: string - description: Respond to report request in: body name: request required: true schema: $ref: '#/definitions/report.StoreRespondRequest' produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/report.MessageResponse' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Respond to a report tags: - Reports - Store Owner /stores/my: delete: consumes: - application/json description: Soft-deletes the store owned by the authenticated user parameters: - description: Deactivation request with optional reason in: body name: request schema: $ref: '#/definitions/store.DeactivateMyStoreRequestDTO' produces: - application/json responses: "204": description: Store deactivated successfully "400": description: Store already deactivated or has pending orders schema: $ref: '#/definitions/store.ErrorResponseDTO' "401": description: Unauthorized schema: $ref: '#/definitions/store.ErrorResponseDTO' "404": description: Store not found schema: $ref: '#/definitions/store.ErrorResponseDTO' "500": description: Internal server error schema: $ref: '#/definitions/store.ErrorResponseDTO' security: - BearerAuth: [] summary: Deactivate current user's store tags: - My Store put: consumes: - application/json description: Updates the store owned by the authenticated user parameters: - description: Store update request in: body name: request required: true schema: $ref: '#/definitions/store.UpdateMyStoreRequestDTO' produces: - application/json responses: "200": description: OK schema: $ref: '#/definitions/github_com_shoppie_backend_internal_handlers_store.UpdateStoreResponse' "400": description: Invalid request schema: $ref: '#/definitions/store.ErrorResponseDTO' "401": description: Unauthorized schema: $ref: '#/definitions/store.ErrorResponseDTO' "403": description: Store is suspended schema: $ref: '#/definitions/store.ErrorResponseDTO' "404": description: Store not found schema: $ref: '#/definitions/store.ErrorResponseDTO' "429": description: Rate limit exceeded schema: $ref: '#/definitions/store.ErrorResponseDTO' "500": description: Internal server error schema: $ref: '#/definitions/store.ErrorResponseDTO' security: - BearerAuth: [] summary: Update current user's store tags: - My Store /stores/my/close: post: consumes: - application/json description: Close the authenticated vendor's own store parameters: - description: Close data in: body name: request required: true schema: $ref: '#/definitions/store.CloseStoreRequestDTO' produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/store.StoreDTO' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Close own store (vendor) tags: - stores /stores/my/images/{imageID}: delete: description: Soft-deletes a store image and clears the corresponding avatar_url or cover_url column. Triggers Meilisearch re-index. parameters: - description: Image ID (from store's images) in: path name: imageID required: true type: string produces: - application/json responses: "200": description: OK schema: $ref: '#/definitions/response.StandardResponse' "400": description: Invalid image ID schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Image does not belong to your store schema: $ref: '#/definitions/response.StandardResponse' "404": description: Image not found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal server error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Delete store avatar or cover image tags: - My Store /stores/my/reopen: post: description: Reopen the authenticated vendor's own previously closed store produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/store.StoreDTO' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Reopen own closed store (vendor) tags: - stores /stores/my/upload-url: post: consumes: - application/json description: Generates a pre-signed URL for uploading store avatar or cover image parameters: - description: Upload URL request in: body name: request required: true schema: $ref: '#/definitions/store.UploadURLRequestDTO' produces: - application/json responses: "200": description: OK schema: $ref: '#/definitions/store.UploadURLResponseDTO' "400": description: Invalid request schema: $ref: '#/definitions/store.ErrorResponseDTO' "401": description: Unauthorized schema: $ref: '#/definitions/store.ErrorResponseDTO' "403": description: Store is suspended schema: $ref: '#/definitions/store.ErrorResponseDTO' "404": description: Store not found schema: $ref: '#/definitions/store.ErrorResponseDTO' "500": description: Internal server error schema: $ref: '#/definitions/store.ErrorResponseDTO' security: - BearerAuth: [] summary: Generate pre-signed upload URL for store images tags: - My Store /support/tickets: post: consumes: - application/json description: |- Creates a support ticket from the public contact form. Works for both anonymous and authenticated users (no auth required). parameters: - description: Contact request in: body name: request required: true schema: $ref: '#/definitions/support.CreateTicketRequestDTO' produces: - application/json responses: "201": description: Created schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/support.TicketResponse' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "429": description: Too Many Requests schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' summary: Submit a support / contact-us request tags: - Support /support/tickets/{id}: get: description: Returns a single ticket the caller owns, with its visible thread. parameters: - description: Ticket ID in: path name: id required: true type: string produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/support.TicketDetailResponse' type: object "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' summary: Get one of my support tickets tags: - Support /support/tickets/{id}/messages: post: consumes: - application/json description: Appends a customer reply; a resolved/closed ticket is reopened. parameters: - description: Ticket ID in: path name: id required: true type: string - description: Reply body in: body name: request required: true schema: $ref: '#/definitions/support.ReplyRequestDTO' produces: - application/json responses: "201": description: Created schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/support.ReplyResponse' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' summary: Reply to one of my support tickets tags: - Support /support/tickets/mine: get: description: Returns the authenticated caller's support tickets, paginated. parameters: - description: Page number in: query name: page type: integer - description: Page size in: query name: limit type: integer produces: - application/json responses: "200": description: OK schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' summary: List my support tickets tags: - Support /telemetry/test: get: description: Test endpoint to verify distributed tracing is working correctly produces: - application/json responses: "200": description: OK schema: $ref: '#/definitions/response.StandardResponse' summary: Test OpenTelemetry tracing tags: - Monitoring /users/{userId}/reviews: get: parameters: - description: User ID in: path name: userId required: true type: string - default: 1 description: Page number in: query name: page type: integer - default: 20 description: Items per page in: query name: limit type: integer produces: - application/json responses: "200": description: OK schema: $ref: '#/definitions/response.StandardResponse' "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' summary: List reviews by a user tags: - Reviews /v1/admin/categories/reindex-search: post: description: Replaces the Meilisearch categories index with the current taxonomy. The worker keeps the index current as categories change, so this is for recovering from a lost index or a schema change, not for routine use. produces: - application/json responses: "200": description: OK schema: $ref: '#/definitions/response.StandardResponse' "503": description: Service Unavailable schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Rebuild the category search index tags: - Admin /v1/admin/following/statistics: get: consumes: - application/json description: Get aggregated following statistics for admin dashboard parameters: - description: 'Period: 7d, 30d, 90d (default: 30d)' in: query name: period type: string produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/following.AdminStatisticsResponseDTO' type: object "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Get following statistics tags: - Admin Following /v1/admin/following/top-stores: get: consumes: - application/json description: Get stores ranked by follower count parameters: - description: 'Number of stores (default: 10, max: 100)' in: query name: limit type: integer - description: 'Period for new followers count (default: 30)' in: query name: days type: integer produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/following.AdminTopFollowedResponseDTO' type: object "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Get top followed stores tags: - Admin Following /v1/admin/following/trends: get: consumes: - application/json description: Get time-series following trends for admin dashboard parameters: - description: Start date (YYYY-MM-DD) in: query name: start_date type: string - description: End date (YYYY-MM-DD) in: query name: end_date type: string - description: 'Granularity: day, week, month (default: day)' in: query name: granularity type: string produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/following.AdminTrendsResponseDTO' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Get following trends tags: - Admin Following /v1/admin/products: get: consumes: - application/json description: List all products including inactive, suspended, and deleted (admin only) parameters: - default: 1 description: Page number in: query name: page type: integer - default: 20 description: Items per page in: query name: limit type: integer - default: created_at description: Sort field in: query name: sort_by type: string - default: desc description: Sort order (asc/desc) in: query name: sort_order type: string - description: Filter by status in: query name: status type: string - description: Filter by category ID in: query name: category_id type: string - description: Filter by store ID in: query name: store_id type: string - description: Minimum price in: query name: min_price type: string - description: Maximum price in: query name: max_price type: string - description: Filter by condition in: query name: condition type: string - description: Filter by featured status in: query name: is_featured type: string - description: Search term in: query name: search type: string - description: Include soft-deleted products in: query name: include_deleted type: string produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/pagination.Response' type: object "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: List all products (Admin) tags: - Products - Admin /v1/admin/products/{id}: delete: consumes: - application/json description: Permanently delete a product (admin only) parameters: - description: Product ID in: path name: id required: true type: string - default: "false" description: Hard delete (permanent) in: query name: hard type: string produces: - application/json responses: "204": description: No Content "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Delete product (Admin) tags: - Products - Admin get: consumes: - application/json description: Get a single product by ID including inactive and deleted (admin only) parameters: - description: Product ID in: path name: id required: true type: string produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/product.AdminProductResponse' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Get product by ID (Admin) tags: - Products - Admin put: consumes: - application/json description: Update any product regardless of ownership (admin only) parameters: - description: Product ID in: path name: id required: true type: string - description: Product update data in: body name: request required: true schema: $ref: '#/definitions/product.UpdateProductRequestDTO' produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/product.AdminProductResponse' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Update product (Admin) tags: - Products - Admin /v1/admin/products/{id}/feature: post: consumes: - application/json description: Toggle featured status of a product (admin only) parameters: - description: Product ID in: path name: id required: true type: string - description: Feature request data in: body name: request required: true schema: $ref: '#/definitions/product.FeatureProductRequestDTO' produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/product.AdminProductResponse' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Feature/unfeature product (Admin) tags: - Products - Admin /v1/admin/products/{id}/suspend: post: consumes: - application/json description: Suspend a product for policy violations (admin only) parameters: - description: Product ID in: path name: id required: true type: string - description: Suspend request data in: body name: request required: true schema: $ref: '#/definitions/product.SuspendProductRequestDTO' produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/product.AdminProductResponse' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' "409": description: Conflict schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Suspend product (Admin) tags: - Products - Admin /v1/admin/products/{id}/unsuspend: post: consumes: - application/json description: Unsuspend a previously suspended product (admin only) parameters: - description: Product ID in: path name: id required: true type: string produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/product.AdminProductResponse' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Unsuspend product (Admin) tags: - Products - Admin /v1/admin/products/analytics: get: consumes: - application/json description: Get time-series product analytics (admin only) parameters: - default: week description: Time period (day, week, month) in: query name: period type: string - description: Start date (RFC3339) in: query name: start_date type: string - description: End date (RFC3339) in: query name: end_date type: string - description: Filter by store ID in: query name: store_id type: string - description: Filter by category ID in: query name: category_id type: string - default: 10 description: Number of top products to include in: query name: top_products_n type: integer produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/product.ProductAnalyticsResponse' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Get product analytics (Admin) tags: - Products - Admin /v1/admin/products/bulk/delete: post: consumes: - application/json description: Delete multiple products at once (admin only) parameters: - description: Bulk delete data in: body name: request required: true schema: $ref: '#/definitions/product.AdminBulkDeleteRequestDTO' produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/product.BulkOperationResponse' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Bulk delete products (Admin) tags: - Products - Admin /v1/admin/products/bulk/update: post: consumes: - application/json description: Update multiple products at once (admin only) parameters: - description: Bulk update data in: body name: request required: true schema: $ref: '#/definitions/product.AdminBulkUpdateRequestDTO' produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/product.BulkOperationResponse' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Bulk update products (Admin) tags: - Products - Admin /v1/admin/products/reindex-search: post: description: Republishes search events for all active products to sync the search index. Safe to run while live. produces: - application/json responses: "200": description: OK schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Re-index all active products in Meilisearch tags: - Admin /v1/admin/products/statistics: get: consumes: - application/json description: Get aggregated product statistics (admin only) parameters: - description: Include per-store breakdown in: query name: include_by_store type: boolean - description: Include top categories in: query name: include_categories type: boolean produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/product.ProductStatisticsResponse' type: object "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Get product statistics (Admin) tags: - Products - Admin /v1/admin/services/reindex-search: post: description: |- Republishes search events for every active service so the index picks up document-shape changes. Safe to run while live, and safe to repeat. produces: - application/json responses: "200": description: OK schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Re-index all active services in Meilisearch tags: - Admin /v1/admin/stores/reindex-search: post: description: Republishes search events for all active stores to sync the search index. Safe to run while live. produces: - application/json responses: "200": description: OK schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Re-index all active stores in Meilisearch tags: - Admin /v1/auth/{provider}/callback: get: description: Handle OAuth callback and complete authentication parameters: - description: OAuth provider (google, apple) in: path name: provider required: true type: string - description: OAuth authorization code in: query name: code required: true type: string - description: OAuth state parameter in: query name: state required: true type: string responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/auth.OAuthCallbackResponseDTO' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' summary: OAuth callback handler tags: - auth /v1/auth/2fa/disable: post: description: Disable 2FA for the user produces: - application/json responses: "200": description: OK schema: $ref: '#/definitions/response.StandardResponse' "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - Bearer: [] summary: Disable two-factor authentication tags: - auth /v1/auth/2fa/enable: post: consumes: - application/json description: Confirm and enable 2FA for the user parameters: - description: Enable 2FA request in: body name: request required: true schema: $ref: '#/definitions/auth.Enable2FARequestDTO' produces: - application/json responses: "200": description: OK schema: $ref: '#/definitions/response.StandardResponse' "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "409": description: Conflict schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - Bearer: [] summary: Enable two-factor authentication tags: - auth /v1/auth/2fa/setup: get: description: Generate 2FA secret and QR code for user produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/auth.Enable2FASetupResponse' type: object "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "409": description: Conflict schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - Bearer: [] summary: Setup two-factor authentication tags: - auth /v1/auth/2fa/verify: post: consumes: - application/json description: Verify a 2FA TOTP code for testing purposes parameters: - description: Verify 2FA request in: body name: request required: true schema: $ref: '#/definitions/auth.Verify2FARequest' produces: - application/json responses: "200": description: OK schema: $ref: '#/definitions/response.StandardResponse' "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - Bearer: [] summary: Verify two-factor authentication code tags: - auth /v1/auth/forgot-password: post: consumes: - application/json description: Send password reset email to user parameters: - description: Forgot password request in: body name: request required: true schema: $ref: '#/definitions/auth.ForgotPasswordRequestDTO' produces: - application/json responses: "200": description: OK schema: $ref: '#/definitions/response.StandardResponse' "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "429": description: Too Many Requests schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' summary: Request password reset tags: - auth /v1/auth/login: post: consumes: - application/json description: Authenticate user with email and password parameters: - description: Login request in: body name: request required: true schema: $ref: '#/definitions/auth.LoginRequestDTO' produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/auth.LoginResponseDTO' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "429": description: Too Many Requests schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' summary: User login tags: - auth /v1/auth/login/2fa: post: consumes: - application/json description: Complete login with two-factor authentication parameters: - description: 2FA login request in: body name: request required: true schema: $ref: '#/definitions/auth.TwoFactorLoginRequestDTO' produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/auth.LoginResponseDTO' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' summary: Complete 2FA login tags: - auth /v1/auth/logout: post: consumes: - application/json description: Logout user and revoke refresh tokens parameters: - description: Logout request in: body name: request schema: $ref: '#/definitions/auth.LogoutRequestDTO' produces: - application/json responses: "200": description: OK schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - Bearer: [] summary: User logout tags: - auth /v1/auth/oauth/{provider}: get: description: Start OAuth authentication flow with provider parameters: - description: OAuth provider (google, apple) in: path name: provider required: true type: string - description: URL to redirect to after successful authentication in: query name: redirect type: string responses: "302": description: Redirect to OAuth provider "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' summary: Start OAuth authentication tags: - auth /v1/auth/oauth/google/onetap: post: description: Authenticate with Google One Tap using a credential (ID token) parameters: - description: Google credential in: body name: request required: true schema: $ref: '#/definitions/auth.GoogleOneTapRequest' responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/auth.OAuthCallbackResponseDTO' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' summary: Google One Tap authentication tags: - auth /v1/auth/refresh: post: consumes: - application/json description: Get a new access token using refresh token parameters: - description: Refresh token request (optional if using cookie) in: body name: request schema: $ref: '#/definitions/auth.RefreshTokenRequestDTO' produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/auth.RefreshTokenResponseDTO' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' summary: Refresh access token tags: - auth /v1/auth/register: post: consumes: - application/json description: Register a new user with email and password parameters: - description: Registration request in: body name: request required: true schema: $ref: '#/definitions/auth.RegisterWithEmailRequest' produces: - application/json responses: "201": description: Created schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/auth.RegisterResponse' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "409": description: Conflict schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' summary: Register a new user tags: - auth /v1/auth/reset-password: post: consumes: - application/json description: Reset user password using reset token parameters: - description: Reset password request in: body name: request required: true schema: $ref: '#/definitions/auth.ResetPasswordRequestDTO' produces: - application/json responses: "200": description: OK schema: $ref: '#/definitions/response.StandardResponse' "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' summary: Reset password tags: - auth /v1/auth/send-verification-token: post: consumes: - application/json description: Send a verification token to user's email parameters: - description: Send verification token request in: body name: request required: true schema: $ref: '#/definitions/auth.SendVerificationTokenRequest' produces: - application/json responses: "200": description: OK schema: $ref: '#/definitions/response.StandardResponse' "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' "429": description: Too Many Requests schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' summary: Send email verification token tags: - auth /v1/auth/verify-email: post: consumes: - application/json description: Verify user email with verification token parameters: - description: Email verification request in: body name: request required: true schema: $ref: '#/definitions/auth.VerifyEmailRequest' produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/auth.VerifyEmailResponse' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' summary: Verify email address tags: - auth /v1/categories/{id}/products: get: consumes: - application/json description: List all active products in a specific category parameters: - description: Category ID in: path name: id required: true type: string - default: 1 description: Page number in: query name: page type: integer - default: 4 description: Items per page in: query name: limit type: integer - default: created_at description: Sort field in: query name: sort_by type: string - default: desc description: Sort order (asc/desc) in: query name: sort_order type: string produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/pagination.Response' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' summary: List products by category tags: - Products /v1/notifications: get: consumes: - application/json description: Retrieves a paginated list of notifications for the current user parameters: - description: 'Page number (default: 1)' in: query name: page type: integer - description: 'Page size (default: 20, max: 100)' in: query name: page_size type: integer - description: Only return unread notifications in: query name: unread_only type: boolean produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/pagination.Response' type: object "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: List notifications for the authenticated user tags: - notifications /v1/notifications/{id}: delete: consumes: - application/json description: Soft deletes a notification parameters: - description: Notification ID (UUID) in: path name: id required: true type: string produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/notification.DeleteNotificationResponseDTO' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Delete a notification tags: - notifications /v1/notifications/{id}/archive: patch: consumes: - application/json description: Archives a notification (hides from main view) parameters: - description: Notification ID (UUID) in: path name: id required: true type: string produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/notification.ArchiveNotificationResponseDTO' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Archive a notification tags: - notifications /v1/notifications/{id}/read: patch: consumes: - application/json description: Marks a single notification as read parameters: - description: Notification ID (UUID) in: path name: id required: true type: string produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/notification.MarkReadResponseDTO' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Mark a notification as read tags: - notifications /v1/notifications/{id}/snooze: delete: consumes: - application/json description: Removes the snooze from a notification parameters: - description: Notification ID (UUID) in: path name: id required: true type: string produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/notification.MarkReadResponseDTO' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Clear snooze from a notification tags: - notifications post: consumes: - application/json description: Snoozes a notification until the specified time parameters: - description: Notification ID (UUID) in: path name: id required: true type: string - description: Snooze details in: body name: request required: true schema: $ref: '#/definitions/notification.SnoozeNotificationRequestDTO' produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/notification.SnoozeNotificationResponseDTO' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Snooze a notification tags: - notifications /v1/notifications/{id}/unarchive: patch: consumes: - application/json description: Restores an archived notification to the main view parameters: - description: Notification ID (UUID) in: path name: id required: true type: string produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/notification.ArchiveNotificationResponseDTO' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Unarchive a notification tags: - notifications /v1/notifications/archived: get: consumes: - application/json description: Retrieves a paginated list of archived notifications parameters: - description: 'Page number (default: 1)' in: query name: page type: integer - description: 'Page size (default: 20, max: 100)' in: query name: page_size type: integer produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/pagination.Response' type: object "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: List archived notifications tags: - notifications /v1/notifications/devices: post: consumes: - application/json description: Registers a device token for receiving push notifications parameters: - description: Device registration details in: body name: request required: true schema: $ref: '#/definitions/notification.RegisterDeviceRequest' produces: - application/json responses: "201": description: Created schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/notification.DeviceTokenResponseDTO' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Register a device for push notifications tags: - notifications /v1/notifications/devices/{token}: delete: consumes: - application/json description: Removes a device token from push notification registration parameters: - description: Device token to unregister in: path name: token required: true type: string produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/notification.MarkReadResponseDTO' type: object "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Unregister a device from push notifications tags: - notifications /v1/notifications/preferences: get: consumes: - application/json description: Retrieves the current user's notification preferences produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/notification.PreferencesResponseDTO' type: object "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Get notification preferences tags: - notifications put: consumes: - application/json description: Updates the current user's notification preferences parameters: - description: Preferences to update in: body name: request required: true schema: $ref: '#/definitions/notification.UpdatePreferencesRequestDTO' produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/notification.PreferencesResponseDTO' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Update notification preferences tags: - notifications /v1/notifications/read-all: patch: consumes: - application/json description: Marks all notifications for the current user as read produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/notification.MarkReadResponseDTO' type: object "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Mark all notifications as read tags: - notifications /v1/notifications/unread-count: get: consumes: - application/json description: Returns the number of unread notifications for the current user produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/notification.UnreadCountResponseDTO' type: object "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Get unread notification count tags: - notifications /v1/products: get: consumes: - application/json description: Returns lightweight ProductPublicDTO with only 10 essential fields for product cards. 92% smaller payloads optimized for mobile. Full details available via GET /products/:id parameters: - default: 1 description: Page number in: query name: page type: integer - default: 24 description: Items per page in: query name: limit type: integer - default: created_at description: Sort field in: query name: sort_by type: string - default: desc description: Sort order (asc/desc) in: query name: sort_order type: string - description: Filter by status in: query name: status type: string - description: Filter by category ID in: query name: category_id type: string - description: Filter by store ID in: query name: store_id type: string - description: Minimum price in: query name: min_price type: string - description: Maximum price in: query name: max_price type: string - description: Filter by condition in: query name: condition type: string - description: Filter by featured status in: query name: is_featured type: string produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/pagination.Response' type: object "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' summary: List products (lightweight - ProductPublicDTO) tags: - Products /v1/products/{id}: get: consumes: - application/json description: Get a single product by its ID parameters: - description: Product ID in: path name: id required: true type: string produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/product.ProductResponse' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' summary: Get product by ID tags: - Products /v1/products/{id}/favorite: delete: consumes: - application/json description: Remove a product from user's favorites/wishlist parameters: - description: Product ID in: path name: id required: true type: string produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/following.UnfavoriteProductResponseDTO' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not favorited schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Unfavorite a product tags: - Favorites post: consumes: - application/json description: Add a product to user's favorites/wishlist parameters: - description: Product ID in: path name: id required: true type: string - description: Notification preferences in: body name: request schema: $ref: '#/definitions/following.FavoriteProductRequestDTO' produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/following.FavoriteProductResponseDTO' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' "409": description: Already favorited schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Favorite a product tags: - Favorites /v1/products/{id}/options: get: parameters: - description: Product ID in: path name: id required: true type: string produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/product.ListOptionTypesResponseDTO' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' summary: List all option types with their values for a product tags: - Products /v1/products/{id}/specifications: get: description: Returns all key-value specifications for a product, ordered by position. parameters: - description: Product ID in: path name: id required: true type: string produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/product.ListSpecificationsResponseDTO' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' summary: List all specifications for a product tags: - Products /v1/products/{id}/variants: get: description: Returns all variants with resolved option names and values, ordered by position. parameters: - description: Product ID in: path name: id required: true type: string produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/product.ListVariantsResponseDTO' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' summary: List all variants for a product tags: - Products /v1/products/featured: get: consumes: - application/json description: Get a list of featured products (paginated) parameters: - default: 1 description: Page number in: query name: page type: integer - default: 4 description: Number of products per page in: query name: limit type: integer produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/pagination.Response' type: object "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' summary: Get featured products tags: - Products /v1/products/trending: get: consumes: - application/json description: Get a list of trending products based on recent activity (paginated) parameters: - default: 1 description: Page number in: query name: page type: integer - default: 20 description: Number of products per page in: query name: limit type: integer - default: week description: Time period (day, week, month) in: query name: period type: string - description: Filter by category ID (UUID) format: uuid in: query name: category_id type: string produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/pagination.Response' type: object "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' summary: Get trending products tags: - Products /v1/promotions: get: description: Get all active promotions across the platform (public) parameters: - default: 1 description: Page number in: query name: page type: integer - default: 20 description: Items per page in: query name: limit type: integer produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/promotion.ListPublicPromotionsResponseDTO' type: object "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' summary: List all active promotions tags: - promotions /v1/promotions/apply: post: consumes: - application/json description: Apply a promo code to an order and record usage parameters: - description: Store ID in: query name: store_id required: true type: string - description: Apply request in: body name: request required: true schema: $ref: '#/definitions/promotion.ApplyPromoCodeRequestDTO' produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/promotion.ApplyPromoCodeResponseDTO' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Apply a promo code tags: - promotions /v1/promotions/store/{store_id}: get: description: Get all active promotions for a specific store (public) parameters: - description: Store ID in: path name: store_id required: true type: string - default: 1 description: Page number in: query name: page type: integer - default: 20 description: Items per page in: query name: limit type: integer produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/promotion.ListPublicPromotionsResponseDTO' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' summary: List active promotions for a store tags: - promotions /v1/promotions/validate: post: consumes: - application/json description: Validate a promo code without applying it parameters: - description: Store ID in: query name: store_id required: true type: string - description: Validation request in: body name: request required: true schema: $ref: '#/definitions/promotion.ValidatePromoCodeRequestDTO' produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/promotion.ValidatePromoCodeResponseDTO' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' summary: Validate a promo code tags: - promotions /v1/services: get: description: List services with optional filtering parameters: - default: 1 description: Page number in: query name: page type: integer - default: 20 description: Items per page in: query name: page_size type: integer - description: Filter by store ID in: query name: store_id type: string - description: Filter by category ID in: query name: category_id type: string - description: Filter by location type (in_person, online, hybrid) in: query name: location_type type: string - description: Minimum price in: query name: min_price type: number - description: Maximum price in: query name: max_price type: number - description: Minimum rating in: query name: min_rating type: number - description: 'Sort order: random (rotates discovery). Default: newest first.' in: query name: sort type: string produces: - application/json responses: "200": description: OK schema: $ref: '#/definitions/response.StandardResponse' "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' summary: List services tags: - services post: consumes: - application/json description: Create a new service for a store parameters: - description: Service data in: body name: request required: true schema: $ref: '#/definitions/service.CreateServiceRequest' produces: - application/json responses: "201": description: Created schema: $ref: '#/definitions/response.StandardResponse' "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Create a new service tags: - services /v1/services/{id}: delete: description: Soft delete a service parameters: - description: Service ID in: path name: id required: true type: string produces: - application/json responses: "200": description: OK schema: $ref: '#/definitions/response.StandardResponse' "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Delete a service tags: - services get: description: Get a service by its ID parameters: - description: Service ID in: path name: id required: true type: string produces: - application/json responses: "200": description: OK schema: $ref: '#/definitions/response.StandardResponse' "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' summary: Get service by ID tags: - services patch: consumes: - application/json description: Update an existing service parameters: - description: Service ID in: path name: id required: true type: string - description: Service data in: body name: request required: true schema: $ref: '#/definitions/service.UpdateServiceRequest' produces: - application/json responses: "200": description: OK schema: $ref: '#/definitions/response.StandardResponse' "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Update a service tags: - services /v1/services/{id}/favorite: delete: consumes: - application/json description: Remove a service from user's favorites parameters: - description: Service ID in: path name: id required: true type: string produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/following.UnfavoriteServiceResponseDTO' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not favorited schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Unfavorite a service tags: - Following post: consumes: - application/json description: Add a service to user's favorites parameters: - description: Service ID in: path name: id required: true type: string produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/following.FavoriteServiceResponseDTO' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' "409": description: Already favorited schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Favorite a service tags: - Following /v1/services/featured: get: description: Get list of featured services parameters: - default: 10 description: Maximum number of services in: query name: limit type: integer produces: - application/json responses: "200": description: OK schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' summary: Get featured services tags: - services /v1/services/my: get: description: List all services belonging to the authenticated vendor's store across all statuses (draft, active, suspended, archived). Designed for vendor dashboard management. parameters: - default: 1 description: Page number in: query name: page type: integer - default: 20 description: Items per page in: query name: limit type: integer - description: 'Filter by status: draft, active, suspended, archived' in: query name: status type: string produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/pagination.Response' type: object "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: No store found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: List vendor's services (all statuses) tags: - Services - Vendor /v1/services/slug/{slug}: get: description: Get a service by its slug parameters: - description: Service slug in: path name: slug required: true type: string produces: - application/json responses: "200": description: OK schema: $ref: '#/definitions/response.StandardResponse' "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' summary: Get service by slug tags: - services /v1/services/trending: get: description: Get list of trending services based on bookings and ratings parameters: - default: 10 description: Maximum number of services in: query name: limit type: integer produces: - application/json responses: "200": description: OK schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' summary: Get trending services tags: - services /v1/stores: get: consumes: - application/json description: Get a paginated list of public stores with optional filters parameters: - default: 1 description: 'Page number (default: 1)' in: query name: page type: integer - default: 20 description: 'Page size (default: 20, max: 100)' in: query name: page_size type: integer - description: Filter by category in: query name: category type: string - description: Filter by location in: query name: location type: string - description: Filter by verification status in: query name: is_verified type: boolean - description: Minimum rating (0-5) in: query name: min_rating type: number - default: newest description: 'Sort by: newest, popular, rating, alphabetical, random' in: query name: sort_by type: string - default: desc description: 'Sort order: asc, desc' in: query name: sort_order type: string produces: - application/json responses: "200": description: OK schema: $ref: '#/definitions/store.ListPublicStoresResponseDTO' "400": description: Bad Request schema: $ref: '#/definitions/store.ErrorResponseDTO' "500": description: Internal Server Error schema: $ref: '#/definitions/store.ErrorResponseDTO' summary: List public stores tags: - stores post: consumes: - application/json description: Create a new store for the authenticated user (vendor onboarding completion) parameters: - description: Store creation data in: body name: request required: true schema: $ref: '#/definitions/store.CreateStoreRequestDTO' produces: - application/json responses: "201": description: Created schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/store.StoreDTO' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "409": description: Conflict schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Create a new store tags: - stores /v1/stores/{id}: get: consumes: - application/json description: Get detailed information about a public store parameters: - description: Store ID (UUID) in: path name: id required: true type: string - default: true description: Whether to track this view in: query name: track_view type: boolean produces: - application/json responses: "200": description: OK schema: $ref: '#/definitions/store.GetPublicStoreResponseDTO' "404": description: Not Found schema: $ref: '#/definitions/store.ErrorResponseDTO' "500": description: Internal Server Error schema: $ref: '#/definitions/store.ErrorResponseDTO' summary: Get public store by ID tags: - stores /v1/stores/{id}/follow: delete: consumes: - application/json description: Stop following a store parameters: - description: Store ID in: path name: id required: true type: string produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/following.UnfollowStoreResponseDTO' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not following schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Unfollow a store tags: - Following post: consumes: - application/json description: Follow a store to receive updates and notifications parameters: - description: Store ID in: path name: id required: true type: string produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/following.FollowStoreResponseDTO' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' "409": description: Already following schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Follow a store tags: - Following /v1/stores/{id}/follow/status: get: consumes: - application/json description: Check if the current user follows a store parameters: - description: Store ID in: path name: id required: true type: string produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/following.FollowStatusResponseDTO' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Get follow status tags: - Following /v1/stores/{id}/followers: get: consumes: - application/json description: Get paginated list of users following a store parameters: - description: Store ID in: path name: id required: true type: string - description: 'Page number (default: 1)' in: query name: page type: integer - description: 'Page size (default: 20, max: 100)' in: query name: limit type: integer produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/following.ListFollowersResponseDTO' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' summary: List store followers tags: - Following /v1/stores/{slug}: patch: consumes: - application/json description: Update own store (bio, images, etc.) parameters: - description: Store slug in: path name: slug required: true type: string - description: Store update data in: body name: request required: true schema: $ref: '#/definitions/store.UpdateStoreRequestDTO' produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/store.StoreDTO' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Update store tags: - stores /v1/stores/{store_id}/products: get: consumes: - application/json description: Returns lightweight ProductPublicDTO with only 10 essential fields for product cards. 92% smaller payloads optimized for mobile. Full details available via GET /products/:id parameters: - description: Store ID in: path name: store_id required: true type: string - default: 1 description: Page number in: query name: page type: integer - default: 20 description: Items per page in: query name: limit type: integer - default: created_at description: Sort field in: query name: sort_by type: string - default: desc description: Sort order (asc/desc) in: query name: sort_order type: string produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/pagination.Response' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' summary: List products by store (lightweight - ProductPublicDTO) tags: - Products - Stores /v1/stores/{store_id}/products/{slug}: get: consumes: - application/json description: Get a single product by its slug within a store parameters: - description: Store ID in: path name: store_id required: true type: string - description: Product slug in: path name: slug required: true type: string produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/product.ProductResponse' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' summary: Get product by slug tags: - Products /v1/stores/{store_id}/promotions: get: description: List all promotions for a store (vendor only) parameters: - description: Store ID in: path name: store_id required: true type: string - default: 1 description: Page number in: query name: page type: integer - default: 20 description: Items per page in: query name: limit type: integer - description: Filter by status in: query name: status type: string - description: Search in title in: query name: search type: string - description: Sort by field enum: - created_at - starts_at - ends_at - usage_count - title in: query name: sort_by type: string - description: Sort order enum: - asc - desc in: query name: sort_order type: string produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/promotion.ListPromotionsResponseDTO' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: List my promotions tags: - promotions post: consumes: - application/json description: Create a new promotion for a store (vendor only) parameters: - description: Store ID in: path name: store_id required: true type: string - description: Promotion data in: body name: request required: true schema: $ref: '#/definitions/promotion.CreatePromotionRequestDTO' produces: - application/json responses: "201": description: Created schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/promotion.PromotionDTO' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "409": description: Conflict schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Create a new promotion tags: - promotions /v1/stores/{store_id}/promotions/{id}: delete: description: Soft delete a promotion (vendor only) parameters: - description: Store ID in: path name: store_id required: true type: string - description: Promotion ID in: path name: id required: true type: string produces: - application/json responses: "204": description: No content "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Delete a promotion tags: - promotions get: description: Get detailed information about a specific promotion (vendor only) parameters: - description: Store ID in: path name: store_id required: true type: string - description: Promotion ID in: path name: id required: true type: string produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/promotion.PromotionDTO' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Get a promotion tags: - promotions put: consumes: - application/json description: Update an existing promotion (vendor only) parameters: - description: Store ID in: path name: store_id required: true type: string - description: Promotion ID in: path name: id required: true type: string - description: Updated promotion data in: body name: request required: true schema: $ref: '#/definitions/promotion.UpdatePromotionRequestDTO' produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/promotion.PromotionDTO' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Update a promotion tags: - promotions /v1/stores/{store_id}/promotions/{id}/activate: post: description: Activate a scheduled or draft promotion (vendor only) parameters: - description: Store ID in: path name: store_id required: true type: string - description: Promotion ID in: path name: id required: true type: string produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/promotion.PromotionDTO' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Activate a promotion tags: - promotions /v1/stores/{store_id}/promotions/{id}/analytics: get: description: Get analytics for a specific promotion (vendor only) parameters: - description: Store ID in: path name: store_id required: true type: string - description: Promotion ID in: path name: id required: true type: string - description: Start date (RFC3339) in: query name: date_from type: string - description: End date (RFC3339) in: query name: date_to type: string produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/promotion.PromotionAnalyticsDTO' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Get promotion analytics tags: - promotions /v1/stores/{store_id}/promotions/{id}/pause: post: description: Pause an active promotion (vendor only) parameters: - description: Store ID in: path name: store_id required: true type: string - description: Promotion ID in: path name: id required: true type: string produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/promotion.PromotionDTO' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Pause a promotion tags: - promotions /v1/stores/{store_id}/promotions/{id}/resume: post: description: Resume a paused promotion (vendor only) parameters: - description: Store ID in: path name: store_id required: true type: string - description: Promotion ID in: path name: id required: true type: string produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/promotion.PromotionDTO' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Resume a promotion tags: - promotions /v1/stores/{store_id}/services: get: description: List services for a specific store parameters: - description: Store ID in: path name: store_id required: true type: string - default: 1 description: Page number in: query name: page type: integer - default: 20 description: Items per page in: query name: page_size type: integer produces: - application/json responses: "200": description: OK schema: $ref: '#/definitions/response.StandardResponse' "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' summary: List services by store tags: - services /v1/stores/my: get: description: Get own store (private view) produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/store.StoreDTO' type: object "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Get own store tags: - My Store /v1/stores/slug/{slug}: get: consumes: - application/json description: Get detailed information about a public store by its URL-friendly slug parameters: - description: Store slug in: path name: slug required: true type: string - default: true description: Whether to track this view in: query name: track_view type: boolean produces: - application/json responses: "200": description: OK schema: $ref: '#/definitions/store.GetPublicStoreResponseDTO' "404": description: Not Found schema: $ref: '#/definitions/store.ErrorResponseDTO' "500": description: Internal Server Error schema: $ref: '#/definitions/store.ErrorResponseDTO' summary: Get public store by slug tags: - stores /v1/users: get: description: Get a paginated list of users with optional filtering parameters: - default: 1 description: Page number in: query name: page type: integer - default: 20 description: Items per page in: query name: per_page type: integer - description: Filter by role enum: - customer - vendor - admin in: query name: role type: string - description: Search in email, first name, last name in: query name: search type: string - default: created_at description: Sort field enum: - created_at - email - role in: query name: sort_by type: string - default: desc description: Sort direction enum: - asc - desc in: query name: sort_dir type: string produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/pagination.Response' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - Bearer: [] summary: List users (Admin only) tags: - user /v1/users/{id}: get: description: Get a specific user's information by ID. Accessible by moderators, admins, and super_admins, or by the user themselves. parameters: - description: User ID format: uuid in: path name: id required: true type: string produces: - application/json responses: "200": description: User details schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/user.UserResponse' type: object "400": description: Invalid user ID format schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized - no valid token schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden - not authorized to view this user schema: $ref: '#/definitions/response.StandardResponse' "404": description: User not found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal server error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Get user by ID (Staff only) tags: - user put: consumes: - application/json description: Update a specific user's information by ID. Accessible by moderators, admins, and super_admins, or by the user themselves. parameters: - description: User ID format: uuid in: path name: id required: true type: string - description: User update request in: body name: request required: true schema: $ref: '#/definitions/user.UpdateUserRequestDTO' produces: - application/json responses: "200": description: User updated successfully schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/user.UserResponse' type: object "400": description: Invalid request body or user ID schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized - no valid token schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden - not authorized to update this user schema: $ref: '#/definitions/response.StandardResponse' "404": description: User not found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal server error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Update user by ID (Staff only) tags: - user /v1/users/me: delete: description: Soft delete the authenticated user's account produces: - application/json responses: "200": description: OK schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - Bearer: [] summary: Delete current user account tags: - user get: description: Get the authenticated user's profile information (simplified for web portal) produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/user.UserProfileDTO' type: object "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - Bearer: [] summary: Get current user profile tags: - user put: consumes: - application/json description: Update the authenticated user's profile information (returns simplified profile for web portal) parameters: - description: Update profile request in: body name: request required: true schema: $ref: '#/definitions/user.UpdateUserRequestDTO' produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/user.UserProfileDTO' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - Bearer: [] summary: Update current user profile tags: - user /v1/users/me/favorites: get: consumes: - application/json description: Get paginated list of user's favorite products parameters: - description: 'Page number (default: 1)' in: query name: page type: integer - description: 'Page size (default: 20, max: 100)' in: query name: limit type: integer produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/following.ListFavoritesResponseDTO' type: object "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: List favorite products tags: - Favorites /v1/users/me/favorites/services: get: consumes: - application/json description: Get paginated list of user's favorite services parameters: - description: 'Page number (default: 1)' in: query name: page type: integer - description: 'Page size (default: 20, max: 100)' in: query name: limit type: integer produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/pagination.Response' type: object "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: List favorite services tags: - Following /v1/users/me/following/stores: get: consumes: - application/json description: Get paginated list of stores the authenticated user follows parameters: - description: 'Page number (default: 1)' in: query name: page type: integer - description: 'Page size (default: 20, max: 100)' in: query name: limit type: integer produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/following.ListFollowedStoresResponseDTO' type: object "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: List stores followed by current user tags: - Following /v1/users/me/password: put: consumes: - application/json description: Change the authenticated user's password parameters: - description: Change password request in: body name: request required: true schema: $ref: '#/definitions/auth.ChangePasswordRequest' produces: - application/json responses: "200": description: OK schema: $ref: '#/definitions/response.StandardResponse' "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - Bearer: [] summary: Change current user password tags: - auth /v1/vendor/products: get: consumes: - application/json description: List all products owned by the authenticated vendor parameters: - default: 1 description: Page number in: query name: page type: integer - default: 20 description: Items per page in: query name: limit type: integer - default: created_at description: Sort field in: query name: sort_by type: string - default: desc description: Sort order (asc/desc) in: query name: sort_order type: string - description: Filter by status (draft, pending, active, suspended, archived) in: query name: status type: string - description: Search term in: query name: search type: string produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/pagination.Response' type: object "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: List vendor's products tags: - Products - Vendor post: consumes: - application/json description: Create a new product for the vendor's store parameters: - description: Product creation data in: body name: request required: true schema: $ref: '#/definitions/product.CreateProductRequestDTO' produces: - application/json responses: "201": description: Created schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/product.ProductResponse' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Create a new product tags: - Products - Vendor /v1/vendor/products/{id}: delete: consumes: - application/json description: Soft delete a product owned by the vendor parameters: - description: Product ID in: path name: id required: true type: string produces: - application/json responses: "204": description: No Content "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Delete a product tags: - Products - Vendor put: consumes: - application/json description: Update an existing product owned by the vendor parameters: - description: Product ID in: path name: id required: true type: string - description: Product update data in: body name: request required: true schema: $ref: '#/definitions/product.UpdateProductRequestDTO' produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/product.ProductResponse' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Update a product tags: - Products - Vendor /v1/vendor/products/{id}/archive: post: consumes: - application/json description: Archive a product owned by the vendor parameters: - description: Product ID in: path name: id required: true type: string produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/product.ProductResponse' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Archive a product tags: - Products - Vendor /v1/vendor/products/{id}/inventory: post: consumes: - application/json description: Adjust the inventory quantity for a product parameters: - description: Product ID in: path name: id required: true type: string - description: Inventory adjustment data in: body name: request required: true schema: $ref: '#/definitions/product.AdjustInventoryRequestDTO' produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/product.AdjustInventoryResponseDTO' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Adjust product inventory tags: - Products - Vendor /v1/vendor/products/{id}/inventory/history: get: consumes: - application/json description: Get the inventory adjustment history for a product parameters: - description: Product ID in: path name: id required: true type: string - default: 1 description: Page number in: query name: page type: integer - default: 20 description: Items per page in: query name: limit type: integer produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/pagination.Response' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Get inventory history tags: - Products - Vendor /v1/vendor/products/{id}/options: post: consumes: - application/json parameters: - description: Product ID in: path name: id required: true type: string - description: Option type data in: body name: request required: true schema: $ref: '#/definitions/product.CreateOptionTypeRequestDTO' produces: - application/json responses: "201": description: Created schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/product.OptionTypeDTO' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "409": description: Conflict schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Add a new option type (e.g. "Size", "Color") to a product tags: - Products /v1/vendor/products/{id}/options/{optionID}: delete: parameters: - description: Product ID in: path name: id required: true type: string - description: Option Type ID in: path name: optionID required: true type: string responses: "204": description: No Content "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Remove an option type and all its values from a product tags: - Products put: consumes: - application/json parameters: - description: Product ID in: path name: id required: true type: string - description: Option Type ID in: path name: optionID required: true type: string - description: Option type data in: body name: request required: true schema: $ref: '#/definitions/product.UpdateOptionTypeRequestDTO' produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/product.OptionTypeDTO' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Rename or reposition an option type tags: - Products /v1/vendor/products/{id}/options/{optionID}/values: post: consumes: - application/json parameters: - description: Product ID in: path name: id required: true type: string - description: Option Type ID in: path name: optionID required: true type: string - description: Option value data in: body name: request required: true schema: $ref: '#/definitions/product.AddOptionValueRequestDTO' produces: - application/json responses: "201": description: Created schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/product.OptionValueDTO' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "409": description: Conflict schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Add a value to an option type (e.g. "M" to "Size") tags: - Products /v1/vendor/products/{id}/options/{optionID}/values/{valueID}: delete: parameters: - description: Product ID in: path name: id required: true type: string - description: Option Type ID in: path name: optionID required: true type: string - description: Option Value ID in: path name: valueID required: true type: string responses: "204": description: No Content "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Remove an option value from an option type tags: - Products put: consumes: - application/json parameters: - description: Product ID in: path name: id required: true type: string - description: Option Type ID in: path name: optionID required: true type: string - description: Option Value ID in: path name: valueID required: true type: string - description: Option value data in: body name: request required: true schema: $ref: '#/definitions/product.UpdateOptionValueRequestDTO' produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/product.OptionValueDTO' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Rename or reposition an option value tags: - Products /v1/vendor/products/{id}/publish: post: consumes: - application/json description: Publish a draft product to make it active and visible parameters: - description: Product ID in: path name: id required: true type: string produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/product.ProductResponse' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Publish a product tags: - Products - Vendor /v1/vendor/products/{id}/specifications: put: consumes: - application/json description: Replaces all existing specifications with the provided list. Send an empty array to clear all specs. parameters: - description: Product ID in: path name: id required: true type: string - description: Specifications list in: body name: request required: true schema: $ref: '#/definitions/product.SetSpecificationsRequestDTO' produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/product.SetSpecificationsResponseDTO' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Replace all specifications for a product (atomic) tags: - Products /v1/vendor/products/{id}/unarchive: post: consumes: - application/json description: Restore an archived product to draft status parameters: - description: Product ID in: path name: id required: true type: string produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/product.ProductResponse' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Unarchive a product tags: - Products - Vendor /v1/vendor/products/{id}/unpublish: post: consumes: - application/json description: Unpublish an active product to return it to draft status parameters: - description: Product ID in: path name: id required: true type: string produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/product.ProductResponse' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Unpublish a product tags: - Products - Vendor /v1/vendor/products/{id}/variants: post: consumes: - application/json description: Creates a variant with the given option value combination. All option_value_ids must belong to this product. parameters: - description: Product ID in: path name: id required: true type: string - description: Variant data in: body name: request required: true schema: $ref: '#/definitions/product.CreateVariantRequestDTO' produces: - application/json responses: "201": description: Created schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/product.VariantDTO' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Create a new variant for a product tags: - Products /v1/vendor/products/{id}/variants/{variantID}: delete: parameters: - description: Product ID in: path name: id required: true type: string - description: Variant ID in: path name: variantID required: true type: string responses: "204": description: No Content "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Delete a product variant tags: - Products put: consumes: - application/json description: Partially updates an existing variant. Only provided fields are updated. parameters: - description: Product ID in: path name: id required: true type: string - description: Variant ID in: path name: variantID required: true type: string - description: Variant update data in: body name: request required: true schema: $ref: '#/definitions/product.UpdateVariantRequestDTO' produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/product.VariantDTO' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Update a product variant tags: - Products /v1/vendor/stores/{id}/followers/analytics: get: consumes: - application/json description: Get follower analytics for vendor dashboard. Only the store owner can access this endpoint. parameters: - description: Store ID in: path name: id required: true type: string - description: 'Number of days for growth data (default: 30, max: 90)' in: query name: days type: integer produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/following.FollowerAnalyticsResponseDTO' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Not the store owner schema: $ref: '#/definitions/response.StandardResponse' "404": description: Store not found schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Get follower analytics tags: - Vendor Following /v1/vendor/stores/{id}/followers/recent: get: consumes: - application/json description: Get recent followers for vendor dashboard. Only the store owner can access this endpoint. parameters: - description: Store ID in: path name: id required: true type: string - description: 'Number of followers (default: 10, max: 50)' in: query name: limit type: integer produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/following.RecentFollowersResponseDTO' type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Not the store owner schema: $ref: '#/definitions/response.StandardResponse' "404": description: Store not found schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Get recent followers tags: - Vendor Following /vendor/bookings/reviews/{id}/reply: post: consumes: - application/json description: Provider replies to a customer's service/booking review parameters: - description: Review UUID in: path name: id required: true type: string - description: Reply body in: body name: request required: true schema: $ref: '#/definitions/github_com_shoppie_backend_internal_handlers_booking.ReplyToReviewRequest' produces: - application/json responses: "200": description: OK schema: $ref: '#/definitions/response.StandardResponse' "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Reply to a booking review tags: - Bookings - Vendor /vendor/boosts: get: description: Lists boosts belonging to the authenticated vendor's store. parameters: - description: Page number in: query name: page type: integer - description: Page size in: query name: limit type: integer produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: type: object type: object "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: List the vendor's boosts tags: - Vendor - Boost post: consumes: - application/json description: Creates a pending boost for one of the vendor's listings and returns a Paystack checkout URL. The boost activates when payment is confirmed. parameters: - description: Boost purchase in: body name: request required: true schema: $ref: '#/definitions/github_com_shoppie_backend_internal_handlers_boost.CreateBoostRequest' produces: - application/json responses: "201": description: Created schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: type: object type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "409": description: Conflict schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Purchase a boost tags: - Vendor - Boost /vendor/boosts/{id}: get: description: Returns a single boost owned by the authenticated vendor's store. parameters: - description: Boost ID in: path name: id required: true type: string produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: type: object type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Get one of the vendor's boosts tags: - Vendor - Boost /vendor/boosts/{id}/analytics: get: description: Returns impressions, clicks, click-through rate, attributed sales/revenue (window-overlap), and a daily breakdown for a boost owned by the authenticated vendor's store. No buyer-level data is exposed. parameters: - description: Boost ID in: path name: id required: true type: string produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: type: object type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Get analytics for one of the vendor's boosts tags: - Vendor - Boost /vendor/boosts/{id}/cancel: post: description: Ends an active or paused boost owned by the authenticated vendor's store so the listing immediately stops surfacing. Already-ended, refunded, or pending boosts are rejected as a conflict. parameters: - description: Boost ID in: path name: id required: true type: string produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: type: object type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' "409": description: Conflict schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Cancel one of the vendor's boosts tags: - Vendor - Boost /vendor/boosts/{id}/pause: post: description: Temporarily stops an active boost from surfacing without consuming paid days. Resuming extends the end date by the paused duration. Only an active boost can be paused. parameters: - description: Boost ID in: path name: id required: true type: string produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: type: object type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' "409": description: Conflict schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Pause one of the vendor's boosts tags: - Vendor - Boost /vendor/boosts/{id}/resume: post: description: Brings a boost the vendor paused back to active, extending its end date by the time it spent paused. Boosts paused automatically (unsellable listing) or by an admin cannot be resumed here, nor can a boost whose listing is still not sellable. parameters: - description: Boost ID in: path name: id required: true type: string produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: type: object type: object "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' "409": description: Conflict schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal Server Error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Resume one of the vendor's paused boosts tags: - Vendor - Boost /vendor/products/{id}/images: patch: consumes: - application/json description: Atomically updates alt_text for multiple product images. If any image ID is invalid, the entire batch is rejected. parameters: - description: Product ID in: path name: id required: true type: string - description: Bulk alt text updates in: body name: request required: true schema: $ref: '#/definitions/product.BulkUpdateImageAltTextRequest' produces: - application/json responses: "200": description: OK schema: $ref: '#/definitions/response.StandardResponse' "400": description: Invalid request or validation failure schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Access denied - not product owner schema: $ref: '#/definitions/response.StandardResponse' "404": description: Product not found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal server error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Bulk update image alt text tags: - Vendor Products post: consumes: - application/json description: Links multiple pre-uploaded images to a product in a single atomic operation. Every image must exist, have status=ready, and belong to the same store. Primary image gets display_order=0. parameters: - description: Product ID in: path name: id required: true type: string - description: Image IDs to link in: body name: request required: true schema: $ref: '#/definitions/github_com_shoppie_backend_internal_handlers_product.BulkLinkImagesRequest' produces: - application/json responses: "200": description: OK schema: $ref: '#/definitions/response.StandardResponse' "400": description: Invalid request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Access denied schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal server error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Bulk-link pre-uploaded images to a product tags: - Vendor Products /vendor/products/{id}/images/{imageID}: delete: description: Soft-deletes a specific image from a product. entity_id and entity_type are auto-filled from the route — no request body needed. parameters: - description: Product ID in: path name: id required: true type: string - description: Image ID in: path name: imageID required: true type: string produces: - application/json responses: "200": description: OK schema: $ref: '#/definitions/response.StandardResponse' "400": description: Invalid ID format schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Access denied - not product owner schema: $ref: '#/definitions/response.StandardResponse' "404": description: Image or product not found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal server error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Delete a product image tags: - Vendor Products get: consumes: - application/json description: Returns the current processing status, progress, and URLs for a product image. parameters: - description: Product ID in: path name: id required: true type: string - description: Image ID in: path name: imageID required: true type: string produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/product.ImageStatusResponse' type: object "400": description: Invalid ID format schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Access denied schema: $ref: '#/definitions/response.StandardResponse' "404": description: Product or image not found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal server error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Get image processing status tags: - Vendor Products patch: consumes: - application/json description: Updates the alt_text for a single product image. Empty alt_text clears the value. HTML tags are stripped. Max 512 characters. parameters: - description: Product ID in: path name: id required: true type: string - description: Image ID in: path name: imageID required: true type: string - description: Alt text data in: body name: request required: true schema: $ref: '#/definitions/product.UpdateImageAltTextRequest' produces: - application/json responses: "200": description: OK schema: $ref: '#/definitions/response.StandardResponse' "400": description: Invalid ID or alt text exceeds 512 chars schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Access denied - not product owner schema: $ref: '#/definitions/response.StandardResponse' "404": description: Product or image not found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal server error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Update image alt text tags: - Vendor Products /vendor/products/{id}/images/reorder: post: consumes: - application/json description: Atomically reorders all images for a product. The first image_id becomes the primary image shown in listings. Triggers a Meilisearch re-index for active products. parameters: - description: Product ID in: path name: id required: true type: string - description: Reorder request in: body name: request required: true schema: $ref: '#/definitions/product.ReorderProductImagesRequest' produces: - application/json responses: "200": description: OK schema: $ref: '#/definitions/response.StandardResponse' "400": description: Invalid request or image_id not belonging to product schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Access denied schema: $ref: '#/definitions/response.StandardResponse' "404": description: Product not found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal server error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Reorder product images / change primary image tags: - Vendor Products /vendor/products/{id}/upload-url: post: consumes: - application/json description: Generates a presigned URL for uploading product images (convenience endpoint that auto-fills entity_type=product) parameters: - description: Product ID in: path name: id required: true type: string - description: Upload URL request in: body name: request required: true schema: $ref: '#/definitions/product.GetUploadURLRequestDTO' produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/product.GetUploadURLResponseDTO' type: object "400": description: Invalid request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Access denied - not product owner schema: $ref: '#/definitions/response.StandardResponse' "404": description: Product not found schema: $ref: '#/definitions/response.StandardResponse' "500": description: Internal server error schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Generate presigned upload URL for product images tags: - Vendor Products /vendor/reviews: get: parameters: - default: 1 description: Page number in: query name: page type: integer - default: 20 description: Items per page in: query name: limit type: integer - description: Filter by status in: query name: status type: string produces: - application/json responses: "200": description: OK schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: List reviews for vendor's products tags: - Reviews - Vendor /vendor/reviews/{id}/reply: delete: parameters: - description: Review ID in: path name: id required: true type: string produces: - application/json responses: "200": description: OK schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Delete a vendor reply tags: - Reviews - Vendor post: consumes: - application/json parameters: - description: Review ID in: path name: id required: true type: string - description: Reply content in: body name: request required: true schema: $ref: '#/definitions/review.VendorReplyDTO' produces: - application/json responses: "201": description: Created schema: $ref: '#/definitions/response.StandardResponse' "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "409": description: Conflict schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Add a reply to a review tags: - Reviews - Vendor put: consumes: - application/json parameters: - description: Review ID in: path name: id required: true type: string - description: Updated reply content in: body name: request required: true schema: $ref: '#/definitions/review.VendorReplyDTO' produces: - application/json responses: "200": description: OK schema: $ref: '#/definitions/response.StandardResponse' "400": description: Bad Request schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' "403": description: Forbidden schema: $ref: '#/definitions/response.StandardResponse' "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Update a vendor reply tags: - Reviews - Vendor /vendor/reviews/pending: get: parameters: - default: 1 description: Page number in: query name: page type: integer - default: 20 description: Items per page in: query name: limit type: integer produces: - application/json responses: "200": description: OK schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Get reviews awaiting vendor response tags: - Reviews - Vendor /vendor/reviews/stats: get: produces: - application/json responses: "200": description: OK schema: $ref: '#/definitions/response.StandardResponse' "401": description: Unauthorized schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Get vendor's review statistics tags: - Reviews - Vendor /vendor/services/{service_id}/availability: delete: parameters: - description: Service UUID in: path name: service_id required: true type: string produces: - application/json responses: "204": description: No Content security: - BearerAuth: [] summary: Delete service availability schedule tags: - Availability get: parameters: - description: Service UUID in: path name: service_id required: true type: string produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/booking.AvailabilityResponse' type: object "404": description: Not Found schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: Get service availability schedule tags: - Availability put: consumes: - application/json parameters: - description: Service UUID in: path name: service_id required: true type: string - description: Weekly schedule in: body name: request required: true schema: $ref: '#/definitions/booking.SetScheduleRequest' produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/booking.AvailabilityResponse' type: object security: - BearerAuth: [] summary: Set service availability schedule tags: - Availability /vendor/services/{service_id}/availability/overrides: get: parameters: - description: Service UUID in: path name: service_id required: true type: string - description: Start date YYYY-MM-DD in: query name: from type: string - description: End date YYYY-MM-DD in: query name: to type: string produces: - application/json responses: "200": description: OK schema: $ref: '#/definitions/response.StandardResponse' security: - BearerAuth: [] summary: List date overrides (holidays, custom hours) tags: - Availability post: consumes: - application/json parameters: - description: Service UUID in: path name: service_id required: true type: string - description: Date override in: body name: request required: true schema: $ref: '#/definitions/booking.AddDateOverrideRequest' produces: - application/json responses: "201": description: Created schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/booking.DateOverrideResponse' type: object security: - BearerAuth: [] summary: Add date override tags: - Availability /vendor/services/{service_id}/availability/overrides/{override_id}: delete: responses: {} put: parameters: - description: Service UUID in: path name: service_id required: true type: string - description: Override UUID in: path name: override_id required: true type: string produces: - application/json responses: "204": description: No Content security: - BearerAuth: [] summary: Delete date override tags: - Availability /vendor/services/{service_id}/availability/pause: patch: parameters: - description: Service UUID in: path name: service_id required: true type: string produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/booking.AvailabilityResponse' type: object security: - BearerAuth: [] summary: Pause service availability (stop accepting new bookings) tags: - Availability /vendor/services/{service_id}/availability/resume: patch: parameters: - description: Service UUID in: path name: service_id required: true type: string produces: - application/json responses: "200": description: OK schema: allOf: - $ref: '#/definitions/response.StandardResponse' - properties: data: $ref: '#/definitions/booking.AvailabilityResponse' type: object security: - BearerAuth: [] summary: Resume service availability (re-enable new bookings) tags: - Availability securityDefinitions: BearerAuth: description: JWT Authorization header using the Bearer scheme in: header name: Authorization type: apiKey swagger: "2.0"