الملفات
back_end_oudelaa/docs/FRONTEND_INTEGRATION.md
boutmoun123 5bd5e19a89
فشلت بعض الفحوصات
/ deploy (push) Failing after 1m22s
feat: expand backend admin marketplace and scaling
2026-05-14 16:44:07 +03:00

249 أسطر
6.7 KiB
Markdown

# Frontend Integration
## Network setup
When testing from a phone or another device on the same LAN:
1. Set `HOST=0.0.0.0`
2. Set `PUBLIC_BASE_URL` to the machine IP, not `localhost`
3. Add frontend origins to `CORS_ORIGINS`
4. Keep `GOOGLE_CALLBACK_URL` on the same reachable host if Google auth is used
Example:
```env
HOST=0.0.0.0
PUBLIC_BASE_URL=http://192.168.1.12:4000
CORS_ORIGINS=http://192.168.1.12:3000,http://192.168.1.12:5173
GOOGLE_CALLBACK_URL=http://192.168.1.12:4000/api/v1/auth/google/callback
```
With `PUBLIC_BASE_URL` configured, file fields such as `avatar`, `coverImage`, `imageUrls`, `videoUrl`, `audioUrl`, `thumbnailUrl`, `mediaUrl`, and marketplace images are returned as absolute URLs.
## Pagination contract
List endpoints now keep the legacy fields and also return a unified `pagination` object.
Example:
```json
{
"items": [],
"count": 0,
"page": 1,
"limit": 20,
"total": 0,
"totalPages": 1,
"nextCursor": null,
"pagination": {
"mode": "offset",
"page": 1,
"limit": 20,
"count": 0,
"total": 0,
"totalPages": 1,
"hasNextPage": false,
"hasPreviousPage": false,
"nextPage": null,
"previousPage": null,
"currentCursor": null,
"nextCursor": null
}
}
```
Notes:
- Offset endpoints use `page` and `limit`
- Cursor-aware endpoints also return `nextCursor`
- Existing clients can keep reading the old top-level fields
- `sortOrder=asc|desc` is available on paginated endpoints
## Filter and sorting contract
Boolean query filters are parsed consistently now. Send:
- `?isActive=true`
- `?isActive=false`
- `?read=true`
- `?read=false`
- `?followingOnly=true`
Common conventions:
- `page`, `limit`, `sortOrder`
- `sortOrder` defaults to `desc`
- `sortBy` is supported on selected endpoints with endpoint-specific allowed values
Supported filters:
- `GET /marketplace/home`
- `listingsLimit`, `instrumentsLimit`, `repairShopsLimit`, `onlyActive`
- `GET /users`
- `q`, `isVerified`, `musicRole`, `experienceLevel`, `isPrivate`, `hasAvatar`, `sortBy`
- `sortBy`: `createdAt`, `name`, `username`, `followersCount`, `postsCount`
- `GET /users/discover`
- `q`, `musicRole`, `experienceLevel`, `hasAvatarOnly`, `includeRoleBuckets`, `sortBy`, `sortOrder`
- `GET /users/:id/profile-overview`
- returns `stats`, `contentCounts`, `tabs`, and `viewerState`
- `GET /posts/user/:userId`
- `visibility`, `postType`, `q`, `hashtag`, `sortBy`
- `sortBy`: `createdAt`, `updatedAt`, `likesCount`, `commentsCount`, `savesCount`, `shareCount`, `viewCount`, `playCount`
- `GET /posts/reels`
- `visibility`, `authorId`, `q`, `sortBy`
- `GET /marketplace/listings`
- `q`, `minPrice`, `maxPrice`, `isActive`, `listingCategory`, `condition`, `instrumentType`, `sortBy`
- `listingCategory`: `musical_instrument`, `accessory`, `audio_gear`, `sheet_music`, `other`
- `GET /marketplace/instruments`
- `q`, `minPrice`, `maxPrice`, `isActive`, `condition`, `instrumentType`, `sortBy`
- this route is now a musical-instruments-only view of marketplace listings
- `sortBy`: `createdAt`, `updatedAt`, `price`, `title`
- `GET /marketplace/repair-shops`
- `q`, `isActive`, `sortBy`
- `sortBy`: `createdAt`, `updatedAt`, `name`
- `GET /notifications`
- `read`, `type`, `resourceType`, `sortOrder`
- `GET /comments/post/:postId`
- `page`, `limit`, `sortOrder`
## WebSocket auth
Both namespaces accept the JWT access token in one of these places:
- `auth.token`
- `Authorization` header as `Bearer <token>`
## Chat namespace
Namespace: `/chat`
Client emits:
- `join_conversation`
- payload: `{ "conversationId": "..." }`
- `send_message`
- payload matches `SendMessageDto`
- `typing`
- payload: `{ "conversationId": "...", "isTyping": true }`
- `mark_seen`
- payload: `{ "messageId": "...", "conversationId": "..." }`
Server emits:
- `presence`
- payload: `{ "userId": "...", "online": true }`
- `joined_conversation`
- payload: `{ "conversationId": "..." }`
- `new_message`
- payload: message object
- `typing`
- payload: `{ "conversationId": "...", "userId": "...", "isTyping": true }`
- `message_seen`
- payload: `{ "messageId": "...", "userId": "..." }`
## Notifications namespace
Namespace: `/notifications`
Server emits:
- `notification_created`
- payload: notification object
- `notifications_unread_count`
- payload: `{ "unreadCount": 3 }`
Notification types currently used:
- `like`
- `comment`
- `follow`
- `message`
- `save`
- `share`
- `mention`
## Mentions
Posts and comments support:
- `taggedUserIds`: official tagged users by Mongo id
- `mentionUsernames`: usernames such as `["rami_sabry"]`
The backend also extracts `@username` from `content` automatically and emits mention notifications for matched users.
## Marketplace split
Marketplace is now separated from musical instruments at the API contract level:
- `GET /marketplace/listings`
- general sale listings across all listing categories
- `GET /marketplace/instruments`
- only musical instruments
- `GET /marketplace/repair-shops`
- service providers and maintenance shops
- `GET /marketplace/home`
- frontend-friendly grouped payload with `categories`, `summary`, `filters.listingCategories`, `featuredShops`, and `sections`
Admin endpoints follow the same split:
- `POST /marketplace/admin/listings`
- `GET /marketplace/admin/listings/me`
- `PATCH /marketplace/admin/listings/:id`
- `DELETE /marketplace/admin/listings/:id`
The older `/marketplace/admin/instruments*` routes still exist and always force `listingCategory=musical_instrument` for backward compatibility.
Marketplace shop ownership rule:
- each admin can own one repair-shop / marketplace shop record only
- if the admin already created one, the frontend should call update endpoints instead of create
Listing responses now also include:
- `shop`
- `{ adminId, name, username, avatar }`
- `storeName`
- direct shortcut for list cards
- `condition`
- `new`, `like_new`, `used`, `refurbished`
- `instrumentType`
- free-text type such as `oud`, `piano`, or `violin`
Search on marketplace listings now matches:
- listing title
- listing description
- instrument type
- shop name
## Talent discovery
The talents screen can now be built from:
- `GET /users/discover`
- paginated talent cards
- `roleBuckets` counts for tabs such as instrumentalists, singers, producers, and lyricists
- `GET /users/:id/profile-overview`
- summary for the profile header and tab counts
`profile-overview` returns:
- `stats.followersCount`
- `stats.followingCount`
- `stats.postsCount`
- `stats.collaborationsCount`
- `contentCounts.reels`
- `contentCounts.audio`
- `contentCounts.other`
- `viewerState.following`
## Smoke / e2e
Run:
```bash
npm run test:e2e
```
The smoke suite covers health, auth verification, profile setup, image upload, post creation, feed retrieval, notifications, and comment mentions.