Cross-site register now updates the password to the signup value and documents passwordUpdated for storefronts. Co-authored-by: Cursor <cursoragent@cursor.com>
95 lines
5.5 KiB
Markdown
95 lines
5.5 KiB
Markdown
# 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):**
|
||
- Hub: https://api.meshkee.com/docs/website
|
||
- OpenAPI: https://api.meshkee.com/docs/website/openapi.json
|
||
- Postman: https://api.meshkee.com/docs/website/Meshkee-Website-API.postman_collection.json
|
||
|
||
**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 (profile unchanged; **password is replaced** with the new signup password), 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` + `specialProductsSource` (`product` or `store_item`)
|
||
2. Homepage: business-info, **static-images**, sliders, category-groups, brand-groups, store-specials (`source` repeats the tenant setting; items are store listings when `source` is `store_item`)
|
||
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`
|
||
|
||
```json
|
||
{
|
||
"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.
|