From 34a4f594ce67d03a0a2f17a4b3d3a5e414564036 Mon Sep 17 00:00:00 2001 From: julien vdb Date: Fri, 12 Dec 2025 19:29:10 +0100 Subject: [PATCH] 0.12.16 : add custom endpoints for contacts --- package.json | 2 +- src/api/contact/controllers/contact.ts | 165 +++++++++++++++++- src/api/contact/routes/01-custom.ts | 33 ++++ .../1.0.0/full_documentation.json | 2 +- 4 files changed, 196 insertions(+), 6 deletions(-) create mode 100644 src/api/contact/routes/01-custom.ts diff --git a/package.json b/package.json index c983370..a13d3c5 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "harmony-back", - "version": "0.12.15", + "version": "0.12.16", "private": true, "description": "A Strapi application", "scripts": { diff --git a/src/api/contact/controllers/contact.ts b/src/api/contact/controllers/contact.ts index 5687b27..a3987d5 100644 --- a/src/api/contact/controllers/contact.ts +++ b/src/api/contact/controllers/contact.ts @@ -7,6 +7,78 @@ import { factories } from "@strapi/strapi"; export default factories.createCoreController( "api::contact.contact", ({ strapi }) => ({ + async activities(ctx) { + const userId = ctx.state.user?.id; + + if (!userId) { + return ctx.unauthorized("User not authenticated"); + } + + console.log("GET /contacts/activities - Requête reçue:", { + userId: userId, + }); + + try { + const friends = await strapi + .documents("api::contact.contact") + .findMany({ + filters: { + owner: { id: userId }, + state: "accepted", + }, + populate: { + user: { + fields: ["id", "username"], + populate: { + activities: true, + }, + }, + }, + }); + + console.log("GET /contacts/activities - Amis trouvés:", { + count: friends.length, + }); + + const friendsWithLatestActivity = friends.map((contact) => { + const user = contact.user; + let latestActivity = null; + + if (user.activities && Array.isArray(user.activities) && user.activities.length > 0) { + latestActivity = user.activities.reduce((latest, activity) => { + const latestDate = new Date(latest.activityDate).getTime(); + const currentDate = new Date(activity.activityDate).getTime(); + return currentDate > latestDate ? activity : latest; + }); + } + + return { + id: user.id, + username: user.username, + latestActivity: latestActivity, + }; + }); + + return { + data: friendsWithLatestActivity, + meta: { + pagination: { + page: 1, + pageSize: friendsWithLatestActivity.length, + pageCount: 1, + total: friendsWithLatestActivity.length, + }, + }, + }; + } catch (error) { + console.error("GET /contacts/activities - Erreur:", { + error: error.message, + userId: userId, + }); + + throw error; + } + }, async find(ctx) { // Log de la requête entrante console.log("GET /contacts - Requête reçue:", { @@ -72,8 +144,8 @@ export default factories.createCoreController( .documents("api::contact.contact") .findFirst({ filters: { - owner: owner, - user: user, + owner: { id: owner }, + user: { id: user }, }, }); @@ -148,10 +220,10 @@ export default factories.createCoreController( filters: { $or: [ { - user: id, + user: { id: id }, }, { - owner: id, + owner: { id: id }, }, ], }, @@ -192,5 +264,90 @@ export default factories.createCoreController( throw error; } }, + + async suggestions(ctx) { + const userId = ctx.state.user?.id; + + if (!userId) { + return ctx.unauthorized("User not authenticated"); + } + + console.log("GET /contacts/suggestions - Requête reçue:", { + userId: userId, + }); + + try { + const userFriends = await strapi + .documents("api::contact.contact") + .findMany({ + filters: { + owner: { id: userId }, + state: "accepted", + }, + populate: { + user: { + fields: ["id", "username"], + }, + }, + }); + + console.log("GET /contacts/suggestions - Amis trouvés:", { + count: userFriends.length, + }); + + const friendIds = new Set(userFriends.map((contact) => contact.user.id)); + friendIds.add(userId); + + const suggestedFriendIds = new Set(); + + for (const friend of userFriends) { + const friendsFriendsContacts = await strapi + .documents("api::contact.contact") + .findMany({ + filters: { + owner: { id: friend.user.id }, + state: "accepted", + }, + populate: { + user: { + fields: ["id", "username"], + }, + }, + }); + + for (const friendFriend of friendsFriendsContacts) { + if (!friendIds.has(friendFriend.user.id)) { + suggestedFriendIds.add(JSON.stringify({ + id: friendFriend.user.id, + username: friendFriend.user.username, + })); + } + } + } + + const suggestions = Array.from(suggestedFriendIds) + .map((str) => JSON.parse(str)) + .sort((a, b) => a.username.localeCompare(b.username)); + + return { + data: suggestions, + meta: { + pagination: { + page: 1, + pageSize: suggestions.length, + pageCount: 1, + total: suggestions.length, + }, + }, + }; + } catch (error) { + console.error("GET /contacts/suggestions - Erreur:", { + error: error.message, + userId: userId, + }); + + throw error; + } + }, }) ); diff --git a/src/api/contact/routes/01-custom.ts b/src/api/contact/routes/01-custom.ts new file mode 100644 index 0000000..cb08d6c --- /dev/null +++ b/src/api/contact/routes/01-custom.ts @@ -0,0 +1,33 @@ +/** + * Custom contact routes + */ + +export default { + type: "content-api", + routes: [ + { + method: "GET", + path: "/contacts/activities", + handler: "contact.activities", + config: { + // Ajoutez ce bloc 'auth' pour être explicite + auth: { + scope: ["api::contact.contact.activities"], // Nom exact de la permission + }, + policies: [], // On garde les politiques par défaut + }, + }, + { + method: "GET", + path: "/contacts/suggestions", + handler: "contact.suggestions", + config: { + // Ajoutez ce bloc 'auth' pour être explicite + auth: { + scope: ["api::contact.contact.activities"], // Nom exact de la permission + }, + policies: [], // On garde les politiques par défaut + }, + }, + ], +}; diff --git a/src/extensions/documentation/documentation/1.0.0/full_documentation.json b/src/extensions/documentation/documentation/1.0.0/full_documentation.json index 9c799b2..1ee4c95 100644 --- a/src/extensions/documentation/documentation/1.0.0/full_documentation.json +++ b/src/extensions/documentation/documentation/1.0.0/full_documentation.json @@ -14,7 +14,7 @@ "name": "Apache 2.0", "url": "https://www.apache.org/licenses/LICENSE-2.0.html" }, - "x-generation-date": "2025-12-11T16:29:12.158Z" + "x-generation-date": "2025-12-12T18:29:01.167Z" }, "x-strapi-config": { "plugins": [