Files
backend/docs/website-api/AI_PROMPT.md
T
Alireza HassaniandCursor 7277817b6e Add store-item Excel export/import for bulk price and stock updates.
Dashboard can download grouped product variants and re-upload to update price and stock. Also expose Content-Disposition for downloads and keep related product/customer API docs in sync.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-19 01:02:43 +03:30

5.3 KiB
Raw Blame History

Meshkee Website API — AI / designer brief

Copy everything below into a new AI chat when building a Meshkee storefront.


System context (paste this)

You are building a Meshkee business website (storefront). You must use the Meshkee Website API only — never invent admin/CMS endpoints.

Canonical docs (always prefer these):

API base URL: https://api.meshkee.com/api/v1
(Optional alias if configured: https://api.<WEBSITE_DOMAIN>/api/v1 — same backend.)

This website’s apex domain: <WEBSITE_DOMAIN>
(example: sanihome.ir — no www., no api., no customer., no business.)

Hard rules

  1. Resolve tenant first: GET /tenants/<WEBSITE_DOMAIN> → save businessId from id.
  2. All public content uses /tenants/<WEBSITE_DOMAIN>/... (no auth).
  3. Cart, orders, favorites use /businesses/<businessId>/... with Authorization: Bearer <accessToken>.
  4. Customer register body must include "domain": "<WEBSITE_DOMAIN>". If the cell already exists on another Meshkee site and the password differs, API returns 409 with CELL_EXISTS_OTHER_SITE:.... Retry register with "acknowledgeExistingAccount": true to link that account (password/profile stay unchanged), then complete SMS OTP.
  5. Cell numbers are E.164 (+98912...).
  6. Do not call dashboard/CMS routes (/businesses/.../products write APIs, media upload, domain-admin, etc.).
  7. Partner SMS (POST /public/sms/send) is for external partner backends with an issued X-Api-Key only — not for normal storefront UI. See https://api.meshkee.com/docs/website/SMS.md

Typical bootstrap sequence

  1. GET /tenants/{domain} → branding + businessId
  2. Homepage: business-info, static-images, sliders, category-groups, brand-groups, store-specials
  3. Catalog: categories, products (GET /products/{slug} includes relatedProducts: same category then same brand, in-stock first), store-items (name instant search: in-stock first, then updatedAt), user-products (customer stock listings)
  4. Auth: register/login → store tokens. Optional: POST /auth/send-otp then POST /auth/login-otp (passwordless) or POST /auth/reset-password (forgot password). POST /auth/verify-otp only marks the cell verified (no tokens).
  5. Cart checkout with addressId or inline shippingAddress + payment
    • For online pay: payment.type = "e_payment_gate", gatewayType (e.g. "mellat" or "zarinpal"), and absolute returnUrl
    • Response includes payment.redirect { method, url, fields } — POST/redirect shopper to the bank
    • Bank callback hits API then redirects to returnUrl?status=success|failed&orderId=…
    • Enabled gateways: GET /tenants/{domain} → ePayment, or GET /businesses/{businessId}/payments/methods

User products (customer listings)

Public marketplace listings owned by customers — not catalog products.

  • GET /tenants/{domain}/user-products — list published (name/q, categoryId, cityId, countryId, condition, promoted, pagination)
  • GET /tenants/{domain}/user-products/{slug} — details + gallery
  • GET /tenants/{domain}/user-products/{slug}/technical-info — category form + values Use product categories from GET /tenants/{domain}/categories?entityType=product for filters. Creating/editing listings is customer-dashboard only (/businesses/.../my-user-products), not website-facing.

Static images

Named slots the business dashboard can replace. Fetch once per page:

  • GET /tenants/{domain}/website/static-images — all slots
  • GET /tenants/{domain}/website/static-images?pageKey=home — slots for one page (home, products, about, …)
  • GET /tenants/{domain}/website/static-images/{key} — one slot (e.g. home-hero)

Use slot.key in the placeholder. Match pageKey to the website page. For a single image: images[0]?.url. For a list: map images (if itemCount is set, that many images are expected). Each image may include titleFa, titleEn, subtext, and linkUrl. If linkUrl is set, wrap in <a href={linkUrl}>. Pick titleFa or titleEn from the site locale. If images is empty, keep the local fallback.

Also publish a slot catalog on this website so the business dashboard Refresh button can import keys from the main domain:

GET https://<WEBSITE_DOMAIN>/meshkee/static-image-slots

{
  "slots": [
    {
      "key": "slider",
      "label": "Homepage slider",
      "kind": "list",
      "pageKey": "home",
      "aspectRatio": "16:9",
      "itemCount": null,
      "recommendedWidth": 1440
    },
    {
      "key": "home-side-banner",
      "label": "Side banner",
      "kind": "single",
      "pageKey": "home",
      "aspectRatio": "12:19",
      "itemCount": 1,
      "recommendedWidth": 480
    }
  ]
}

kind is single (one image) or list (duplicatable). For a fixed row, set itemCount (e.g. 2). Leave itemCount null for an unbounded slider. aspectRatio must look like 16:9. Do not invent CMS/upload APIs.

If OpenAPI and this brief conflict, OpenAPI wins.


What to tell each website team

Replace <WEBSITE_DOMAIN> once per project. Everything else is global — same Postman, same OpenAPI, same base URL.