# Task: MoreRoute catalogue lists — ApiFeature pagination + Swagger + Figma

Copy/paste this file into a new Cursor chat and tell the agent: **execute this task end-to-end**.

Reference: `AGENTS.md` · `docs/PROJECT_ARCHITECTURE.md` · `docs/API_WORKFLOW.md` · `docs/SWAGGER_GUIDE.md` · `docs/TASK_TEMPLATE.md`

---

## Task Name

Paginate More/Home dashboard-managed catalogue lists (ApiFeature) and document them in Swagger with Figma links.

---

## Task Type

- [x] **API** — existing new-domain / shared More lookups · `AGENTS.md` § API Implementation Standard

---

## Pre-Flight (already verified)

| Check | Result |
|---|---|
| `GET /packages` | Exists — auth More route; was unpaginated |
| `GET /premium-packages` | **Did not exist** — add from `PremiumPackage` model (dashboard `/premiumPackages`) |
| `packagesAi` / AI packages model | **Does not exist** — do **not** invent a model; map Figma “packagesAi” to `GET /packages` (subscription packages) until a real AI-package domain is designed |
| `GET /countries` | **Did not exist** — add from `Country` model |
| `GET /regions` (cities) | Exists — unpaginated |
| `GET /reasons` | Exists — unpaginated |
| `GET /sliders` | Route exists on HomeRoute; **helper was missing** — implement via `Slider` (`sildersModel.js`) |
| `GET /intros` | Exists — unpaginated; Swagger existed without paginate |
| `GET /setting` | Exists — **single object**, no pagination |
| `GET /payments` | Exists — unpaginated |
| Reference pattern | `More.attributes` + `ApiFeature` + `validatePagination` / `validateAttributesList` |

**Verdict:** Modification of existing More/Home lists + two new public/auth list endpoints (`/countries`, `/premium-packages`). No new business domain models.

---

## Feature Scope

**IN**

1. Add `page`/`limit` validation + `ApiFeature` pagination to list endpoints that are dashboard-managed plural catalogues.
2. Wire new routes: `GET /premium-packages`, `GET /countries`.
3. Implement missing `Home.sliders`.
4. Swagger (YAML source + `public/api-docs/openapi.json`) with field examples matching `@returnObj` DTOs and Figma Mobile/Web links where provided.
5. i18n keys in **both** `ar` and `en` for new list messages.

**OUT**

- Inventing an AI-packages model/schema.
- Changing subscribe / charge / wallet flows.
- Paginate `GET /setting` (not a list).
- Paginate `GET /global` aggregate payload.
- Dashboard CRUD UI changes.
- New npm packages.

**Surface:** API `/api`  
**Actors:** guest (public lists) · authenticated client/provider (packages / premium-packages)

---

## What Should Be Implemented

### Pagination (ApiFeature) — response envelope

```json
{
  "key": "success",
  "message": "...",
  "status": 200,
  "data": [ /* DTO items */ ],
  "paginate": { "currentPage": 1, "lastPage": 1, "perPage": 20, "total": N }
}
```

Use `new ApiResponse(..., 'api', req, currentPage, lastPage, perPage, total)`.

Optional query: `page` (int ≥ 1), `limit` (int 1–100). Reuse / add `MoreValidator.validatePagination()` (attributes list can alias it).

| Endpoint | Auth | Model | Sort | returnObj / DTO | Figma |
|---|---|---|---|---|---|
| `GET /packages` | requireAuth (More.more) | `Package` | `price,duration` | `returnObject.package` + `currentPackage` / `renewButton` / `subscribeButton` / `expireAt` | Mobile `10792:109725` · Web `10792:112272` (packagesAi screens — used here until AI domain exists) |
| `GET /premium-packages` | requireAuth (More.more) | `PremiumPackage` | `price,duration` | `returnObject.package` | Mobile `9967:27997` · Web `10764:92406` |
| `GET /countries` | public | `Country` filter `status=active,isVisible=true` | default `createdAt:-1` | `returnObject.createBasicStructure` | — |
| `GET /regions` | public | `City` same filter | default | `createBasicStructure` | — |
| `GET /reasons` | public | `Reason` available | default | `{ id, name }` localized | Mobile `9967:25401` · Web `10760:87532` |
| `GET /sliders` | public (HomeRoute) | `Slider` `isActive=true` | default | `homeClientAppSlider` → `{ id, image, description }` | Mobile `9064:3213` · Web `10227:32828` |
| `GET /intros` | public | `Intro` | default | `introPages` | Client+Provider Mobile `9064:6157` |
| `GET /payments` | public | `PaymentMethod` `type=dashboard,status=available` | default | `payments` | none (brand “كم تسوي”) |
| `GET /setting` | public | `Setting.findOne` | N/A | `settings` — **document only**, no paginate | none |

### Shared helper (recommended)

In `src/helpers/api/More.js`, a small `sendPaginatedCatalogue({ req, res, lang, Model, filter, messagePhrase, mapItem, sort })` wrapping `ApiFeature` — same style as attributes.

### Swagger style (must mirror attributes / support.yaml)

- Description bullets + trailing `<div class="figma-links">…</div>`
- Parallel `x-figma: { mobile, mobileNodeId, web, webNodeId }`
- `page` / `limit` query params
- `200` example includes `data[]` **exact field names from returnObj** (no leftover `slug` on attributes; packages include UI flags)
- `paginate` block on list responses
- Update **both** `docs/openapi/paths/*.yaml` + `docs/openapi/openapi.yaml` schemas **and** `public/api-docs/openapi.json`

Figma base file: `mTRILiWaS8pzLcNnmAUr2k` (كم تسوي proto links provided by product).

---

## What Must Not Be Changed

- Stack / `package.json`
- `AppInitializer` structure
- ApiResponse / ApiError / errorHandler contracts
- Unrelated domains
- `.env`, certificates, CD
- Do not invent `packagesAi` model without analysis approval

---

## Files To Create

| File | Purpose |
|---|---|
| `docs/openapi/paths/lookups.yaml` | packages, premium-packages, countries, regions, reasons, sliders, payments, setting |
| `AI/Prompts/MoreCataloguePagination.md` | this prompt (optional location) |

## Files To Modify

| File | Change |
|---|---|
| `src/helpers/api/More.js` | paginate helpers; `getPackages`, `getPremiumPackages`, `reasons`, `payments`, `intros`, `regions`, `countries` |
| `src/helpers/api/Home.js` | implement `sliders` |
| `src/routes/api/MoreRoute/MoreRoute.js` | validation chains; `/premium-packages`; `/countries`; paginated `/regions` |
| `src/routes/api/HomeRoute/HomeRoute.js` | pagination validation on `/sliders` |
| `src/controllers/api/moreController.js` | `getPremiumPackages`, `countries` |
| `src/utils/validations/api/more.js` | `validatePagination` |
| `src/utils/validations/api/home.js` | `validatePagination` |
| `src/locales/ar/more.json` + `en/more.json` | `premiumPackagesList`, `countriesList`, `citiesList`, `slidersList` |
| `docs/openapi/openapi.yaml` | path refs + schemas |
| `docs/openapi/paths/info.yaml` | intros → paginated + dual mobile figma |
| `public/api-docs/openapi.json` | bundled sync |
| `docs/openapi/README.md` | list new endpoints (optional) |

---

## Implementation Plan

1. Add `sendPaginatedCatalogue` + convert list helpers.
2. Keep package subscription flag logic after paginating the `Package` query.
3. Wire routes + thin controller methods + validators.
4. Implement `Home.sliders`.
5. i18n keys both locales.
6. Swagger YAML then sync `openapi.json` (same description/example style as attributes).
7. Smoke: `node --check` on touched JS; load `openapi.json`.
8. Manual QA notes in Final Report.

---

## Validation Rules

| Field | Rule |
|---|---|
| `page` | optional int ≥ 1 → `.toInt()` |
| `limit` | optional int 1–100 → `.toInt()` |
| Messages | `more.pageInvalid` / `more.limitInvalid` |

---

## Security Rules

- Public lists: `SecretKeyAuth` only in Swagger; no bearer required in code (unRequireAuthRoutes).
- `/packages` and `/premium-packages`: stay behind existing More `requireAuth` mount; filter by `userType` for store/haraj when present.
- Never return OTP/passwords/tokens.
- No raw Mongoose documents — always map via returnObj / explicit DTO.

---

## Manual QA

1. `GET /api/reasons?page=1&limit=2` → `paginate.perPage === 2`, `data.length ≤ 2`.
2. `GET /api/regions?page=1&limit=1` → paginate present.
3. `GET /api/countries?page=1` → 200 + paginate.
4. `GET /api/payments?page=1` → DTO `{ id, name, slug, image }`.
5. `GET /api/intros?page=1` → DTO `{ id, title, description, image }` + paginate.
6. `GET /api/sliders?page=1` → DTO `{ id, image, description }` (helper no longer missing).
7. Auth `GET /api/packages?page=1` → flags present + paginate.
8. Auth `GET /api/premium-packages?page=1` → premium list + paginate.
9. `GET /api/setting` → object, **no** paginate.
10. Open `/api-docs` — Lookups shows packages / premium / reasons / sliders, while intros remains under Common; all supplied Figma links are visible.

---

## Definition of Done

- [ ] All plural dashboard catalogues above paginate via ApiFeature
- [ ] `/premium-packages` and `/countries` registered
- [ ] `/sliders` helper implemented
- [ ] Swagger YAML + openapi.json updated for touched endpoints only
- [ ] Figma links present where provided
- [ ] i18n ar+en
- [ ] No invented AI-package model
- [ ] Final report filled

---

## Final Report (agent fills after execution)

1. Files inspected:
2. Files created:
3. Files modified:
4. Endpoints added/changed:
5. Validation rules:
6. Documentation updates:
7. Security checks:
8. Manual QA steps:
9. Automated test results:
10. Not implemented and why: **packagesAi as separate domain** — no model; Figma attached to `GET /packages` instead.
