From fe4c1c5d5618c39797080890a13353f7fc76a44e Mon Sep 17 00:00:00 2001 From: theolemague Date: Tue, 26 Nov 2024 14:56:13 +0100 Subject: [PATCH 01/21] add slack message and fix apply status issue --- process/src/jobs/metabase/account.ts | 1 + process/src/jobs/metabase/apply.ts | 13 ++- process/src/jobs/metabase/campaign.ts | 3 +- process/src/jobs/metabase/click.ts | 1 + process/src/jobs/metabase/import.ts | 1 + process/src/jobs/metabase/index.ts | 80 ++++++++++++++++--- process/src/jobs/metabase/kpi.ts | 1 + process/src/jobs/metabase/login-history.ts | 7 +- process/src/jobs/metabase/mission.ts | 11 ++- process/src/jobs/metabase/partner.ts | 3 +- .../jobs/metabase/{impression.ts => print.ts} | 2 +- process/src/jobs/metabase/user.ts | 3 +- process/src/jobs/metabase/widget-query.ts | 3 +- process/src/jobs/metabase/widget.ts | 3 +- 14 files changed, 102 insertions(+), 30 deletions(-) rename process/src/jobs/metabase/{impression.ts => print.ts} (99%) diff --git a/process/src/jobs/metabase/account.ts b/process/src/jobs/metabase/account.ts index 277334b..aa44232 100644 --- a/process/src/jobs/metabase/account.ts +++ b/process/src/jobs/metabase/account.ts @@ -184,6 +184,7 @@ const handler = async () => { } console.log(`[Accounts] Ended at ${new Date().toISOString()} in ${(Date.now() - start.getTime()) / 1000}s.`); + return { created, updated }; } catch (error) { captureException(error, "[Accounts] Error while syncing docs."); } diff --git a/process/src/jobs/metabase/apply.ts b/process/src/jobs/metabase/apply.ts index c4222a9..e1bafaa 100644 --- a/process/src/jobs/metabase/apply.ts +++ b/process/src/jobs/metabase/apply.ts @@ -67,7 +67,7 @@ const buildData = async ( widget_id: sourceId && doc.source === "widget" ? sourceId : null, to_partner_id: partnerToId, from_partner_id: partnerFromId, - status: doc.status, + status: doc.status || null, } as Apply; return obj; @@ -154,8 +154,13 @@ const handler = async () => { } const obj = await buildData({ ...hit._source, _id: hit._id }, partners, missions, campaigns, widgets, clickId); if (!obj) continue; - if (stored[hit._id.toString()] && stored[hit._id.toString()].status !== obj.status && stored[hit._id.toString()].click_id !== obj.click_id) dataToUpdate.push(obj); - else if (!stored[hit._id.toString()]) dataToCreate.push(obj); + + if (stored[hit._id.toString()] && (stored[hit._id.toString()].status !== obj.status || stored[hit._id.toString()].click_id !== obj.click_id)) { + console.log("UPDATE"); + console.log("status", stored[hit._id.toString()].status !== obj.status, stored[hit._id.toString()].status, obj.status); + console.log("click_id", stored[hit._id.toString()].click_id !== obj.click_id, stored[hit._id.toString()].click_id, obj.click_id); + dataToUpdate.push(obj); + } else if (!stored[hit._id.toString()]) dataToCreate.push(obj); } console.log(`[Applies] ${dataToCreate.length} docs to create, ${dataToUpdate.length} docs to update.`); @@ -180,8 +185,8 @@ const handler = async () => { updated += dataToUpdate.length; console.log(`[Applies] Updated ${dataToUpdate.length} docs, ${updated} updated so far.`); } - console.log(`[Applies] Ended at ${new Date().toISOString()} in ${(Date.now() - start.getTime()) / 1000}s.`); + return { created, updated }; } catch (error) { captureException(error, "[Applies] Error while syncing docs."); } diff --git a/process/src/jobs/metabase/campaign.ts b/process/src/jobs/metabase/campaign.ts index 4503ad0..0175461 100644 --- a/process/src/jobs/metabase/campaign.ts +++ b/process/src/jobs/metabase/campaign.ts @@ -44,7 +44,7 @@ const handler = async () => { const stored = {} as { [key: string]: { old_id: string; updated_at: Date } }; await prisma.campaign.findMany({ select: { old_id: true, updated_at: true } }).then((data) => data.forEach((d) => (stored[d.old_id] = d))); - console.log(`[Campaigns] Found ${stored.length} docs in database.`); + console.log(`[Campaigns] Found ${Object.keys(stored).length} docs in database.`); const partners = {} as { [key: string]: string }; await prisma.partner.findMany({ select: { id: true, old_id: true } }).then((data) => data.forEach((d) => (partners[d.old_id] = d.id))); @@ -77,6 +77,7 @@ const handler = async () => { } console.log(`[Campaigns] Ended at ${new Date().toISOString()} in ${(Date.now() - start.getTime()) / 1000}s.`); + return { created: dataToCreate.length, updated: dataToUpdate.length }; } catch (error) { captureException(error, "[Campaigns] Error while syncing docs."); } diff --git a/process/src/jobs/metabase/click.ts b/process/src/jobs/metabase/click.ts index 6eaf0cf..c1e40ba 100644 --- a/process/src/jobs/metabase/click.ts +++ b/process/src/jobs/metabase/click.ts @@ -153,6 +153,7 @@ const handler = async () => { } console.log(`[Clicks] Ended at ${new Date().toISOString()} in ${(Date.now() - start.getTime()) / 1000}s.`); + return { created }; } catch (error) { captureException(error, "[Clicks] Error while syncing docs."); } diff --git a/process/src/jobs/metabase/import.ts b/process/src/jobs/metabase/import.ts index 7b7f1dc..96f25d5 100644 --- a/process/src/jobs/metabase/import.ts +++ b/process/src/jobs/metabase/import.ts @@ -70,6 +70,7 @@ const handler = async () => { } console.log(`[Imports] Ended at ${new Date().toISOString()} in ${(Date.now() - start.getTime()) / 1000}s.`); + return { created }; } catch (error) { captureException(error, "[Imports] Error while syncing docs."); } diff --git a/process/src/jobs/metabase/index.ts b/process/src/jobs/metabase/index.ts index 4b21352..01f55f5 100644 --- a/process/src/jobs/metabase/index.ts +++ b/process/src/jobs/metabase/index.ts @@ -4,26 +4,80 @@ import importCampaigns from "./campaign"; import importWidgets from "./widget"; import importMissions from "./mission"; import importImports from "./import"; -import importImpressions from "./impression"; +import importImpressions from "./print"; import importClicks from "./click"; import importApplies from "./apply"; import importAccounts from "./account"; import importRequestWidgets from "./widget-query"; import importLoginHistory from "./login-history"; +// import importKpi from "./kpi"; +import { postMessage } from "../../services/slack"; +import { SLACK_PRODUCT_CHANNEL_ID } from "../../config"; const handler = async () => { - await importPartners(); - await importUsers(); - await importCampaigns(); - await importWidgets(); - await importMissions(); - await importImpressions(); - await importClicks(); - await importApplies(); - await importAccounts(); - await importImports(); - await importRequestWidgets(); - await importLoginHistory(); + const stats = { + partners: { created: 0, updated: 0 }, + users: { created: 0, updated: 0 }, + campaigns: { created: 0, updated: 0 }, + widgets: { created: 0, updated: 0 }, + missions: { created: 0, updated: 0 }, + imports: { created: 0, updated: null }, + prints: { created: 0, updated: null }, + clicks: { created: 0, updated: null }, + applies: { created: 0, updated: null }, + accounts: { created: 0, updated: 0 }, + requests: { created: 0, updated: null }, + login_history: { created: 0, updated: null }, + kpi: { created: 0, updated: null }, + }; + + const partners = await importPartners(); + stats.partners.created += partners?.created || 0; + stats.partners.updated += partners?.updated || 0; + const users = await importUsers(); + stats.users.created += users?.created || 0; + stats.users.updated += users?.updated || 0; + const campaigns = await importCampaigns(); + stats.campaigns.created += campaigns?.created || 0; + stats.campaigns.updated += campaigns?.updated || 0; + const widgets = await importWidgets(); + stats.widgets.created += widgets?.created || 0; + stats.widgets.updated += widgets?.updated || 0; + const missions = await importMissions(); + stats.missions.created += missions?.created || 0; + stats.missions.updated += missions?.updated || 0; + const impressions = await importImpressions(); + stats.prints.created += impressions?.created || 0; + const clicks = await importClicks(); + stats.clicks.created += clicks?.created || 0; + const applies = await importApplies(); + stats.applies.created += applies?.created || 0; + const accounts = await importAccounts(); + stats.accounts.created += accounts?.created || 0; + stats.accounts.updated += accounts?.updated || 0; + const imports = await importImports(); + stats.imports.created += imports?.created || 0; + const requests = await importRequestWidgets(); + stats.requests.created += requests?.created || 0; + const login_history = await importLoginHistory(); + stats.login_history.created += login_history?.created || 0; + // const kpi = await importKpi(); + // stats.kpi.created += kpi?.created || 0; + + // Send message to slack + const text = `${Object.entries(stats) + .map(([key, value]) => `${key}: ${value.created} created${value.updated !== null ? `, ${value.updated} updated` : ""}`) + .join("\n")}`; + + console.log("stats", stats); + await postMessage( + { + title: `Metabase Sync completed`, + text, + }, + SLACK_PRODUCT_CHANNEL_ID, + ); + return stats; }; export default { handler }; diff --git a/process/src/jobs/metabase/kpi.ts b/process/src/jobs/metabase/kpi.ts index 68ef0b7..5ff75d3 100644 --- a/process/src/jobs/metabase/kpi.ts +++ b/process/src/jobs/metabase/kpi.ts @@ -79,6 +79,7 @@ const handler = async () => { } console.log(`[KPI] Ended at ${new Date().toISOString()} in ${(Date.now() - start.getTime()) / 1000}s.`); + return { created: dataToCreate.length }; } catch (error) { captureException(error, "[KPI] Error while syncing docs."); } diff --git a/process/src/jobs/metabase/login-history.ts b/process/src/jobs/metabase/login-history.ts index 4d502a7..dc4bdf6 100644 --- a/process/src/jobs/metabase/login-history.ts +++ b/process/src/jobs/metabase/login-history.ts @@ -1,13 +1,13 @@ import prisma from "../../db/postgres"; import UserModel from "../../models/user"; import { captureException } from "../../error"; -import { PgLoginHistory } from "../../types/postgres"; +import { LoginHistory } from "@prisma/client"; const buildData = (userId: string, loginTime: Date) => { return { user_id: userId, login_at: loginTime, - } as PgLoginHistory; + } as LoginHistory; }; const handler = async () => { @@ -32,7 +32,7 @@ const handler = async () => { .then((data) => data.forEach((e) => (logins[e.user_id] = e._max.login_at))); console.log(`[LoginHistory] Fetched latest login times for ${Object.keys(logins).length} users.`); - const dataToCreate = [] as PgLoginHistory[]; + const dataToCreate = [] as LoginHistory[]; for (const user of data) { const userId = users[user._id.toString()]; const latestLoginAt = logins[userId]; @@ -58,6 +58,7 @@ const handler = async () => { } console.log(`[LoginHistory] Ended at ${new Date().toISOString()} in ${(Date.now() - start.getTime()) / 1000}s.`); + return { created: dataToCreate.length }; } catch (error) { captureException(error, "[LoginHistory] Error while syncing login history."); } diff --git a/process/src/jobs/metabase/mission.ts b/process/src/jobs/metabase/mission.ts index f9236ff..be3ad7c 100644 --- a/process/src/jobs/metabase/mission.ts +++ b/process/src/jobs/metabase/mission.ts @@ -1,7 +1,7 @@ import prisma from "../../db/postgres"; import { captureException } from "../../error"; import { Mission as MongoMission } from "../../types"; -import { Mission as PrismaMission } from "@prisma/client"; +import { Mission as PgMission } from "@prisma/client"; import MissionModel from "../../models/mission"; const BULK_SIZE = 5000; @@ -92,7 +92,7 @@ const buildData = (doc: MongoMission, partners: { [key: string]: string }) => { created_at: new Date(doc.createdAt), updated_at: new Date(doc.updatedAt), deleted_at: doc.deletedAt ? new Date(doc.deletedAt) : null, - } as PrismaMission; + } as PgMission; return obj; }; @@ -115,13 +115,15 @@ const handler = async () => { const fourteenDaysAgo = new Date(); fourteenDaysAgo.setDate(fourteenDaysAgo.getDate() - 14); const where = { $or: [{ createdAt: { $gte: fourteenDaysAgo } }, { updatedAt: { $gte: fourteenDaysAgo } }] }; + const countToSync = await MissionModel.countDocuments(where); + console.log(`[Missions] Found ${countToSync} docs to sync.`); while (true) { const data = await MissionModel.find(where).limit(BULK_SIZE).skip(offset).lean(); if (data.length === 0) break; - const dataToCreate = [] as PrismaMission[]; - const dataToUpdate = [] as PrismaMission[]; + const dataToCreate = [] as PgMission[]; + const dataToUpdate = [] as PgMission[]; console.log(`[Missions] Processing ${data.length} docs.`); // Fetch all existing missions in one go @@ -166,6 +168,7 @@ const handler = async () => { } console.log(`[Missions] Ended at ${new Date().toISOString()} in ${(Date.now() - start.getTime()) / 1000}s.`); + return { created, updated }; } catch (error) { captureException(error, "[Missions] Error while syncing docs."); } diff --git a/process/src/jobs/metabase/partner.ts b/process/src/jobs/metabase/partner.ts index aa6a539..65c9978 100644 --- a/process/src/jobs/metabase/partner.ts +++ b/process/src/jobs/metabase/partner.ts @@ -2,7 +2,7 @@ import prisma from "../../db/postgres"; import PublisherModel from "../../models/publisher"; import { captureException } from "../../error"; import { Publisher } from "../../types"; -import { PgPartner } from "../../types/postgres"; +import { Partner as PgPartner } from "@prisma/client"; const buildData = (doc: Publisher) => { const obj = { @@ -59,6 +59,7 @@ const handler = async () => { } console.log(`[Partners] Ended at ${new Date().toISOString()} in ${(Date.now() - start.getTime()) / 1000}s.`); + return { created: dataToCreate.length, updated: dataToUpdate.length }; } catch (error) { captureException(error, "[Partners] Error while syncing docs."); } diff --git a/process/src/jobs/metabase/impression.ts b/process/src/jobs/metabase/print.ts similarity index 99% rename from process/src/jobs/metabase/impression.ts rename to process/src/jobs/metabase/print.ts index d1e120e..5db5f66 100644 --- a/process/src/jobs/metabase/impression.ts +++ b/process/src/jobs/metabase/print.ts @@ -3,7 +3,6 @@ import prisma from "../../db/postgres"; import { STATS_INDEX } from "../../config"; import { captureException } from "../../error"; import { Stats } from "../../types"; -import { PgImpression } from "../../types/postgres"; import { Impression } from "@prisma/client"; const BATCH_SIZE = 5000; @@ -153,6 +152,7 @@ const handler = async () => { } console.log(`[Prints] Ended at ${new Date().toISOString()} in ${(Date.now() - start.getTime()) / 1000}s.`); + return { created }; } catch (error) { captureException(error, "[Prints] Error while syncing docs."); } diff --git a/process/src/jobs/metabase/user.ts b/process/src/jobs/metabase/user.ts index f8d984c..2a1f446 100644 --- a/process/src/jobs/metabase/user.ts +++ b/process/src/jobs/metabase/user.ts @@ -2,7 +2,7 @@ import prisma from "../../db/postgres"; import UserModel from "../../models/user"; import { captureException } from "../../error"; import { User } from "../../types"; -import { PgUser } from "../../types/postgres"; +import { User as PgUser } from "@prisma/client"; interface UserUpdate extends PgUser { partners: { connect: { id: string }[] }; @@ -85,6 +85,7 @@ const handler = async () => { } console.log(`[Users] Ended at ${new Date().toISOString()} in ${(Date.now() - start.getTime()) / 1000}s.`); + return { created: dataToCreate.length, updated: dataToUpdate.length }; } catch (error) { captureException(error, "[Users] Error while syncing docs."); } diff --git a/process/src/jobs/metabase/widget-query.ts b/process/src/jobs/metabase/widget-query.ts index c7d2081..9393a68 100644 --- a/process/src/jobs/metabase/widget-query.ts +++ b/process/src/jobs/metabase/widget-query.ts @@ -2,7 +2,7 @@ import prisma from "../../db/postgres"; import RequestWidgetModel from "../../models/request-widget"; import { captureException } from "../../error"; import { RequestWidget } from "../../types"; -import { PgWidgetQuery } from "../../types/postgres"; +import { WidgetQuery as PgWidgetQuery } from "@prisma/client"; const BATCH_SIZE = 5000; @@ -82,6 +82,7 @@ const handler = async () => { } console.log(`[Widget-Requests] Ended at ${new Date().toISOString()} in ${(Date.now() - start.getTime()) / 1000}s.`); + return { created }; } catch (error) { captureException(error, "[Widget-Requests] Error while syncing docs."); } diff --git a/process/src/jobs/metabase/widget.ts b/process/src/jobs/metabase/widget.ts index 3663992..8b15499 100644 --- a/process/src/jobs/metabase/widget.ts +++ b/process/src/jobs/metabase/widget.ts @@ -2,7 +2,7 @@ import prisma from "../../db/postgres"; import WidgetModel from "../../models/widget"; import { captureException } from "../../error"; import { Widget } from "../../types"; -import { PgWidget } from "../../types/postgres"; +import { Widget as PgWidget } from "@prisma/client"; interface WidgetUpdate extends PgWidget { annonceur: { connect: { id: string }[] }; @@ -75,6 +75,7 @@ const handler = async () => { } console.log(`[Widgets] Ended at ${new Date().toISOString()} in ${(Date.now() - start.getTime()) / 1000}s.`); + return { created: dataToCreate.length, updated: dataToUpdate.length }; } catch (error) { captureException(error, "[Widgets] Error while syncing docs."); } From acb5f72bc56bf85126ba0428a5cd79b0556fe2ad Mon Sep 17 00:00:00 2001 From: Alexandre TENSORER Date: Thu, 28 Nov 2024 14:40:39 +0100 Subject: [PATCH 02/21] fix: admin stats pie chart data --- app/src/scenes/admin-stats/Apercu.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/scenes/admin-stats/Apercu.jsx b/app/src/scenes/admin-stats/Apercu.jsx index 8cd3b1e..1804e77 100644 --- a/app/src/scenes/admin-stats/Apercu.jsx +++ b/app/src/scenes/admin-stats/Apercu.jsx @@ -447,7 +447,7 @@ const Patners = ({ filters }) => { ); const announcePie = buildPie( data.filter((d) => d.role_promoteur), - "applyFrom", + "applyTo", ); return ( From c9df3771e8259249aa2952020bc9598beef7e11d Mon Sep 17 00:00:00 2001 From: Alexandre TENSORER Date: Thu, 28 Nov 2024 16:10:46 +0100 Subject: [PATCH 03/21] fix: admin stats total publishers --- api/src/controllers/stats-admin.ts | 15 +++++- app/src/scenes/admin-stats/Apercu.jsx | 67 ++++++++++++++++++++++----- 2 files changed, 68 insertions(+), 14 deletions(-) diff --git a/api/src/controllers/stats-admin.ts b/api/src/controllers/stats-admin.ts index b8b9a17..5ba8404 100644 --- a/api/src/controllers/stats-admin.ts +++ b/api/src/controllers/stats-admin.ts @@ -344,8 +344,19 @@ router.get("/publishers-views", passport.authenticate("user", { session: false } const total = { publishers: publishers.length, - announcers: publishers.filter((e) => e.role_promoteur).length, - broadcasters: publishers.filter((e) => e.role_annonceur_api || e.role_annonceur_campagne || e.role_annonceur_widget).length, + announcers: publishers.filter((e) => { + if (!e.role_promoteur) return false; + if (query.data.type === "volontariat") return e.name === "Service Civique"; + if (query.data.type === "benevolat") return e.name !== "Service Civique"; + return true; + }).length, + broadcasters: publishers.filter((e) => { + const isBroadcaster = e.role_annonceur_api || e.role_annonceur_campagne || e.role_annonceur_widget; + if (!isBroadcaster) return false; + if (query.data.type === "volontariat") return e.publishers?.some((p) => p.publisherName === "Service Civique"); + if (query.data.type === "benevolat") return e.publishers?.some((p) => p.publisherName !== "Service Civique"); + return true; + }).length, clicks: response.body.aggregations.totalClick.doc_count, applys: response.body.aggregations.totalApply.doc_count, }; diff --git a/app/src/scenes/admin-stats/Apercu.jsx b/app/src/scenes/admin-stats/Apercu.jsx index 1804e77..6357fef 100644 --- a/app/src/scenes/admin-stats/Apercu.jsx +++ b/app/src/scenes/admin-stats/Apercu.jsx @@ -13,6 +13,9 @@ import { captureError } from "../../services/error"; const Apercu = () => { const [searchParams, setSearchParams] = useSearchParams(); + const [stickyVisible, setStickyVisible] = useState(false); + const [filterSection, setFilterSection] = useState(null); + const [filters, setFilters] = useState({ from: searchParams.has("from") ? new Date(searchParams.get("from")) : new Date(new Date().getFullYear() - 1, new Date().getMonth(), new Date().getDate()), to: searchParams.has("to") ? new Date(searchParams.get("to")) : new Date(new Date().getFullYear(), new Date().getMonth(), new Date().getDate() + 1, 0, 0, 0, -1), @@ -26,24 +29,64 @@ const Apercu = () => { setSearchParams(query); }, [filters, location.pathname]); + useEffect(() => { + if (!filterSection) return; + + const observer = new IntersectionObserver( + ([entry]) => { + setStickyVisible(!entry.isIntersecting); + }, + { threshold: 0 }, + ); + + observer.observe(filterSection); + + return () => { + if (filterSection) { + observer.unobserve(filterSection); + } + }; + }, [filterSection]); + return (
Aperçu - Statistiques - Administration - API Engagement -
-
- - setFilters({ ...filters, from: value.from, to: value.to })} /> + + {stickyVisible && ( +
+
+
+ setFilters({ ...filters, from: value.from, to: value.to })} /> +
+ + +
+
+ )} + +
setFilterSection(node)}> +
+
+ + setFilters({ ...filters, from: value.from, to: value.to })} /> +
+ +
- -
From 3a07e9253e99a5dcfefa2dfb77546b685950ef7e Mon Sep 17 00:00:00 2001 From: Alexandre TENSORER Date: Mon, 2 Dec 2024 10:43:56 +0100 Subject: [PATCH 04/21] fix: update ResetPassword.jsx --- app/src/scenes/auth/ResetPassword.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/scenes/auth/ResetPassword.jsx b/app/src/scenes/auth/ResetPassword.jsx index a47e743..3ed70eb 100644 --- a/app/src/scenes/auth/ResetPassword.jsx +++ b/app/src/scenes/auth/ResetPassword.jsx @@ -180,7 +180,7 @@ const ResetPasswordForm = ({ user, token }) => { Date: Mon, 2 Dec 2024 11:01:58 +0100 Subject: [PATCH 05/21] fix: update password reset --- app/src/scenes/account/index.jsx | 6 +++--- app/src/scenes/auth/Signup.jsx | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/src/scenes/account/index.jsx b/app/src/scenes/account/index.jsx index 182b1be..86f409c 100644 --- a/app/src/scenes/account/index.jsx +++ b/app/src/scenes/account/index.jsx @@ -202,7 +202,7 @@ const ResetPasswordModal = ({ open, setOpen }) => { { { { Date: Mon, 2 Dec 2024 15:17:45 +0100 Subject: [PATCH 06/21] update: global broadcast click total --- api/src/controllers/stats-global.ts | 13 +++++++++---- app/src/scenes/performance/GlobalBroadcast.jsx | 6 +++--- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/api/src/controllers/stats-global.ts b/api/src/controllers/stats-global.ts index c2891ae..2b4d0b9 100644 --- a/api/src/controllers/stats-global.ts +++ b/api/src/controllers/stats-global.ts @@ -57,9 +57,14 @@ router.get("/broadcast-preview", passport.authenticate("user", { session: false }, }, }, - totalMission: { - cardinality: { - field: "missionId.keyword", + totalMissionClick: { + filter: { term: { type: "click" } }, + aggs: { + missions: { + cardinality: { + field: "missionId.keyword", + }, + }, }, }, }, @@ -73,7 +78,7 @@ router.get("/broadcast-preview", passport.authenticate("user", { session: false totalPrint: response.body.aggregations.totalPrint.doc_count, totalAccount: response.body.aggregations.totalAccount.doc_count, totalMissionApply: response.body.aggregations.totalMissionApply.missions.value, - totalMission: response.body.aggregations.totalMission.value, + totalMissionClick: response.body.aggregations.totalMissionClick.missions.value, }; return res.status(200).send({ ok: true, data }); diff --git a/app/src/scenes/performance/GlobalBroadcast.jsx b/app/src/scenes/performance/GlobalBroadcast.jsx index db20a1f..06c875c 100644 --- a/app/src/scenes/performance/GlobalBroadcast.jsx +++ b/app/src/scenes/performance/GlobalBroadcast.jsx @@ -33,7 +33,7 @@ const COLORS = ["rgba(250,117,117,255)", "rgba(252,205,109,255)", "rgba(251,146, const GlobalDiffuseur = ({ filters, onFiltersChange }) => { const { publisher } = useStore(); - const [data, setData] = useState({ totalMission: 0, totalMissionApply: 0, totalPrint: 0, totalClick: 0, totalAccount: 0, totalApply: 0 }); + const [data, setData] = useState({ totalMissionClick: 0, totalMissionApply: 0, totalPrint: 0, totalClick: 0, totalAccount: 0, totalApply: 0 }); const [loading, setLoading] = useState(true); const [trackingWarning, setTrackingWarning] = useState(false); @@ -111,8 +111,8 @@ const GlobalDiffuseur = ({ filters, onFiltersChange }) => {
-

{data.totalMission.toLocaleString("fr")}

-

missions diffusées

+

{data.totalMissionClick.toLocaleString("fr")}

+

missions ayant généré au moins une redirection

{data.totalMissionApply.toLocaleString("fr")}

From 910d5fa31f2f281955919a9288769f51ad9c99f6 Mon Sep 17 00:00:00 2001 From: Alexandre TENSORER Date: Mon, 2 Dec 2024 17:53:28 +0100 Subject: [PATCH 07/21] refacto: remove 3 character minimum search --- app/src/components/SelectCity.jsx | 3 ++- app/src/components/SelectOrganization.jsx | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/app/src/components/SelectCity.jsx b/app/src/components/SelectCity.jsx index 462085a..90ddb06 100644 --- a/app/src/components/SelectCity.jsx +++ b/app/src/components/SelectCity.jsx @@ -12,7 +12,8 @@ const SelectCity = ({ onChange }) => { useEffect(() => { const fetchOptions = async () => { try { - if (search.length > 0 && search.length < 3) { + if (search.length === 0) { + onChange(null); setOptions([]); return; } diff --git a/app/src/components/SelectOrganization.jsx b/app/src/components/SelectOrganization.jsx index 619d415..0da6ec3 100644 --- a/app/src/components/SelectOrganization.jsx +++ b/app/src/components/SelectOrganization.jsx @@ -12,7 +12,8 @@ const SelectOrganization = ({ onChange }) => { useEffect(() => { const fetchOptions = async () => { try { - if (search.length > 0 && search.length < 3) { + if (search.length === 0) { + onChange(null); setOptions([]); return; } From 5f3737ee34794922be050e4c5d4667b166a0ae13 Mon Sep 17 00:00:00 2001 From: theolemague Date: Tue, 3 Dec 2024 13:59:49 +0100 Subject: [PATCH 08/21] Update index.ts --- process/src/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/process/src/index.ts b/process/src/index.ts index b48737b..6bf718c 100644 --- a/process/src/index.ts +++ b/process/src/index.ts @@ -279,7 +279,7 @@ const leboncoinJob = new CronJob( // Every first Tuesday of the month at 10:00 AM const reportJob = new CronJob( - "0 10 2 * *", + "0 14 2 * *", async () => { // if not the first Tuesday of the month, return const date = new Date(); From 04224b7c3ef185351dc0d4b8cf597af8c16c42a9 Mon Sep 17 00:00:00 2001 From: theolemague Date: Tue, 3 Dec 2024 14:01:45 +0100 Subject: [PATCH 09/21] Update index.ts --- process/src/index.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/process/src/index.ts b/process/src/index.ts index 6bf718c..3a23ff1 100644 --- a/process/src/index.ts +++ b/process/src/index.ts @@ -279,10 +279,14 @@ const leboncoinJob = new CronJob( // Every first Tuesday of the month at 10:00 AM const reportJob = new CronJob( - "0 14 2 * *", + "5 14 2 * *", async () => { + console.log("reportJob"); // if not the first Tuesday of the month, return const date = new Date(); + console.log(date.getDay(), date.getDate()); + console.log(date.getDay() !== 2, date.getDate() > 7); + if (date.getDay() !== 2 || date.getDate() > 7) return; runnings.report = true; From a88b04bb12b9b6a0696dd640fcbf5c83852e6fbe Mon Sep 17 00:00:00 2001 From: theolemague Date: Tue, 3 Dec 2024 14:06:54 +0100 Subject: [PATCH 10/21] fix: test report cron --- process/src/index.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/process/src/index.ts b/process/src/index.ts index 3a23ff1..05ad708 100644 --- a/process/src/index.ts +++ b/process/src/index.ts @@ -279,7 +279,7 @@ const leboncoinJob = new CronJob( // Every first Tuesday of the month at 10:00 AM const reportJob = new CronJob( - "5 14 2 * *", + "8 13 2 * *", async () => { console.log("reportJob"); // if not the first Tuesday of the month, return @@ -396,4 +396,4 @@ app.get("/tasks", async (req, res) => { } }); -app.listen(PORT, () => console.log("Listening on port ", PORT, "at", new Date().toISOString())); +app.listen(PORT, () => console.log(`Listening on port ${PORT} at ${new Date().toISOString()}`)); From 0aa320adea61637eb8ded0a6ba083e0e31644afe Mon Sep 17 00:00:00 2001 From: theolemague Date: Tue, 3 Dec 2024 14:08:18 +0100 Subject: [PATCH 11/21] fix: cron report test --- process/src/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/process/src/index.ts b/process/src/index.ts index 05ad708..f711bce 100644 --- a/process/src/index.ts +++ b/process/src/index.ts @@ -279,7 +279,7 @@ const leboncoinJob = new CronJob( // Every first Tuesday of the month at 10:00 AM const reportJob = new CronJob( - "8 13 2 * *", + "10 13 * * 2", async () => { console.log("reportJob"); // if not the first Tuesday of the month, return From 690c76fcc8339cf7696b7c149cddae46b752d8b7 Mon Sep 17 00:00:00 2001 From: theolemague Date: Tue, 3 Dec 2024 14:10:33 +0100 Subject: [PATCH 12/21] fix: cron report test --- process/src/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/process/src/index.ts b/process/src/index.ts index f711bce..3de1ebf 100644 --- a/process/src/index.ts +++ b/process/src/index.ts @@ -279,7 +279,7 @@ const leboncoinJob = new CronJob( // Every first Tuesday of the month at 10:00 AM const reportJob = new CronJob( - "10 13 * * 2", + "11 14 * * 2", async () => { console.log("reportJob"); // if not the first Tuesday of the month, return From 86b51e67ef7a58ddb2e7500ac9829d006e13deed Mon Sep 17 00:00:00 2001 From: theolemague Date: Tue, 3 Dec 2024 14:11:34 +0100 Subject: [PATCH 13/21] Update index.ts --- process/src/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/process/src/index.ts b/process/src/index.ts index 3de1ebf..b3575ca 100644 --- a/process/src/index.ts +++ b/process/src/index.ts @@ -279,7 +279,7 @@ const leboncoinJob = new CronJob( // Every first Tuesday of the month at 10:00 AM const reportJob = new CronJob( - "11 14 * * 2", + "13 14 * * 2", async () => { console.log("reportJob"); // if not the first Tuesday of the month, return From c69983b2bc423f50e3c53dcfb1c0db4cb92d8f56 Mon Sep 17 00:00:00 2001 From: theolemague Date: Tue, 3 Dec 2024 14:25:42 +0100 Subject: [PATCH 14/21] fix: cron test report --- process/src/index.ts | 2 +- process/src/jobs/report/generate.ts | 17 ++++++++++++----- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/process/src/index.ts b/process/src/index.ts index b3575ca..b8a5ca9 100644 --- a/process/src/index.ts +++ b/process/src/index.ts @@ -279,7 +279,7 @@ const leboncoinJob = new CronJob( // Every first Tuesday of the month at 10:00 AM const reportJob = new CronJob( - "13 14 * * 2", + "27 14 * * 2", async () => { console.log("reportJob"); // if not the first Tuesday of the month, return diff --git a/process/src/jobs/report/generate.ts b/process/src/jobs/report/generate.ts index 84326d3..8813738 100644 --- a/process/src/jobs/report/generate.ts +++ b/process/src/jobs/report/generate.ts @@ -31,7 +31,11 @@ const startNextAppWithPM2 = async () => { console.error(`PM2 stderr: ${stderr}`); } console.log(`PM2 stdout: ${stdout}`); - resolve(stdout); + if (stdout.includes("Process successfully started")) { + resolve(stdout); + } else { + reject(new Error("Failed to start Next.js app with PM2")); + } }); }); }; @@ -53,8 +57,12 @@ const stopNextAppWithPM2 = async () => { }; const pingNextApp = async () => { - const response = await fetch("http://localhost:3000/"); - return response.ok; + try { + const response = await fetch("http://localhost:3000/"); + return response.ok; + } catch (err) { + return false; + } }; const pdfGeneration = async (browser: Browser, publisher: Publisher, year: number, month: number) => { @@ -166,8 +174,7 @@ export const generate = async (year: number, month: number) => { await startNextAppWithPM2(); // wait 10 seconds await new Promise((resolve) => setTimeout(resolve, 10000)); - const isNextAppReady = await pingNextApp(); - if (!isNextAppReady) { + if (!(await pingNextApp())) { console.log(`[Report] Next.js app is not ready`); return { count: 0, errors: [] }; } From a3b2464b21aa64aac26be9b5df0aafe806a81694 Mon Sep 17 00:00:00 2001 From: theolemague Date: Tue, 3 Dec 2024 14:28:12 +0100 Subject: [PATCH 15/21] fix: cron report test --- process/src/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/process/src/index.ts b/process/src/index.ts index b8a5ca9..096d619 100644 --- a/process/src/index.ts +++ b/process/src/index.ts @@ -279,7 +279,7 @@ const leboncoinJob = new CronJob( // Every first Tuesday of the month at 10:00 AM const reportJob = new CronJob( - "27 14 * * 2", + "32 14 * * 2", async () => { console.log("reportJob"); // if not the first Tuesday of the month, return From 1c21c5672befe247188d0a764120655dde82395e Mon Sep 17 00:00:00 2001 From: theolemague Date: Tue, 3 Dec 2024 14:47:17 +0100 Subject: [PATCH 16/21] fix: cron report test --- process/src/index.ts | 2 +- process/src/jobs/report/generate.ts | 23 +++++++++++++++-------- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/process/src/index.ts b/process/src/index.ts index 096d619..4db063b 100644 --- a/process/src/index.ts +++ b/process/src/index.ts @@ -279,7 +279,7 @@ const leboncoinJob = new CronJob( // Every first Tuesday of the month at 10:00 AM const reportJob = new CronJob( - "32 14 * * 2", + "49 14 * * 2", async () => { console.log("reportJob"); // if not the first Tuesday of the month, return diff --git a/process/src/jobs/report/generate.ts b/process/src/jobs/report/generate.ts index 8813738..69900a6 100644 --- a/process/src/jobs/report/generate.ts +++ b/process/src/jobs/report/generate.ts @@ -1,6 +1,6 @@ import puppeteer, { Browser } from "puppeteer"; import { exec } from "child_process"; - +import path from "path"; import PublisherModel from "../../models/publisher"; import ReportModel from "../../models/report"; import { putObject, OBJECT_ACL, BUCKET_URL } from "../../services/s3"; @@ -20,9 +20,16 @@ const fetchData = async (publisher: Publisher, year: number, month: number) => { } }; +const cleanPM2 = async () => { + return new Promise((resolve, reject) => { + exec("npx pm2 delete pdf", (error, stdout, stderr) => resolve(true)); + }); +}; + const startNextAppWithPM2 = async () => { return new Promise((resolve, reject) => { - exec("npx pm2 start pdf", (error, stdout, stderr) => { + const directory = path.join(process.cwd(), "../pdf-next"); + exec(`cd ${directory} && npm run start`, (error, stdout, stderr) => { if (error) { console.error(`Error starting Next.js app with PM2: ${error.message}`); reject(error); @@ -31,11 +38,8 @@ const startNextAppWithPM2 = async () => { console.error(`PM2 stderr: ${stderr}`); } console.log(`PM2 stdout: ${stdout}`); - if (stdout.includes("Process successfully started")) { - resolve(stdout); - } else { - reject(new Error("Failed to start Next.js app with PM2")); - } + + resolve(stdout); }); }); }; @@ -171,8 +175,9 @@ const pdfGeneration = async (browser: Browser, publisher: Publisher, year: numbe }; export const generate = async (year: number, month: number) => { + await cleanPM2(); + await new Promise((resolve) => setTimeout(resolve, 2000)); await startNextAppWithPM2(); - // wait 10 seconds await new Promise((resolve) => setTimeout(resolve, 10000)); if (!(await pingNextApp())) { console.log(`[Report] Next.js app is not ready`); @@ -193,6 +198,8 @@ export const generate = async (year: number, month: number) => { errors.push(...res.errors); } + await browser.close(); + await stopNextAppWithPM2(); return { count, errors }; From f8ded1b937479fde21c2f7c4034c2cacb6a5a176 Mon Sep 17 00:00:00 2001 From: theolemague Date: Tue, 3 Dec 2024 15:39:44 +0100 Subject: [PATCH 17/21] fix: report gen --- .github/workflows/deploy-pdf-production.yml | 2 +- pdf-next/.prettierrc | 8 +++ pdf-next/src/app/[id]/page.tsx | 9 ++- pdf-next/src/services/api.ts | 8 +-- pdf-next/src/services/config.ts | 5 -- process/src/config.ts | 1 + process/src/jobs/report/generate.ts | 77 ++++----------------- 7 files changed, 34 insertions(+), 76 deletions(-) create mode 100644 pdf-next/.prettierrc diff --git a/.github/workflows/deploy-pdf-production.yml b/.github/workflows/deploy-pdf-production.yml index 44ff1db..9464903 100644 --- a/.github/workflows/deploy-pdf-production.yml +++ b/.github/workflows/deploy-pdf-production.yml @@ -20,7 +20,7 @@ jobs: - name: Connect and restart process uses: appleboy/ssh-action@master with: - host: process.api-engagement.beta.gouv.fr + host: pdf.api-engagement.beta.gouv.fr username: "root" key: ${{ secrets.SCW_SSH_KEY }} script: | diff --git a/pdf-next/.prettierrc b/pdf-next/.prettierrc new file mode 100644 index 0000000..34198f1 --- /dev/null +++ b/pdf-next/.prettierrc @@ -0,0 +1,8 @@ +{ + "arrowParens": "always", + "printWidth": 180, + "semi": true, + "doubleQuote": true, + "tabWidth": 2, + "jsxBracketSameLine": true +} diff --git a/pdf-next/src/app/[id]/page.tsx b/pdf-next/src/app/[id]/page.tsx index c1bb10f..93709a9 100644 --- a/pdf-next/src/app/[id]/page.tsx +++ b/pdf-next/src/app/[id]/page.tsx @@ -10,8 +10,15 @@ const Page = async ({ params, searchParams }: { params: { id: string }; searchPa const id = params.id; const year = searchParams?.year ? Number(searchParams?.year) : new Date().getFullYear(); const month = searchParams?.month ? Number(searchParams?.month) : new Date().getMonth(); + const apiKey = searchParams?.apiKey as string; - const res = await api.get<{ data: StatsReport; publisher: Publisher }>(`/stats-report?year=${year}&month=${month}&publisherId=${id}`); + if (!apiKey) return null; + + const res = await api.get<{ data: StatsReport; publisher: Publisher }>(`/stats-report?year=${year}&month=${month}&publisherId=${id}`, { + headers: { + "x-api-key": apiKey, + }, + }); if (!res.data) return null; return ( <> diff --git a/pdf-next/src/services/api.ts b/pdf-next/src/services/api.ts index 2865226..2c91f01 100644 --- a/pdf-next/src/services/api.ts +++ b/pdf-next/src/services/api.ts @@ -1,24 +1,24 @@ -import { API_KEY, API_URL } from "./config"; +import { API_URL } from "./config"; class APIHandler { name: string; baseUrl: string; - headers: { "Content-Type": string; "x-api-key": string }; + headers: { "Content-Type": string }; constructor() { this.name = "APIHandler"; this.baseUrl = API_URL; this.headers = { "Content-Type": "application/json", - "x-api-key": API_KEY || "", }; } - async get(endpoint: string) { + async get(endpoint: string, options?: { headers?: { "x-api-key": string } }) { const response = await fetch(`${this.baseUrl}${endpoint}`, { cache: "no-store", method: "GET", headers: { ...this.headers, + ...options?.headers, }, credentials: "include", }); diff --git a/pdf-next/src/services/config.ts b/pdf-next/src/services/config.ts index 2cd2246..146fd77 100644 --- a/pdf-next/src/services/config.ts +++ b/pdf-next/src/services/config.ts @@ -1,6 +1 @@ export const API_URL = process.env.API_URL || "http://localhost:4000"; -export const API_KEY = process.env.API_KEY; -export const ES_ENDPOINT = process.env.ES_ENDPOINT || "https://uMauldOGSf1wYkNlSjf3:G8yQCPMp8M6el9dBEIsu@bddrzfdyvueuszf4d5ex-elasticsearch.services.clever-cloud.com"; -export const DB_ENDPOINT = - process.env.DB_ENDPOINT || "mongodb://ujs56xwhhbadijpyvlbm:sLVzx0f3us4dqoOIgwI@bammvxrlz7r7fbaulp2m-mongodb.services.clever-cloud.com:2668/bammvxrlz7r7fbaulp2m"; -export const STATS_INDEX = "stats"; diff --git a/process/src/config.ts b/process/src/config.ts index 8ba5e95..7fdf8e7 100644 --- a/process/src/config.ts +++ b/process/src/config.ts @@ -3,6 +3,7 @@ process.env.TZ = "Europe/Paris"; export const PORT = process.env.PORT || 4001; export const API_URL = process.env.API_URL || "http://localhost:4000"; export const API_KEY = process.env.API_KEY; +export const PDF_URL = process.env.PDF_URL || "http://localhost:3000"; export const ENVIRONMENT = process.env.ENV || "development"; export const ES_ENDPOINT = process.env.ES_ENDPOINT; diff --git a/process/src/jobs/report/generate.ts b/process/src/jobs/report/generate.ts index 69900a6..24d6266 100644 --- a/process/src/jobs/report/generate.ts +++ b/process/src/jobs/report/generate.ts @@ -1,11 +1,10 @@ import puppeteer, { Browser } from "puppeteer"; -import { exec } from "child_process"; -import path from "path"; import PublisherModel from "../../models/publisher"; import ReportModel from "../../models/report"; import { putObject, OBJECT_ACL, BUCKET_URL } from "../../services/s3"; import { Publisher, Report, StatsReport } from "../../types"; import api from "../../services/api"; +import { API_KEY, PDF_URL } from "../../config"; const MONTHS = ["Janvier", "Février", "Mars", "Avril", "Mai", "Juin", "Juillet", "Août", "Septembre", "Octobre", "Novembre", "Décembre"]; @@ -20,55 +19,6 @@ const fetchData = async (publisher: Publisher, year: number, month: number) => { } }; -const cleanPM2 = async () => { - return new Promise((resolve, reject) => { - exec("npx pm2 delete pdf", (error, stdout, stderr) => resolve(true)); - }); -}; - -const startNextAppWithPM2 = async () => { - return new Promise((resolve, reject) => { - const directory = path.join(process.cwd(), "../pdf-next"); - exec(`cd ${directory} && npm run start`, (error, stdout, stderr) => { - if (error) { - console.error(`Error starting Next.js app with PM2: ${error.message}`); - reject(error); - } - if (stderr) { - console.error(`PM2 stderr: ${stderr}`); - } - console.log(`PM2 stdout: ${stdout}`); - - resolve(stdout); - }); - }); -}; - -const stopNextAppWithPM2 = async () => { - return new Promise((resolve, reject) => { - exec("npx pm2 stop pdf", (error, stdout, stderr) => { - if (error) { - console.error(`Error stopping Next.js app with PM2: ${error.message}`); - reject(error); - } - if (stderr) { - console.error(`PM2 stderr: ${stderr}`); - } - console.log(`PM2 stdout: ${stdout}`); - resolve(stdout); - }); - }); -}; - -const pingNextApp = async () => { - try { - const response = await fetch("http://localhost:3000/"); - return response.ok; - } catch (err) { - return false; - } -}; - const pdfGeneration = async (browser: Browser, publisher: Publisher, year: number, month: number) => { const errors = [] as { id: string; name: string; error: string }[]; try { @@ -113,7 +63,7 @@ const pdfGeneration = async (browser: Browser, publisher: Publisher, year: numbe console.log(`[${publisher.name}] Downloading PDF...`); const page = await browser.newPage(); - await page.goto(`http://localhost:3000/${publisher._id}?year=${year}&month=${month}`, { waitUntil: "networkidle0" }); + await page.goto(`${PDF_URL}/${publisher._id}?year=${year}&month=${month}&apiKey=${API_KEY}`, { waitUntil: "networkidle0" }); const pdf = await page.pdf({ width: 1360, @@ -160,8 +110,15 @@ const pdfGeneration = async (browser: Browser, publisher: Publisher, year: numbe applyFrom: data.send ? data.send.apply : 0, data, }; - await ReportModel.create(obj); - console.log(`[${publisher.name}] Report object created`); + + const existing = await ReportModel.findOne({ publisherId: publisher._id, year, month }); + if (existing) { + await ReportModel.updateOne({ _id: existing._id }, obj); + console.log(`[${publisher.name}] Report object updated`); + } else { + await ReportModel.create(obj); + console.log(`[${publisher.name}] Report object created`); + } } catch (err) { console.log(`[${publisher.name}] ERROR - catch ${err}`); console.error(err); @@ -175,15 +132,6 @@ const pdfGeneration = async (browser: Browser, publisher: Publisher, year: numbe }; export const generate = async (year: number, month: number) => { - await cleanPM2(); - await new Promise((resolve) => setTimeout(resolve, 2000)); - await startNextAppWithPM2(); - await new Promise((resolve) => setTimeout(resolve, 10000)); - if (!(await pingNextApp())) { - console.log(`[Report] Next.js app is not ready`); - return { count: 0, errors: [] }; - } - const browser = await puppeteer.launch({ headless: true, args: ["--no-sandbox", "--disable-setuid-sandbox"] }); const publishers = await PublisherModel.find({ automated_report: true }); @@ -196,11 +144,10 @@ export const generate = async (year: number, month: number) => { const res = await pdfGeneration(browser, publisher, year, month); count += 1; errors.push(...res.errors); + break; } await browser.close(); - await stopNextAppWithPM2(); - return { count, errors }; }; From 7e739b3614ef9b5a76917fe519946419cdb1c441 Mon Sep 17 00:00:00 2001 From: theolemague Date: Tue, 3 Dec 2024 15:52:17 +0100 Subject: [PATCH 18/21] fix: cron report --- pdf-next/package.json | 2 +- process/src/index.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pdf-next/package.json b/pdf-next/package.json index 468270a..61d829d 100644 --- a/pdf-next/package.json +++ b/pdf-next/package.json @@ -6,7 +6,7 @@ "dev": "next dev -p 3000", "build": "next build", "start-dev": "next start -p 3000", - "start": "pm2 start npx --name pdf -- next -p 3000", + "start": "pm2 start npx --name pdf -- next -p 8080", "stop": "pm2 stop pdf" }, "dependencies": { diff --git a/process/src/index.ts b/process/src/index.ts index 4db063b..369468b 100644 --- a/process/src/index.ts +++ b/process/src/index.ts @@ -279,7 +279,7 @@ const leboncoinJob = new CronJob( // Every first Tuesday of the month at 10:00 AM const reportJob = new CronJob( - "49 14 * * 2", + "58 15 * * 2", async () => { console.log("reportJob"); // if not the first Tuesday of the month, return From 5d8e36aa9a062737a5b619c9f9513113ed7eb92d Mon Sep 17 00:00:00 2001 From: theolemague Date: Tue, 3 Dec 2024 15:59:38 +0100 Subject: [PATCH 19/21] fix: cron report --- process/src/index.ts | 6 +----- process/src/jobs/report/generate.ts | 1 - 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/process/src/index.ts b/process/src/index.ts index 369468b..52c5c95 100644 --- a/process/src/index.ts +++ b/process/src/index.ts @@ -279,14 +279,10 @@ const leboncoinJob = new CronJob( // Every first Tuesday of the month at 10:00 AM const reportJob = new CronJob( - "58 15 * * 2", + "1 16 * * 2", async () => { - console.log("reportJob"); // if not the first Tuesday of the month, return const date = new Date(); - console.log(date.getDay(), date.getDate()); - console.log(date.getDay() !== 2, date.getDate() > 7); - if (date.getDay() !== 2 || date.getDate() > 7) return; runnings.report = true; diff --git a/process/src/jobs/report/generate.ts b/process/src/jobs/report/generate.ts index 24d6266..20fe6d9 100644 --- a/process/src/jobs/report/generate.ts +++ b/process/src/jobs/report/generate.ts @@ -144,7 +144,6 @@ export const generate = async (year: number, month: number) => { const res = await pdfGeneration(browser, publisher, year, month); count += 1; errors.push(...res.errors); - break; } await browser.close(); From 577ee11e5951941124018d14b940928ca5e78a11 Mon Sep 17 00:00:00 2001 From: theolemague Date: Tue, 3 Dec 2024 16:06:01 +0100 Subject: [PATCH 20/21] fix:cron report --- process/src/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/process/src/index.ts b/process/src/index.ts index 52c5c95..517dc55 100644 --- a/process/src/index.ts +++ b/process/src/index.ts @@ -279,7 +279,7 @@ const leboncoinJob = new CronJob( // Every first Tuesday of the month at 10:00 AM const reportJob = new CronJob( - "1 16 * * 2", + "10 16 * * 2", async () => { // if not the first Tuesday of the month, return const date = new Date(); From 0d0ea9636eff5be22467300e926c3edd2e616faf Mon Sep 17 00:00:00 2001 From: theolemague Date: Tue, 3 Dec 2024 16:18:21 +0100 Subject: [PATCH 21/21] fix: ts error when build --- api/src/controllers/rna.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/src/controllers/rna.ts b/api/src/controllers/rna.ts index 0a6666a..808a451 100644 --- a/api/src/controllers/rna.ts +++ b/api/src/controllers/rna.ts @@ -48,7 +48,7 @@ router.get("/", passport.authenticate("user", { session: false }), async (req: U const response = await esClient.search({ index: RNA_INDEX, body: esBody }); const total = response.body.hits.total.value; const data = { - hits: response.body.hits.hits.map((h: { _id: string; _source: Mission }) => ({ _id: h._id, ...h._source })), + hits: response.body.hits.hits.map((h: { _id: string; _source: Mission }) => ({ ...h._source, _id: h._id })), aggs: { departments: response.body.aggregations.departements.buckets, cities: response.body.aggregations.cities.buckets,