import { initContract } from '@ts-rest/core'; import { z } from 'zod'; import { storefrontGetShopResponseSchema, storefrontCheckoutBodySchema, storefrontCheckoutResponseSchema, storefrontVerifyPaymentBodySchema, storefrontVerifyPaymentResponseSchema, storefrontPublicOrderSchema, storefrontMarketQuerySchema, storefrontMarketResponseSchema, storefrontDirectoryQuerySchema, storefrontListShopsResponseSchema, storefrontMarketSearchQuerySchema, storefrontMarketSearchResponseSchema, } from '../schemas/storefront.schemas'; import { errorResponseSchema } from '../schemas/common.schemas'; const c = initContract(); export const storefrontContract = c.router({ getMarket: { method: 'GET', path: '/storefront/market', query: storefrontMarketQuerySchema, responses: { 200: storefrontMarketResponseSchema, }, summary: 'Public marketplace home: featured shops and categories', }, listShops: { method: 'GET', path: '/storefront/shops', query: storefrontDirectoryQuerySchema, responses: { 200: storefrontListShopsResponseSchema, }, summary: 'Public shop directory with location and category filters', }, searchMarket: { method: 'GET', path: '/storefront/market/search', query: storefrontMarketSearchQuerySchema, responses: { 200: storefrontMarketSearchResponseSchema, }, summary: 'Cross-shop product search grouped by merchant', }, getShopBySlug: { method: 'GET', path: '/storefront/shops/:slug', pathParams: z.object({ slug: z.string().min(1).max(64) }), responses: { 200: storefrontGetShopResponseSchema, 404: errorResponseSchema, }, summary: 'Public storefront: shop profile and active catalog', }, checkout: { method: 'POST', path: '/storefront/shops/:slug/checkout', pathParams: z.object({ slug: z.string().min(1).max(64) }), body: storefrontCheckoutBodySchema, responses: { 200: storefrontCheckoutResponseSchema, 400: errorResponseSchema, 404: errorResponseSchema, 409: errorResponseSchema, }, summary: 'Create pending online order and initialize Paystack (split to shop subaccount)', }, getOrderById: { method: 'GET', path: '/storefront/orders/:id', pathParams: z.object({ id: z.string().uuid() }), query: z.object({ token: z.string().min(16) }), responses: { 200: storefrontPublicOrderSchema, 404: errorResponseSchema, }, summary: 'Public order tracking (token-gated)', }, verifyPayment: { method: 'POST', path: '/storefront/shops/:slug/verify-payment', pathParams: z.object({ slug: z.string().min(1).max(64) }), body: storefrontVerifyPaymentBodySchema, responses: { 200: storefrontVerifyPaymentResponseSchema, 400: errorResponseSchema, 404: errorResponseSchema, }, summary: 'Verify Paystack payment after redirect (fulfills order idempotently)', }, storefrontWebhookPaystack: { method: 'POST', path: '/storefront/webhook/paystack', body: z .object({ event: z.string().optional(), data: z .object({ reference: z.string().optional(), status: z.string().optional(), amount: z.number().optional(), }) .passthrough() .optional(), }) .passthrough(), responses: { 200: z.object({ received: z.boolean() }), 400: errorResponseSchema, }, summary: 'Paystack webhook for storefront orders', }, });