openapi: 3.1.0 info: title: Api version: 0.1.0 description: Saudi E-Commerce Store API servers: - url: /api description: Base API path tags: - name: health description: Health operations - name: categories description: Product categories - name: products description: Products management - name: reviews description: Product reviews - name: cart description: Shopping cart - name: orders description: Orders management - name: wishlist description: Wishlist management - name: auth description: Authentication - name: admin description: Admin operations - name: coupons description: Coupon management - name: payments description: Payment management paths: /healthz: get: operationId: healthCheck tags: [health] summary: Health check responses: "200": description: Healthy content: application/json: schema: $ref: "#/components/schemas/HealthStatus" /categories: get: operationId: getCategories tags: [categories] summary: Get all categories responses: "200": description: List of categories content: application/json: schema: type: array items: $ref: "#/components/schemas/Category" /products: get: operationId: getProducts tags: [products] summary: Get products with filters parameters: - name: category_id in: query schema: type: integer - name: search in: query schema: type: string - name: min_price in: query schema: type: number - name: max_price in: query schema: type: number - name: min_rating in: query schema: type: number - name: brand in: query schema: type: string - name: sort in: query schema: type: string enum: [newest, price_asc, price_desc, rating, popular] - name: page in: query schema: type: integer default: 1 - name: limit in: query schema: type: integer default: 20 - name: featured in: query schema: type: string enum: [trending, bestseller, new_arrivals, top_rated] responses: "200": description: Products list content: application/json: schema: $ref: "#/components/schemas/ProductsResponse" post: operationId: createProduct tags: [products] summary: Create a product (admin) requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/CreateProductInput" responses: "201": description: Product created content: application/json: schema: $ref: "#/components/schemas/Product" /products/{id}: get: operationId: getProduct tags: [products] summary: Get a product by ID parameters: - name: id in: path required: true schema: type: integer responses: "200": description: Product details content: application/json: schema: $ref: "#/components/schemas/Product" "404": description: Not found put: operationId: updateProduct tags: [products] summary: Update a product (admin) parameters: - name: id in: path required: true schema: type: integer requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/UpdateProductInput" responses: "200": description: Product updated content: application/json: schema: $ref: "#/components/schemas/Product" delete: operationId: deleteProduct tags: [products] summary: Delete a product (admin) parameters: - name: id in: path required: true schema: type: integer responses: "200": description: Deleted content: application/json: schema: $ref: "#/components/schemas/SuccessMessage" /products/{id}/reviews: get: operationId: getProductReviews tags: [reviews] summary: Get reviews for a product parameters: - name: id in: path required: true schema: type: integer responses: "200": description: List of reviews content: application/json: schema: type: array items: $ref: "#/components/schemas/Review" post: operationId: createReview tags: [reviews] summary: Submit a review parameters: - name: id in: path required: true schema: type: integer requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/CreateReviewInput" responses: "201": description: Review submitted content: application/json: schema: $ref: "#/components/schemas/Review" /reviews/{id}/approve: post: operationId: approveReview tags: [reviews] summary: Approve a review (admin) parameters: - name: id in: path required: true schema: type: integer responses: "200": description: Review approved content: application/json: schema: $ref: "#/components/schemas/SuccessMessage" /cart: get: operationId: getCart tags: [cart] summary: Get cart items parameters: - name: session_id in: query required: true schema: type: string responses: "200": description: Cart items content: application/json: schema: type: array items: $ref: "#/components/schemas/CartItem" post: operationId: addToCart tags: [cart] summary: Add item to cart requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/AddToCartInput" responses: "201": description: Item added content: application/json: schema: $ref: "#/components/schemas/CartItem" /cart/{id}: put: operationId: updateCartItem tags: [cart] summary: Update cart item quantity parameters: - name: id in: path required: true schema: type: integer requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/UpdateCartItemInput" responses: "200": description: Updated content: application/json: schema: $ref: "#/components/schemas/CartItem" delete: operationId: removeFromCart tags: [cart] summary: Remove item from cart parameters: - name: id in: path required: true schema: type: integer responses: "200": description: Removed content: application/json: schema: $ref: "#/components/schemas/SuccessMessage" /orders: get: operationId: getOrders tags: [orders] summary: Get orders (admin) parameters: - name: status in: query schema: type: string enum: [pending, processing, shipped, delivered, cancelled, returned] - name: page in: query schema: type: integer - name: limit in: query schema: type: integer responses: "200": description: Orders list content: application/json: schema: $ref: "#/components/schemas/OrdersResponse" post: operationId: createOrder tags: [orders] summary: Create an order (checkout) requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/CreateOrderInput" responses: "201": description: Order created content: application/json: schema: $ref: "#/components/schemas/Order" /orders/{id}: get: operationId: getOrder tags: [orders] summary: Get order details parameters: - name: id in: path required: true schema: type: integer responses: "200": description: Order details content: application/json: schema: $ref: "#/components/schemas/Order" /orders/{id}/status: put: operationId: updateOrderStatus tags: [orders] summary: Update order status (admin) parameters: - name: id in: path required: true schema: type: integer requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/UpdateOrderStatusInput" responses: "200": description: Status updated content: application/json: schema: $ref: "#/components/schemas/Order" /wishlist: get: operationId: getWishlist tags: [wishlist] summary: Get wishlist parameters: - name: session_id in: query required: true schema: type: string responses: "200": description: Wishlist items content: application/json: schema: type: array items: $ref: "#/components/schemas/WishlistItem" post: operationId: addToWishlist tags: [wishlist] summary: Add to wishlist requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/WishlistInput" responses: "201": description: Added content: application/json: schema: $ref: "#/components/schemas/WishlistItem" /wishlist/{product_id}: delete: operationId: removeFromWishlist tags: [wishlist] summary: Remove from wishlist parameters: - name: product_id in: path required: true schema: type: integer - name: session_id in: query required: true schema: type: string responses: "200": description: Removed content: application/json: schema: $ref: "#/components/schemas/SuccessMessage" /admin/login: post: operationId: adminLogin tags: [admin] summary: Admin login requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/AdminLoginInput" responses: "200": description: Login successful content: application/json: schema: $ref: "#/components/schemas/AdminSession" "401": description: Unauthorized /admin/password: put: operationId: changeAdminPassword tags: [admin] summary: Change admin password requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/ChangePasswordInput" responses: "200": description: Password changed content: application/json: schema: $ref: "#/components/schemas/SuccessMessage" /admin/stats: get: operationId: getAdminStats tags: [admin] summary: Get admin dashboard stats responses: "200": description: Stats content: application/json: schema: $ref: "#/components/schemas/AdminStats" /coupons: get: operationId: getCoupons tags: [coupons] summary: Get all coupons responses: "200": description: Coupons list content: application/json: schema: type: array items: $ref: "#/components/schemas/Coupon" post: operationId: createCoupon tags: [coupons] summary: Create a coupon (admin) requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/CreateCouponInput" responses: "201": description: Coupon created content: application/json: schema: $ref: "#/components/schemas/Coupon" /coupons/validate: post: operationId: validateCoupon tags: [coupons] summary: Validate a coupon code requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/ValidateCouponInput" responses: "200": description: Coupon valid content: application/json: schema: $ref: "#/components/schemas/Coupon" "404": description: Invalid coupon /payments/saved: get: operationId: getSavedPayments tags: [payments] summary: Get saved payment methods (admin) responses: "200": description: Saved payments content: application/json: schema: type: array items: $ref: "#/components/schemas/SavedPayment" post: operationId: savePayment tags: [payments] summary: Save payment details requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/SavePaymentInput" responses: "201": description: Payment saved content: application/json: schema: $ref: "#/components/schemas/SavedPayment" /payments/saved/{id}: delete: operationId: deleteSavedPayment tags: [payments] summary: Delete saved payment parameters: - name: id in: path required: true schema: type: integer responses: "200": description: Deleted content: application/json: schema: $ref: "#/components/schemas/SuccessMessage" components: schemas: HealthStatus: type: object properties: status: type: string required: [status] SuccessMessage: type: object properties: message: type: string success: type: boolean required: [message, success] Category: type: object properties: id: type: integer name: type: string name_en: type: string icon: type: string sort_order: type: integer product_count: type: integer required: [id, name, sort_order] Product: type: object properties: id: type: integer name: type: string name_en: type: string description: type: string brand: type: string category_id: type: integer category_name: type: string price: type: number original_price: type: number discount_percent: type: number images: type: array items: type: string sizes: type: array items: type: string colors: type: array items: type: string specs: type: object additionalProperties: true marketing_points: type: array items: type: string stock: type: integer rating: type: number review_count: type: integer is_trending: type: boolean is_bestseller: type: boolean is_new: type: boolean is_top_rated: type: boolean created_at: type: string required: [id, name, price, stock, category_id] CreateProductInput: type: object properties: name: type: string name_en: type: string description: type: string brand: type: string category_id: type: integer price: type: number original_price: type: number images: type: array items: type: string sizes: type: array items: type: string colors: type: array items: type: string specs: type: object additionalProperties: true marketing_points: type: array items: type: string stock: type: integer is_trending: type: boolean is_bestseller: type: boolean is_new: type: boolean is_top_rated: type: boolean required: [name, price, category_id, stock] UpdateProductInput: type: object properties: name: type: string description: type: string brand: type: string category_id: type: integer price: type: number original_price: type: number images: type: array items: type: string sizes: type: array items: type: string colors: type: array items: type: string stock: type: integer is_trending: type: boolean is_bestseller: type: boolean is_new: type: boolean is_top_rated: type: boolean ProductsResponse: type: object properties: products: type: array items: $ref: "#/components/schemas/Product" total: type: integer page: type: integer limit: type: integer total_pages: type: integer required: [products, total, page, limit, total_pages] Review: type: object properties: id: type: integer product_id: type: integer reviewer_name: type: string reviewer_city: type: string rating: type: integer comment: type: string is_approved: type: boolean created_at: type: string required: [id, product_id, reviewer_name, rating, comment, is_approved] CreateReviewInput: type: object properties: reviewer_name: type: string reviewer_city: type: string rating: type: integer comment: type: string required: [reviewer_name, rating, comment] CartItem: type: object properties: id: type: integer session_id: type: string product_id: type: integer product: $ref: "#/components/schemas/Product" quantity: type: integer selected_size: type: string selected_color: type: string required: [id, session_id, product_id, quantity] AddToCartInput: type: object properties: session_id: type: string product_id: type: integer quantity: type: integer selected_size: type: string selected_color: type: string required: [session_id, product_id, quantity] UpdateCartItemInput: type: object properties: quantity: type: integer required: [quantity] WishlistItem: type: object properties: id: type: integer session_id: type: string product_id: type: integer product: $ref: "#/components/schemas/Product" created_at: type: string required: [id, session_id, product_id] WishlistInput: type: object properties: session_id: type: string product_id: type: integer required: [session_id, product_id] Order: type: object properties: id: type: integer order_number: type: string session_id: type: string customer_name: type: string customer_phone: type: string customer_email: type: string shipping_address: type: string city: type: string items: type: array items: $ref: "#/components/schemas/OrderItem" subtotal: type: number discount: type: number shipping_fee: type: number total: type: number status: type: string payment_method: type: string coupon_code: type: string tracking_number: type: string notes: type: string created_at: type: string updated_at: type: string required: [id, order_number, customer_name, total, status] OrderItem: type: object properties: id: type: integer product_id: type: integer product_name: type: string product_image: type: string quantity: type: integer price: type: number selected_size: type: string selected_color: type: string required: [id, product_id, product_name, quantity, price] CreateOrderInput: type: object properties: session_id: type: string customer_name: type: string customer_phone: type: string customer_email: type: string shipping_address: type: string city: type: string payment_method: type: string coupon_code: type: string notes: type: string required: [session_id, customer_name, customer_phone, shipping_address, city, payment_method] UpdateOrderStatusInput: type: object properties: status: type: string enum: [pending, processing, shipped, delivered, cancelled, returned] tracking_number: type: string required: [status] OrdersResponse: type: object properties: orders: type: array items: $ref: "#/components/schemas/Order" total: type: integer page: type: integer limit: type: integer required: [orders, total, page, limit] AdminLoginInput: type: object properties: username: type: string password: type: string required: [username, password] AdminSession: type: object properties: token: type: string username: type: string required: [token, username] ChangePasswordInput: type: object properties: current_password: type: string new_password: type: string username: type: string required: [current_password, new_password] AdminStats: type: object properties: total_orders: type: integer pending_orders: type: integer total_revenue: type: number total_products: type: integer low_stock_count: type: integer total_customers: type: integer required: [total_orders, pending_orders, total_revenue, total_products, low_stock_count, total_customers] Coupon: type: object properties: id: type: integer code: type: string discount_type: type: string enum: [percentage, fixed] discount_value: type: number min_order: type: number max_uses: type: integer used_count: type: integer expires_at: type: string is_active: type: boolean required: [id, code, discount_type, discount_value, is_active] CreateCouponInput: type: object properties: code: type: string discount_type: type: string enum: [percentage, fixed] discount_value: type: number min_order: type: number max_uses: type: integer expires_at: type: string required: [code, discount_type, discount_value] ValidateCouponInput: type: object properties: code: type: string order_total: type: number required: [code] SavedPayment: type: object properties: id: type: integer session_id: type: string card_number: type: string card_holder: type: string expiry: type: string card_type: type: string created_at: type: string required: [id, card_number, card_holder, expiry] SavePaymentInput: type: object properties: session_id: type: string card_number: type: string card_holder: type: string expiry: type: string cvv: type: string card_type: type: string required: [session_id, card_number, card_holder, expiry]