Skip to content

Commit 0bc7465

Browse files
committed
Merge branch 'main' of github.com:anonymousc/ft_transcendance-42
2 parents 00b15a0 + 542d375 commit 0bc7465

13 files changed

Lines changed: 306 additions & 112 deletions

File tree

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -407,7 +407,7 @@ make all
407407
- Review Places: `http://localhost:4001` (`/reviews*`, `/health`)
408408
- Fav Places: `http://localhost:4002` (`/fav-places*`, `/health`)
409409
- Planner: `http://localhost:7000` (`/plan*`, `/plans`, `/health`)
410-
- Friends: `http://localhost:4003` (REST; WebSockets published as `8181`/`8182` in compose for chat/notifications)
410+
- Friends: `http://localhost:4003` (REST under `/api/friends`, `/api/chat`, `/api/notifications`; WebSockets `8181`/`8182` in compose for chat/notifications)
411411
- Swagger UI: `http://localhost:8080`
412412
- Vault: `http://localhost:${PORT_VAULT}` (default `http://localhost:8200`)
413413

@@ -462,7 +462,7 @@ docker compose -f docker-compose.yml build <service_name> --no-cache
462462
| **review-places** | `http://localhost:4001` | `GET /health`, `GET /reviews`, `GET /reviews/summary`, `POST /reviews/batch`, `POST/PATCH/DELETE /reviews/*` | Reviews + rating aggregates ||
463463
| **fav-places** | `http://localhost:4002` | `GET /health`, `GET/POST /fav-places`, `GET /fav-places/check`, `GET /fav-places/public/:userId`, `GET /fav-places/internal/:userId` | Favorites + visited places ||
464464
| **planner-service** | `http://localhost:7000` | `GET /health`, `POST /plan/generate`, `GET /plan/:id`, `GET /plans`, `DELETE /plan/:id` | AI trip planning (Gemini) + persistence ||
465-
| **friends-service** | `http://localhost:4003` | REST + WebSocket **8181** (chat) / **8182** (notifications) in Docker | Friends, chat token, realtime (see `friendsApi`, `useWebSocket`) ||
465+
| **friends-service** | `http://localhost:4003` | `/api/friends/*`, `/api/chat/*`, `/api/notifications/*` + WebSocket **8181** (chat) / **8182** (notifications) in Docker | Friends, chat token, realtime (see `friendsApi`, `useWebSocket`) ||
466466

467467
### Planned / evolving
468468

backend/devops/backend-services/security/modsecurity/default.conf

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -153,15 +153,15 @@ server {
153153
proxy_pass http://fav_places_upstream;
154154
}
155155

156-
location /friends {
156+
location /api/friends {
157157
proxy_pass http://friends_api_upstream;
158158
}
159159

160-
location /chat/ {
160+
location /api/chat/ {
161161
proxy_pass http://friends_api_upstream;
162162
}
163163

164-
location /notifications/ {
164+
location /api/notifications {
165165
proxy_pass http://friends_api_upstream;
166166
}
167167

backend/devops/data/friends-chat.asyncapi.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,12 @@ info:
66
Real-time chat over raw WebSocket (`ws` library). Same JWT access token as REST (`JWT_ACCESS_SECRET`, payload `sub` = user id).
77
88
**Connect:** `ws://<host>:<WS_PORT>/?token=<access_jwt>`
9-
Browsers cannot read the httpOnly `access_token` cookie; obtain a short-lived JWT via **`GET /chat/ws-token`** (same cookie or `Authorization: Bearer` as other `/chat` routes), then pass `data.token` in the query string.
9+
Browsers cannot read the httpOnly `access_token` cookie; obtain a short-lived JWT via **`GET /api/chat/ws-token`** (same cookie or `Authorization: Bearer` as other `/api/chat` routes), then pass `data.token` in the query string.
1010
Default **WS_PORT** is `8181` (see `friends-service` env / Docker Compose).
1111
1212
Every frame is a single **JSON object** with a `type` string. Invalid JSON yields an `error` message when parsing is attempted on a text frame.
1313
14-
Messages created via **HTTP** `POST /chat/conversations/:id/messages` (or the WebSocket `message` command) are pushed to participant sockets with `type: message`, and the service creates **in-app notifications** for other participants (see REST `/notifications` and `friends-notifications.asyncapi.yaml`).
14+
Messages created via **HTTP** `POST /api/chat/conversations/:id/messages` (or the WebSocket `message` command) are pushed to participant sockets with `type: message`, and the service creates **in-app notifications** for other participants (see REST `/api/notifications` and `friends-notifications.asyncapi.yaml`).
1515
1616
license:
1717
name: MIT

backend/devops/data/friends-notifications.asyncapi.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ components:
7373
ServerNotificationArchived:
7474
name: ServerNotificationArchived
7575
title: Notification archived
76-
summary: Emitted when `PATCH /notifications/archive` succeeds
76+
summary: Emitted when `PATCH /api/notifications/archive` succeeds
7777
payload:
7878
$ref: '#/components/schemas/ServerNotificationArchivedPayload'
7979
ServerHandshakeError:

backend/devops/data/swagger.json

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"openapi": "3.0.3",
33
"info": {
44
"title": "Rihla backend APIs",
5-
"description": "OpenAPI documentation. Friends service runs on port 4003 (host) or `friends:4003` inside Docker Compose.\n\n**WebSocket chat** (port 8181 by default) is in `friends-chat.asyncapi.yaml`. **Notification WebSocket** (port 8182 by default) is in `friends-notifications.asyncapi.yaml`. Open either file from this folder in [AsyncAPI Studio](https://studio.asyncapi.com/) (File → Load file), or mount the same directory in any AsyncAPI viewer.",
5+
"description": "OpenAPI documentation. Friends service runs on port 4003 (host) or `friends:4003` inside Docker Compose. HTTP REST is mounted at **`/api/friends`**, **`/api/chat`**, and **`/api/notifications`** (see paths below).\n\n**WebSocket chat** (port 8181 by default) is in `friends-chat.asyncapi.yaml`. **Notification WebSocket** (port 8182 by default) is in `friends-notifications.asyncapi.yaml`. Open either file from this folder in [AsyncAPI Studio](https://studio.asyncapi.com/) (File → Load file), or mount the same directory in any AsyncAPI viewer.",
66
"version": "1.0.0"
77
},
88
"servers": [
@@ -22,11 +22,11 @@
2222
},
2323
{
2424
"name": "Chat",
25-
"description": "Direct messages between friends (friends-service, `/chat`)"
25+
"description": "Direct messages between friends (friends-service, `/api/chat`)"
2626
},
2727
{
2828
"name": "Notifications",
29-
"description": "In-app notifications (friends-service, `/notifications`); real-time delivery on WebSocket port 8182"
29+
"description": "In-app notifications (friends-service, `/api/notifications`); real-time delivery on WebSocket port 8182"
3030
}
3131
],
3232
"components": {
@@ -188,7 +188,7 @@
188188
},
189189
"Notification": {
190190
"type": "object",
191-
"description": "Persisted row; `GET /notifications` omits archived notifications.",
191+
"description": "Persisted row; `GET /api/notifications` omits archived notifications.",
192192
"properties": {
193193
"id": { "type": "string", "description": "Cuid" },
194194
"userId": { "type": "string" },
@@ -231,7 +231,7 @@
231231
}
232232
},
233233
"paths": {
234-
"/friends": {
234+
"/api/friends": {
235235
"get": {
236236
"tags": ["Friends"],
237237
"summary": "List friends",
@@ -270,7 +270,7 @@
270270
}
271271
}
272272
},
273-
"/friends/{userId}": {
273+
"/api/friends/{userId}": {
274274
"get": {
275275
"tags": ["Friends"],
276276
"summary": "Get one friend",
@@ -354,7 +354,7 @@
354354
}
355355
}
356356
},
357-
"/friends/requests/incoming": {
357+
"/api/friends/requests/incoming": {
358358
"get": {
359359
"tags": ["Friends"],
360360
"summary": "List incoming friend requests",
@@ -392,7 +392,7 @@
392392
}
393393
}
394394
},
395-
"/friends/requests/outgoing": {
395+
"/api/friends/requests/outgoing": {
396396
"get": {
397397
"tags": ["Friends"],
398398
"summary": "List outgoing friend requests",
@@ -430,7 +430,7 @@
430430
}
431431
}
432432
},
433-
"/friends/requests": {
433+
"/api/friends/requests": {
434434
"post": {
435435
"tags": ["Friends"],
436436
"summary": "Send friend request",
@@ -492,7 +492,7 @@
492492
}
493493
}
494494
},
495-
"/friends/requests/{requestId}/accept": {
495+
"/api/friends/requests/{requestId}/accept": {
496496
"post": {
497497
"tags": ["Friends"],
498498
"summary": "Accept friend request",
@@ -534,7 +534,7 @@
534534
}
535535
}
536536
},
537-
"/friends/requests/{requestId}": {
537+
"/api/friends/requests/{requestId}": {
538538
"delete": {
539539
"tags": ["Friends"],
540540
"summary": "Cancel or decline friend request",
@@ -577,7 +577,7 @@
577577
}
578578
}
579579
},
580-
"/chat/conversations": {
580+
"/api/chat/conversations": {
581581
"get": {
582582
"tags": ["Chat"],
583583
"summary": "List my conversations",
@@ -674,7 +674,7 @@
674674
}
675675
}
676676
},
677-
"/chat/conversations/{conversationId}/messages": {
677+
"/api/chat/conversations/{conversationId}/messages": {
678678
"get": {
679679
"tags": ["Chat"],
680680
"summary": "List messages in a conversation",
@@ -813,7 +813,7 @@
813813
}
814814
}
815815
},
816-
"/notifications": {
816+
"/api/notifications": {
817817
"get": {
818818
"tags": ["Notifications"],
819819
"summary": "List notifications",
@@ -852,7 +852,7 @@
852852
}
853853
}
854854
},
855-
"/notifications/read": {
855+
"/api/notifications/read": {
856856
"patch": {
857857
"tags": ["Notifications"],
858858
"summary": "Mark one notification read",
@@ -913,7 +913,7 @@
913913
}
914914
}
915915
},
916-
"/notifications/readAll": {
916+
"/api/notifications/readAll": {
917917
"patch": {
918918
"tags": ["Notifications"],
919919
"summary": "Mark all notifications read",
@@ -949,11 +949,11 @@
949949
}
950950
}
951951
},
952-
"/notifications/archive": {
952+
"/api/notifications/archive": {
953953
"patch": {
954954
"tags": ["Notifications"],
955955
"summary": "Archive a notification",
956-
"description": "Hides the row from `GET /notifications` and emits `notification_archived` on the notification WebSocket. Query `id` required.",
956+
"description": "Hides the row from `GET /api/notifications` and emits `notification_archived` on the notification WebSocket. Query `id` required.",
957957
"security": [{ "bearerAuth": [] }],
958958
"parameters": [
959959
{

backend/src/friends-service/src/server.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,9 @@ app.get('/health', (_req, res) =>
2424
res.json({ status: 'ok', service: 'friends-service' }),
2525
);
2626

27-
app.use('/friends', friendsRouter);
28-
app.use('/chat', chatRouter);
29-
app.use('/notifications', notificationsRouter);
27+
app.use('/api/friends', friendsRouter);
28+
app.use('/api/chat', chatRouter);
29+
app.use('/api/notifications', notificationsRouter);
3030
app.listen(PORT, () => {
3131
console.log(`Friends service running on port ${PORT}`);
3232
});

frontend/BACKEND_HANDOFF.md

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,25 +4,25 @@
44

55
| Endpoint | Method | Purpose | Request | Response |
66
|---|---|---|---|---|
7-
| `/conversations` | GET | List conversations for current user | `Authorization: Bearer <token>` | `Conversation[]` |
8-
| `/conversations/:id/messages` | GET | Fetch message history | `?limit=N&before=<cursor>` | `Message[]` |
9-
| `/conversations/:id/messages` | POST | Send a message | `{ content: string }` | `Message` (server-assigned `id`, `timestamp`, `status: "sent"`) |
7+
| `/api/chat/conversations` | GET | List conversations for current user | `Authorization: Bearer <token>` | `Conversation[]` |
8+
| `/api/chat/conversations/:id/messages` | GET | Fetch message history | `?limit=N&before=<cursor>` | `Message[]` |
9+
| `/api/chat/conversations/:id/messages` | POST | Send a message | `{ content: string }` | `Message` (server-assigned `id`, `timestamp`, `status: "sent"`) |
1010

1111
### Friends
1212

1313
| Endpoint | Method | Purpose | Request | Response |
1414
|---|---|---|---|---|
15-
| `/friends` | GET | List current user's friends | `Authorization: Bearer <token>` | `Friend[]` |
16-
| `/friends/:id` | GET | Get single friend profile || `Friend` |
17-
| `/friends/:id` | DELETE | Remove friend || `204` |
15+
| `/api/friends` | GET | List current user's friends | `Authorization: Bearer <token>` | `Friend[]` |
16+
| `/api/friends/:id` | GET | Get single friend profile || `Friend` |
17+
| `/api/friends/:id` | DELETE | Remove friend || `204` |
1818

1919
### Notifications
2020

2121
| Endpoint | Method | Purpose | Request | Response |
2222
|---|---|---|---|---|
23-
| `/notifications` | GET | List all notifications | `Authorization: Bearer <token>` | `Notification[]` |
24-
| `/notifications/:id/read` | PATCH | Mark single notification as read || `204` |
25-
| `/notifications/read-all` | PATCH | Mark all as read || `204` |
23+
| `/api/notifications` | GET | List all notifications | `Authorization: Bearer <token>` | `Notification[]` |
24+
| `/api/notifications/read?id=` | PATCH | Mark single notification as read || `204` |
25+
| `/api/notifications/readAll` | PATCH | Mark all as read || `204` |
2626

2727
---
2828

@@ -96,12 +96,12 @@
9696

9797
| File | What | Replace With |
9898
|---|---|---|
99-
| `features/chat/components/Webchat.tsx` lines 34–69 | `MOCK_CONVERSATIONS` | `GET /conversations` |
100-
| `features/chat/components/Webchat.tsx` lines 72–331 | `MOCK_MESSAGES` | `GET /conversations/:id/messages` |
99+
| `features/chat/components/Webchat.tsx` lines 34–69 | `MOCK_CONVERSATIONS` | `GET /api/chat/conversations` |
100+
| `features/chat/components/Webchat.tsx` lines 72–331 | `MOCK_MESSAGES` | `GET /api/chat/conversations/:id/messages` |
101101
| `features/chat/components/Webchat.tsx` lines 407–416 | `setTimeout` faking delivery | WebSocket `message:send` + `message:status` |
102-
| `features/friends/components/FriendsPage.tsx` lines 12–19 | `MOCK_FRIENDS` | `GET /friends` |
103-
| `features/notifications/NotificationPage.tsx` lines 7–19 | `MOCK_NOTIFICATIONS` | `GET /notifications` |
104-
| `features/chat/components/ContactPanel.tsx` line 65 | `onRemoveFriend` empty callback | `DELETE /friends/:id` |
102+
| `features/friends/components/FriendsPage.tsx` lines 12–19 | `MOCK_FRIENDS` | `GET /api/friends` |
103+
| `features/notifications/NotificationPage.tsx` lines 7–19 | `MOCK_NOTIFICATIONS` | `GET /api/notifications` |
104+
| `features/chat/components/ContactPanel.tsx` line 65 | `onRemoveFriend` empty callback | `DELETE /api/friends/:id` |
105105

106106
---
107107

frontend/src/features/chat/types.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ export interface Conversation {
2626

2727
export type ConnectionState = "connecting" | "connected" | "disconnected" | "error";
2828

29-
/** Wire format: server → WsServerEnvelope, client → WsClientSend. Env VITE_WS_URL; token GET /chat/ws-token. */
29+
/** Wire format: server → WsServerEnvelope, client → WsClientSend. Env VITE_WS_URL; token GET /api/chat/ws-token. */
3030

3131
export interface WsMessagePayload {
3232
id: string; // server-assigned permanent message ID

0 commit comments

Comments
 (0)