From b6bd4338c2ad7f251e2d218a2a1c12ddb342f953 Mon Sep 17 00:00:00 2001 From: kelvin <43873157+kelvinkipruto@users.noreply.github.com> Date: Fri, 27 Feb 2026 11:42:21 +0300 Subject: [PATCH 1/7] fix(tasks): continue workflows on recoverable task failures --- src/tasks/downloadDocuments.ts | 18 +++++++++++++-- src/tasks/extractDocuments.ts | 18 +++++++++++++-- src/tasks/extractPromises.ts | 18 +++++++++++++-- src/tasks/fetchAirtableDocuments.ts | 28 +++++++++++++++++++---- src/tasks/fetchMeedanPromiseStatus.ts | 17 ++++++++++++-- src/tasks/syncMeedanPromises.ts | 19 +++++++++++++-- src/tasks/updatePromiseStatus.ts | 33 +++++++++++++++++++-------- 7 files changed, 127 insertions(+), 24 deletions(-) diff --git a/src/tasks/downloadDocuments.ts b/src/tasks/downloadDocuments.ts index 183d64c4..df8df8b3 100644 --- a/src/tasks/downloadDocuments.ts +++ b/src/tasks/downloadDocuments.ts @@ -524,13 +524,27 @@ export const DownloadDocuments: TaskConfig<"downloadDocuments"> = { output: {}, }; } catch (error) { + const errorMessage = + error instanceof Error ? error.message : String(error ?? ""); logger.error({ message: "downloadDocuments:: Error in document download task", requestedDocumentIds: (input as TaskInput | undefined)?.documentIds?.filter(Boolean) ?? [], - error: error instanceof Error ? error.message : String(error), + error: errorMessage, }); - throw error; + + logger.warn({ + message: + "downloadDocuments:: Continuing workflow despite task-level failure", + recoverable: true, + }); + + return { + output: { + recoverableError: true, + error: errorMessage, + }, + }; } }), }; diff --git a/src/tasks/extractDocuments.ts b/src/tasks/extractDocuments.ts index 0bf41536..63fbd027 100644 --- a/src/tasks/extractDocuments.ts +++ b/src/tasks/extractDocuments.ts @@ -315,13 +315,27 @@ export const ExtractDocuments: TaskConfig<"extractDocuments"> = { output: {}, }; } catch (error) { + const errorMessage = + error instanceof Error ? error.message : String(error ?? ""); logger.error({ message: "extractDocuments:: Error in document extraction task", requestedDocumentIds: (input as TaskInput | undefined)?.documentIds?.filter(Boolean) ?? [], - error: error instanceof Error ? error.message : String(error), + error: errorMessage, }); - throw error; + + logger.warn({ + message: + "extractDocuments:: Continuing workflow despite task-level failure", + recoverable: true, + }); + + return { + output: { + recoverableError: true, + error: errorMessage, + }, + }; } }), }; diff --git a/src/tasks/extractPromises.ts b/src/tasks/extractPromises.ts index 82a42d44..86195886 100644 --- a/src/tasks/extractPromises.ts +++ b/src/tasks/extractPromises.ts @@ -300,13 +300,27 @@ export const ExtractPromises: TaskConfig<"extractPromises"> = { output: {}, }; } catch (error) { + const errorMessage = + error instanceof Error ? error.message : String(error ?? ""); logger.error({ message: "extractPromises:: Error in promise extraction task", requestedDocumentIds: (input as TaskInput | undefined)?.documentIds?.filter(Boolean) ?? [], - error: error instanceof Error ? error.message : String(error), + error: errorMessage, }); - throw error; + + logger.warn({ + message: + "extractPromises:: Continuing workflow despite task-level failure", + recoverable: true, + }); + + return { + output: { + recoverableError: true, + error: errorMessage, + }, + }; } }), }; diff --git a/src/tasks/fetchAirtableDocuments.ts b/src/tasks/fetchAirtableDocuments.ts index f80dea72..a4a4726b 100644 --- a/src/tasks/fetchAirtableDocuments.ts +++ b/src/tasks/fetchAirtableDocuments.ts @@ -239,9 +239,13 @@ export const FetchAirtableDocuments: TaskConfig<"fetchAirtableDocuments"> = { }); const failedDocIDs = failedDocs.map((failedDoc) => failedDoc.docID); - throw new Error( - `fetchAirtableDocuments:: Failed to create documents: ${failedDocIDs.join(", ")}`, - ); + logger.warn({ + message: + "fetchAirtableDocuments:: Completed with partial failures", + createdDocsCount, + failedDocsCount: failedDocs.length, + failedDocIDs, + }); } logger.info( @@ -251,12 +255,26 @@ export const FetchAirtableDocuments: TaskConfig<"fetchAirtableDocuments"> = { output: {}, }; } catch (error) { + const errorMessage = + error instanceof Error ? error.message : String(error ?? ""); logger.error({ message: "fetchAirtableDocuments:: Error fetching documents from Airtable", - error: error instanceof Error ? error.message : String(error), + error: errorMessage, + }); + + logger.warn({ + message: + "fetchAirtableDocuments:: Continuing workflow despite task-level failure", + recoverable: true, }); - throw error; + + return { + output: { + recoverableError: true, + error: errorMessage, + }, + }; } }), }; diff --git a/src/tasks/fetchMeedanPromiseStatus.ts b/src/tasks/fetchMeedanPromiseStatus.ts index dc3c8394..09dd0e91 100644 --- a/src/tasks/fetchMeedanPromiseStatus.ts +++ b/src/tasks/fetchMeedanPromiseStatus.ts @@ -99,12 +99,25 @@ export const FetchPromiseStatuses: TaskConfig<"fetchPromiseStatuses"> = { output: { created }, }; } catch (error) { + const errorMessage = + error instanceof Error ? error.message : String(error ?? ""); logger.error({ message: "fetchPromiseStatuses:: Failed to fetch/save statuses", teamId, - error: error instanceof Error ? error.message : String(error), + error: errorMessage, }); - throw error; + logger.warn({ + message: + "fetchPromiseStatuses:: Continuing workflow despite task-level failure", + recoverable: true, + }); + return { + output: { + created: 0, + recoverableError: true, + error: errorMessage, + }, + }; } }), }; diff --git a/src/tasks/syncMeedanPromises.ts b/src/tasks/syncMeedanPromises.ts index 571372c3..c6e1ea6a 100644 --- a/src/tasks/syncMeedanPromises.ts +++ b/src/tasks/syncMeedanPromises.ts @@ -48,12 +48,27 @@ export const SyncMeedanPromises: TaskConfig<"syncMeedanPromises"> = { output: result, }; } catch (error) { + const errorMessage = + error instanceof Error ? error.message : String(error ?? ""); logger.error({ message: "syncMeedanPromises:: Failed syncing published reports", teamId, - error: error instanceof Error ? error.message : String(error), + error: errorMessage, }); - throw error; + logger.warn({ + message: + "syncMeedanPromises:: Continuing workflow despite task-level failure", + recoverable: true, + }); + return { + output: { + created: 0, + updated: 0, + total: 0, + recoverableError: true, + error: errorMessage, + }, + }; } }), }; diff --git a/src/tasks/updatePromiseStatus.ts b/src/tasks/updatePromiseStatus.ts index 5d78dd83..148da90b 100644 --- a/src/tasks/updatePromiseStatus.ts +++ b/src/tasks/updatePromiseStatus.ts @@ -30,15 +30,16 @@ export const UpdatePromiseStatus: TaskConfig<"updatePromiseStatus"> = { const logger = getTaskLogger(req, "updatePromiseStatus", input); logger.info("updatePromiseStatus:: Starting Meedan status sync"); - try { - const { - meedan: { meedanAPIKey, teamId }, - } = await payload.findGlobal({ slug: "settings" }); - if (!meedanAPIKey || !teamId) { - throw new Error("Meedan API key or team ID not configured in settings"); - } + const { + meedan: { meedanAPIKey, teamId }, + } = await payload.findGlobal({ slug: "settings" }); + + if (!meedanAPIKey || !teamId) { + throw new Error("Meedan API key or team ID not configured in settings"); + } + try { const remoteStatusesList = await fetchProjectMediaStatuses({ apiKey: meedanAPIKey, teamId, @@ -169,13 +170,27 @@ export const UpdatePromiseStatus: TaskConfig<"updatePromiseStatus"> = { }, }; } catch (error) { + const errorMessage = + error instanceof Error ? error.message : String(error ?? ""); logger.error({ message: "updatePromiseStatus:: Failed to sync statuses", requestedDocumentIds: (input as TaskInput | undefined)?.documentIds?.filter(Boolean) ?? [], - error: error instanceof Error ? error.message : String(error), + error: errorMessage, + }); + logger.warn({ + message: + "updatePromiseStatus:: Continuing workflow despite task-level failure", + recoverable: true, }); - throw error; + + return { + output: { + updated: 0, + recoverableError: true, + error: errorMessage, + }, + }; } }), }; From 86b9c9602dbb16f27b097193eccf3677b520a741 Mon Sep 17 00:00:00 2001 From: kelvin <43873157+kelvinkipruto@users.noreply.github.com> Date: Fri, 27 Feb 2026 11:44:27 +0300 Subject: [PATCH 2/7] chore(deps): update payloadcms dependencies to v3.77.0 --- package.json | 26 ++--- pnpm-lock.yaml | 251 ++++++++++++++++++++----------------------- src/payload-types.ts | 5 +- 3 files changed, 135 insertions(+), 147 deletions(-) diff --git a/package.json b/package.json index 6762add1..b8b4d546 100644 --- a/package.json +++ b/package.json @@ -32,18 +32,18 @@ "@mui/material-nextjs": "^7.3.2", "@mui/utils": "^7.3.2", "@next/third-parties": "^15.5.3", - "@payloadcms/db-mongodb": "3.74.0", - "@payloadcms/email-nodemailer": "3.74.0", - "@payloadcms/next": "3.74.0", - "@payloadcms/payload-cloud": "3.74.0", - "@payloadcms/plugin-cloud-storage": "3.74.0", - "@payloadcms/plugin-multi-tenant": "3.74.0", - "@payloadcms/plugin-sentry": "3.74.0", - "@payloadcms/plugin-seo": "3.74.0", - "@payloadcms/richtext-lexical": "3.74.0", - "@payloadcms/storage-s3": "3.74.0", - "@payloadcms/translations": "3.74.0", - "@payloadcms/ui": "3.74.0", + "@payloadcms/db-mongodb": "3.77.0", + "@payloadcms/email-nodemailer": "3.77.0", + "@payloadcms/next": "3.77.0", + "@payloadcms/payload-cloud": "3.77.0", + "@payloadcms/plugin-cloud-storage": "3.77.0", + "@payloadcms/plugin-multi-tenant": "3.77.0", + "@payloadcms/plugin-sentry": "3.77.0", + "@payloadcms/plugin-seo": "3.77.0", + "@payloadcms/richtext-lexical": "3.77.0", + "@payloadcms/storage-s3": "3.77.0", + "@payloadcms/translations": "3.77.0", + "@payloadcms/ui": "3.77.0", "@sentry/nextjs": "^10.6.0", "@svgr/webpack": "^8.1.0", "ai": "^5.0.52", @@ -57,7 +57,7 @@ "graphql": "^16.11.0", "lucide-react": "^0.542.0", "next": "15.5.10", - "payload": "3.75.0", + "payload": "3.77.0", "react": "19.1.3", "react-dom": "19.1.3", "react-share": "^5.2.2", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 8a44a8d5..c7aa3166 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -25,7 +25,7 @@ importers: version: 11.14.1(@emotion/react@11.14.0(@types/react@19.1.11)(react@19.1.3))(@types/react@19.1.11)(react@19.1.3) '@innovixx/payload-color-picker-field': specifier: ^2.0.2 - version: 2.0.2(next@15.5.10(@babel/core@7.28.3)(@opentelemetry/api@1.9.0)(@playwright/test@1.55.0)(react-dom@19.1.3(react@19.1.3))(react@19.1.3)(sass@1.77.4))(payload@3.75.0(graphql@16.11.0)(typescript@5.9.2))(react-dom@19.1.3(react@19.1.3))(react@19.1.3) + version: 2.0.2(next@15.5.10(@babel/core@7.28.3)(@opentelemetry/api@1.9.0)(@playwright/test@1.55.0)(react-dom@19.1.3(react@19.1.3))(react@19.1.3)(sass@1.77.4))(payload@3.77.0(graphql@16.11.0)(typescript@5.9.2))(react-dom@19.1.3(react@19.1.3))(react@19.1.3) '@mui/icons-material': specifier: ^7.3.2 version: 7.3.2(@mui/material@7.3.2(@emotion/react@11.14.0(@types/react@19.1.11)(react@19.1.3))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.1.11)(react@19.1.3))(@types/react@19.1.11)(react@19.1.3))(@types/react@19.1.11)(react-dom@19.1.3(react@19.1.3))(react@19.1.3))(@types/react@19.1.11)(react@19.1.3) @@ -42,41 +42,41 @@ importers: specifier: ^15.5.3 version: 15.5.3(next@15.5.10(@babel/core@7.28.3)(@opentelemetry/api@1.9.0)(@playwright/test@1.55.0)(react-dom@19.1.3(react@19.1.3))(react@19.1.3)(sass@1.77.4))(react@19.1.3) '@payloadcms/db-mongodb': - specifier: 3.74.0 - version: 3.74.0(@aws-sdk/credential-providers@3.864.0)(payload@3.75.0(graphql@16.11.0)(typescript@5.9.2)) + specifier: 3.77.0 + version: 3.77.0(@aws-sdk/credential-providers@3.864.0)(payload@3.77.0(graphql@16.11.0)(typescript@5.9.2)) '@payloadcms/email-nodemailer': - specifier: 3.74.0 - version: 3.74.0(payload@3.75.0(graphql@16.11.0)(typescript@5.9.2)) + specifier: 3.77.0 + version: 3.77.0(payload@3.77.0(graphql@16.11.0)(typescript@5.9.2)) '@payloadcms/next': - specifier: 3.74.0 - version: 3.74.0(@types/react@19.1.11)(graphql@16.11.0)(monaco-editor@0.52.2)(next@15.5.10(@babel/core@7.28.3)(@opentelemetry/api@1.9.0)(@playwright/test@1.55.0)(react-dom@19.1.3(react@19.1.3))(react@19.1.3)(sass@1.77.4))(payload@3.75.0(graphql@16.11.0)(typescript@5.9.2))(react-dom@19.1.3(react@19.1.3))(react@19.1.3)(typescript@5.9.2) + specifier: 3.77.0 + version: 3.77.0(@types/react@19.1.11)(graphql@16.11.0)(monaco-editor@0.52.2)(next@15.5.10(@babel/core@7.28.3)(@opentelemetry/api@1.9.0)(@playwright/test@1.55.0)(react-dom@19.1.3(react@19.1.3))(react@19.1.3)(sass@1.77.4))(payload@3.77.0(graphql@16.11.0)(typescript@5.9.2))(react-dom@19.1.3(react@19.1.3))(react@19.1.3)(typescript@5.9.2) '@payloadcms/payload-cloud': - specifier: 3.74.0 - version: 3.74.0(payload@3.75.0(graphql@16.11.0)(typescript@5.9.2)) + specifier: 3.77.0 + version: 3.77.0(payload@3.77.0(graphql@16.11.0)(typescript@5.9.2)) '@payloadcms/plugin-cloud-storage': - specifier: 3.74.0 - version: 3.74.0(@types/react@19.1.11)(monaco-editor@0.52.2)(next@15.5.10(@babel/core@7.28.3)(@opentelemetry/api@1.9.0)(@playwright/test@1.55.0)(react-dom@19.1.3(react@19.1.3))(react@19.1.3)(sass@1.77.4))(payload@3.75.0(graphql@16.11.0)(typescript@5.9.2))(react-dom@19.1.3(react@19.1.3))(react@19.1.3)(typescript@5.9.2) + specifier: 3.77.0 + version: 3.77.0(@types/react@19.1.11)(monaco-editor@0.52.2)(next@15.5.10(@babel/core@7.28.3)(@opentelemetry/api@1.9.0)(@playwright/test@1.55.0)(react-dom@19.1.3(react@19.1.3))(react@19.1.3)(sass@1.77.4))(payload@3.77.0(graphql@16.11.0)(typescript@5.9.2))(react-dom@19.1.3(react@19.1.3))(react@19.1.3)(typescript@5.9.2) '@payloadcms/plugin-multi-tenant': - specifier: 3.74.0 - version: 3.74.0(@payloadcms/ui@3.74.0(@types/react@19.1.11)(monaco-editor@0.52.2)(next@15.5.10(@babel/core@7.28.3)(@opentelemetry/api@1.9.0)(@playwright/test@1.55.0)(react-dom@19.1.3(react@19.1.3))(react@19.1.3)(sass@1.77.4))(payload@3.75.0(graphql@16.11.0)(typescript@5.9.2))(react-dom@19.1.3(react@19.1.3))(react@19.1.3)(typescript@5.9.2))(payload@3.75.0(graphql@16.11.0)(typescript@5.9.2)) + specifier: 3.77.0 + version: 3.77.0(@payloadcms/ui@3.77.0(@types/react@19.1.11)(monaco-editor@0.52.2)(next@15.5.10(@babel/core@7.28.3)(@opentelemetry/api@1.9.0)(@playwright/test@1.55.0)(react-dom@19.1.3(react@19.1.3))(react@19.1.3)(sass@1.77.4))(payload@3.77.0(graphql@16.11.0)(typescript@5.9.2))(react-dom@19.1.3(react@19.1.3))(react@19.1.3)(typescript@5.9.2))(payload@3.77.0(graphql@16.11.0)(typescript@5.9.2)) '@payloadcms/plugin-sentry': - specifier: 3.74.0 - version: 3.74.0(@opentelemetry/context-async-hooks@2.0.1(@opentelemetry/api@1.9.0))(@opentelemetry/core@2.0.1(@opentelemetry/api@1.9.0))(@opentelemetry/instrumentation@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.0.1(@opentelemetry/api@1.9.0))(next@15.5.10(@babel/core@7.28.3)(@opentelemetry/api@1.9.0)(@playwright/test@1.55.0)(react-dom@19.1.3(react@19.1.3))(react@19.1.3)(sass@1.77.4))(payload@3.75.0(graphql@16.11.0)(typescript@5.9.2))(react-dom@19.1.3(react@19.1.3))(react@19.1.3)(webpack@5.101.3) + specifier: 3.77.0 + version: 3.77.0(@opentelemetry/context-async-hooks@2.0.1(@opentelemetry/api@1.9.0))(@opentelemetry/core@2.0.1(@opentelemetry/api@1.9.0))(@opentelemetry/instrumentation@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.0.1(@opentelemetry/api@1.9.0))(next@15.5.10(@babel/core@7.28.3)(@opentelemetry/api@1.9.0)(@playwright/test@1.55.0)(react-dom@19.1.3(react@19.1.3))(react@19.1.3)(sass@1.77.4))(payload@3.77.0(graphql@16.11.0)(typescript@5.9.2))(react-dom@19.1.3(react@19.1.3))(react@19.1.3)(webpack@5.101.3) '@payloadcms/plugin-seo': - specifier: 3.74.0 - version: 3.74.0(@types/react@19.1.11)(monaco-editor@0.52.2)(next@15.5.10(@babel/core@7.28.3)(@opentelemetry/api@1.9.0)(@playwright/test@1.55.0)(react-dom@19.1.3(react@19.1.3))(react@19.1.3)(sass@1.77.4))(payload@3.75.0(graphql@16.11.0)(typescript@5.9.2))(react-dom@19.1.3(react@19.1.3))(react@19.1.3)(typescript@5.9.2) + specifier: 3.77.0 + version: 3.77.0(@types/react@19.1.11)(monaco-editor@0.52.2)(next@15.5.10(@babel/core@7.28.3)(@opentelemetry/api@1.9.0)(@playwright/test@1.55.0)(react-dom@19.1.3(react@19.1.3))(react@19.1.3)(sass@1.77.4))(payload@3.77.0(graphql@16.11.0)(typescript@5.9.2))(react-dom@19.1.3(react@19.1.3))(react@19.1.3)(typescript@5.9.2) '@payloadcms/richtext-lexical': - specifier: 3.74.0 - version: 3.74.0(@faceless-ui/modal@3.0.0(react-dom@19.1.3(react@19.1.3))(react@19.1.3))(@faceless-ui/scroll-info@2.0.0(react-dom@19.1.3(react@19.1.3))(react@19.1.3))(@payloadcms/next@3.74.0(@types/react@19.1.11)(graphql@16.11.0)(monaco-editor@0.52.2)(next@15.5.10(@babel/core@7.28.3)(@opentelemetry/api@1.9.0)(@playwright/test@1.55.0)(react-dom@19.1.3(react@19.1.3))(react@19.1.3)(sass@1.77.4))(payload@3.75.0(graphql@16.11.0)(typescript@5.9.2))(react-dom@19.1.3(react@19.1.3))(react@19.1.3)(typescript@5.9.2))(@types/react@19.1.11)(monaco-editor@0.52.2)(next@15.5.10(@babel/core@7.28.3)(@opentelemetry/api@1.9.0)(@playwright/test@1.55.0)(react-dom@19.1.3(react@19.1.3))(react@19.1.3)(sass@1.77.4))(payload@3.75.0(graphql@16.11.0)(typescript@5.9.2))(react-dom@19.1.3(react@19.1.3))(react@19.1.3)(typescript@5.9.2)(yjs@13.6.27) + specifier: 3.77.0 + version: 3.77.0(@faceless-ui/modal@3.0.0(react-dom@19.1.3(react@19.1.3))(react@19.1.3))(@faceless-ui/scroll-info@2.0.0(react-dom@19.1.3(react@19.1.3))(react@19.1.3))(@payloadcms/next@3.77.0(@types/react@19.1.11)(graphql@16.11.0)(monaco-editor@0.52.2)(next@15.5.10(@babel/core@7.28.3)(@opentelemetry/api@1.9.0)(@playwright/test@1.55.0)(react-dom@19.1.3(react@19.1.3))(react@19.1.3)(sass@1.77.4))(payload@3.77.0(graphql@16.11.0)(typescript@5.9.2))(react-dom@19.1.3(react@19.1.3))(react@19.1.3)(typescript@5.9.2))(@types/react@19.1.11)(monaco-editor@0.52.2)(next@15.5.10(@babel/core@7.28.3)(@opentelemetry/api@1.9.0)(@playwright/test@1.55.0)(react-dom@19.1.3(react@19.1.3))(react@19.1.3)(sass@1.77.4))(payload@3.77.0(graphql@16.11.0)(typescript@5.9.2))(react-dom@19.1.3(react@19.1.3))(react@19.1.3)(typescript@5.9.2)(yjs@13.6.27) '@payloadcms/storage-s3': - specifier: 3.74.0 - version: 3.74.0(@types/react@19.1.11)(monaco-editor@0.52.2)(next@15.5.10(@babel/core@7.28.3)(@opentelemetry/api@1.9.0)(@playwright/test@1.55.0)(react-dom@19.1.3(react@19.1.3))(react@19.1.3)(sass@1.77.4))(payload@3.75.0(graphql@16.11.0)(typescript@5.9.2))(react-dom@19.1.3(react@19.1.3))(react@19.1.3)(typescript@5.9.2) + specifier: 3.77.0 + version: 3.77.0(@types/react@19.1.11)(monaco-editor@0.52.2)(next@15.5.10(@babel/core@7.28.3)(@opentelemetry/api@1.9.0)(@playwright/test@1.55.0)(react-dom@19.1.3(react@19.1.3))(react@19.1.3)(sass@1.77.4))(payload@3.77.0(graphql@16.11.0)(typescript@5.9.2))(react-dom@19.1.3(react@19.1.3))(react@19.1.3)(typescript@5.9.2) '@payloadcms/translations': - specifier: 3.74.0 - version: 3.74.0 + specifier: 3.77.0 + version: 3.77.0 '@payloadcms/ui': - specifier: 3.74.0 - version: 3.74.0(@types/react@19.1.11)(monaco-editor@0.52.2)(next@15.5.10(@babel/core@7.28.3)(@opentelemetry/api@1.9.0)(@playwright/test@1.55.0)(react-dom@19.1.3(react@19.1.3))(react@19.1.3)(sass@1.77.4))(payload@3.75.0(graphql@16.11.0)(typescript@5.9.2))(react-dom@19.1.3(react@19.1.3))(react@19.1.3)(typescript@5.9.2) + specifier: 3.77.0 + version: 3.77.0(@types/react@19.1.11)(monaco-editor@0.52.2)(next@15.5.10(@babel/core@7.28.3)(@opentelemetry/api@1.9.0)(@playwright/test@1.55.0)(react-dom@19.1.3(react@19.1.3))(react@19.1.3)(sass@1.77.4))(payload@3.77.0(graphql@16.11.0)(typescript@5.9.2))(react-dom@19.1.3(react@19.1.3))(react@19.1.3)(typescript@5.9.2) '@sentry/nextjs': specifier: ^10.6.0 version: 10.6.0(@opentelemetry/context-async-hooks@2.0.1(@opentelemetry/api@1.9.0))(@opentelemetry/core@2.0.1(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.0.1(@opentelemetry/api@1.9.0))(next@15.5.10(@babel/core@7.28.3)(@opentelemetry/api@1.9.0)(@playwright/test@1.55.0)(react-dom@19.1.3(react@19.1.3))(react@19.1.3)(sass@1.77.4))(react@19.1.3)(webpack@5.101.3) @@ -117,8 +117,8 @@ importers: specifier: 15.5.10 version: 15.5.10(@babel/core@7.28.3)(@opentelemetry/api@1.9.0)(@playwright/test@1.55.0)(react-dom@19.1.3(react@19.1.3))(react@19.1.3)(sass@1.77.4) payload: - specifier: 3.75.0 - version: 3.75.0(graphql@16.11.0)(typescript@5.9.2) + specifier: 3.77.0 + version: 3.77.0(graphql@16.11.0)(typescript@5.9.2) react: specifier: 19.1.3 version: 19.1.3 @@ -1018,10 +1018,6 @@ packages: resolution: {integrity: sha512-9uIQ10o0WGdpP6GDhXcdOJPJuDgFtIDtN/9+ArJQ2NAfAmiuhTQdzkaTGR33v43GYS2UrSA0eX2pPPHoFVvpxA==} engines: {node: '>=6.9.0'} - '@babel/runtime@7.28.4': - resolution: {integrity: sha512-Q/N6JNWvIvPnLDvjlE1OUBLPQHH6l3CltCEsHIujp45zQUSSh8K+gHnaEX45yAT1nyngnINhvWtzN+Nb9D8RAQ==} - engines: {node: '>=6.9.0'} - '@babel/runtime@7.28.6': resolution: {integrity: sha512-05WQkdpL9COIMz4LjTxGpPNCdlpyimKppYNoJ5Di5EUObifl8t4tuLuUBBZEpoLYOmfvIWrsp9fCl0HoPRVTdA==} engines: {node: '>=6.9.0'} @@ -2415,93 +2411,90 @@ packages: peerDependencies: '@opentelemetry/api': ^1.1.0 - '@payloadcms/db-mongodb@3.74.0': - resolution: {integrity: sha512-NuYOaAX/F9rpvT+R6ro3BKTlAI9ktaofCx0fSbUI/WUG5A6H8v8JOeO5/8HWaZBy9XoTzjRgQJmB0BuWzTtVIQ==} + '@payloadcms/db-mongodb@3.77.0': + resolution: {integrity: sha512-4T3UkrkE7Lp2+c8SSnQKjRypXT/7gXmwF/NAMX6J9aE6WXV3+qeGVdevrn8WPmlQVNqWWs1QuExyBpJJt1VSqg==} peerDependencies: - payload: 3.74.0 + payload: 3.77.0 - '@payloadcms/email-nodemailer@3.74.0': - resolution: {integrity: sha512-OYBdBs/bFOlpUtwibLTXjEuozWAlJ7DhF7GHwIyUJYI79+6IZQZkxqQYke1qLxIVU5AN0Mb2lw325sNoYyTBzQ==} + '@payloadcms/email-nodemailer@3.77.0': + resolution: {integrity: sha512-1i4JSYAzQ+t2htdZAbfek7cslWXYV0YeLN9MoDI6LSbR8Q6Run6idPBLdEkBNLPc0NJFVWepj2IgXt72ifdbtw==} engines: {node: ^18.20.2 || >=20.9.0} peerDependencies: - payload: 3.74.0 + payload: 3.77.0 - '@payloadcms/graphql@3.74.0': - resolution: {integrity: sha512-feMqBd+Mm4HJm34Ba2FBMCN7cqpUXyWU9uX2PHjnk20Ys9EbyTVccjyRU2k+jDFcjHhC0P2QAYJWYd2Pj5n7gg==} + '@payloadcms/graphql@3.77.0': + resolution: {integrity: sha512-OcJxsf16u38mvgWLawGrGoN4pFlu34vE6gANYAL1TYapiHgO7NerVwMrg3GQHlriSlaI/K9naLbhXdLp8R/nYw==} hasBin: true peerDependencies: graphql: ^16.8.1 - payload: 3.74.0 + payload: 3.77.0 - '@payloadcms/next@3.74.0': - resolution: {integrity: sha512-OfiUmCdhqgAGbN99FSQYfmJeHBdwUDzx2WlP4fxDeOW6LpnHNaipq9gvk1535+V0mPJXRRWIYQf3yPIxC9nOeA==} + '@payloadcms/next@3.77.0': + resolution: {integrity: sha512-6MvRjNdjMTJYoulNXT2XJJbFvzMKT7m1NV7c+l8rMqRc8HeIdi2zSGXuNdFAOFp03cgG5q9U+lrrgh4tll/pjA==} engines: {node: ^18.20.2 || >=20.9.0} peerDependencies: graphql: ^16.8.1 - next: ^15.4.10 || >=16.1.1-canary.35 <16.2.0 || ^16.2.0 - payload: 3.74.0 + next: '>=15.2.9 <15.3.0 || >=15.3.9 <15.4.0 || >=15.4.11 <15.5.0 || >=16.2.0-canary.10 <17.0.0' + payload: 3.77.0 - '@payloadcms/payload-cloud@3.74.0': - resolution: {integrity: sha512-qThbB9+/L+DhOab5iYLfnmOdGZ1yEXDK35fMh8TkfDX4/XcVH9qoHHTHR/TvYLtX9C917Nobhg3ZiM5h2Mb2PA==} + '@payloadcms/payload-cloud@3.77.0': + resolution: {integrity: sha512-6DXSXmnzQdMaPAchuHPdV4WfEDxtrz8MFAw4oS6253FlY3GPTzs9GVUd7fzml/YSDDuDjuRol25/sGqLocdEOg==} peerDependencies: - payload: 3.74.0 + payload: 3.77.0 - '@payloadcms/plugin-cloud-storage@3.74.0': - resolution: {integrity: sha512-tsAb85UqBfK2djT0rXdeq7pczBmXBvUUeMbssBG8aoqjida9d4LdD8wt7WDkq6FLQngkZRGsZwGWUj+vGv0TVA==} + '@payloadcms/plugin-cloud-storage@3.77.0': + resolution: {integrity: sha512-dAnEAS0as3C3s0l4YTPOT6tRZnxqXsagsj3RJp99898nyILHoERGqqCUTVS0QedwwVqNp7mNQM4p5zQqPLhtHw==} peerDependencies: - payload: 3.74.0 + payload: 3.77.0 react: ^19.0.1 || ^19.1.2 || ^19.2.1 react-dom: ^19.0.1 || ^19.1.2 || ^19.2.1 - '@payloadcms/plugin-multi-tenant@3.74.0': - resolution: {integrity: sha512-J1orq+24phUg3SUEla2CSeEDJzjuAnIOLaK28pChIBS/sni6mpJEV6bs0hiIMGo+LuDD6MPcSjbNrWyv1pZ3IQ==} + '@payloadcms/plugin-multi-tenant@3.77.0': + resolution: {integrity: sha512-EQuG/O3xsrN5yyGq2AfErrK/1KKkTXKnBzMq2l60Yl1xVAw5FkjVa+SC+pJJtrvNSBOHQxTy6vsHANPghiu7kw==} peerDependencies: - '@payloadcms/ui': 3.74.0 - payload: 3.74.0 + '@payloadcms/ui': 3.77.0 + payload: 3.77.0 - '@payloadcms/plugin-sentry@3.74.0': - resolution: {integrity: sha512-11RT5hAUe4C8HaWh22mofGMsFf7cBVvXhoXF3Qcka7Y98484b3YYCQtbh3vcMP229HcpmISw4kGm85zdZFEa7w==} + '@payloadcms/plugin-sentry@3.77.0': + resolution: {integrity: sha512-mnPv/0bR7D74iOlQeitQn0HeiiIW5nNa4j3pJdBssPin2DdtdV2U6iFw5y2IPQN8sOIbTtrax6/AQj7QIVsvgw==} peerDependencies: - payload: 3.74.0 + payload: 3.77.0 react: ^19.0.1 || ^19.1.2 || ^19.2.1 react-dom: ^19.0.1 || ^19.1.2 || ^19.2.1 - '@payloadcms/plugin-seo@3.74.0': - resolution: {integrity: sha512-jzR02Yc6EmZaJBXFCIHitp3XTRx4MGKD2P62IVUYDsH6BdeJ6fdB4CevokovPpwdfxs7CX/cXKRhHBfbs/w71g==} + '@payloadcms/plugin-seo@3.77.0': + resolution: {integrity: sha512-YYSTdHTccQKRkHrQX4Nq2Ltjqo7UIkMCAOMW3rLsQ+f6/Fp1l23ZaMxaxrtb8tmiY99fg/NGRpTW7dc9/v+s0Q==} peerDependencies: - payload: 3.74.0 + payload: 3.77.0 react: ^19.0.1 || ^19.1.2 || ^19.2.1 react-dom: ^19.0.1 || ^19.1.2 || ^19.2.1 - '@payloadcms/richtext-lexical@3.74.0': - resolution: {integrity: sha512-kauysxEe6y5IhZA/Kcr3q8T4e3j6BuvqJgxEa72yR11IJUI0mE+6Sfqr1SjEUgFPuz8xDlLKVtqsalhvkOCLUQ==} + '@payloadcms/richtext-lexical@3.77.0': + resolution: {integrity: sha512-hDTAHMRvuEzI1csL4tCw4HK2r7ybYsoQH9enhPXFehfL2uOHIYManqwuBPLxmCpIM7/ia/cF8RXUODvHF+pAgA==} engines: {node: ^18.20.2 || >=20.9.0} peerDependencies: '@faceless-ui/modal': 3.0.0 '@faceless-ui/scroll-info': 2.0.0 - '@payloadcms/next': 3.74.0 - payload: 3.74.0 + '@payloadcms/next': 3.77.0 + payload: 3.77.0 react: ^19.0.1 || ^19.1.2 || ^19.2.1 react-dom: ^19.0.1 || ^19.1.2 || ^19.2.1 - '@payloadcms/storage-s3@3.74.0': - resolution: {integrity: sha512-LCa+CFXtj+ju+As3obIMQwtvuaivVjVkWfJ9pTK+YsFbdtLscJVR8rRzVb7ivRmkR/ZqkJgqMllumiL2qeIpIQ==} + '@payloadcms/storage-s3@3.77.0': + resolution: {integrity: sha512-QTD6H5xH64o8z0iLgv2wxKLKR8StgoFHsaRonkU/qLwrDdNPRjsQLIssc0EtvkyfHdWvdrScjb8VDZKri0Q0gw==} engines: {node: ^18.20.2 || >=20.9.0} peerDependencies: - payload: 3.74.0 + payload: 3.77.0 - '@payloadcms/translations@3.74.0': - resolution: {integrity: sha512-SGzF37i7yQ6av8sTrjBIEd4415hb4Dx66KW+aPsCYaiH5mf6TIXqkdmsteytxV1t1XYMG+jufbv7Gi0NeC3xdw==} + '@payloadcms/translations@3.77.0': + resolution: {integrity: sha512-vDlliIsB7JJqBKuL/YKnzSPfrgfkROudVohJQcP5wBCJBIAtcPqBAKmGlGf4nfUwexN7brixmg2uV2L1B0DKrQ==} - '@payloadcms/translations@3.75.0': - resolution: {integrity: sha512-WbSf105UVAeanl7zPUcemhIgVM9mR8wF92nmNmic4I5+rDChC99btfvlnQrUEOt/+Y7THSiaQTgL4ytun8xd0w==} - - '@payloadcms/ui@3.74.0': - resolution: {integrity: sha512-2AfzDIte0d6KFHkgN5erMr41t/JghTik6IAXm7MICKB4zMyMujah+CdJPd3PnacvAWtlaNFOVRVEx8ahl/PIJg==} + '@payloadcms/ui@3.77.0': + resolution: {integrity: sha512-CCgsehZEyLgS9Njb1NT78ERIW2lC0VEtITaFIa7MBtzGBQ0Uzmk0T7ycE8qbdqz280gNJsPTIocQ9rc237Yy1w==} engines: {node: ^18.20.2 || >=20.9.0} peerDependencies: - next: ^15.2.8 || ^15.3.8 || ^15.4.10 || ^15.5.9 || >=16.1.1-canary.35 <16.2.0 || ^16.2.0 - payload: 3.74.0 + next: '>=15.2.9 <15.3.0 || >=15.3.9 <15.4.0 || >=15.4.11 <15.5.0 || >=16.2.0-canary.10 <17.0.0' + payload: 3.77.0 react: ^19.0.1 || ^19.1.2 || ^19.2.1 react-dom: ^19.0.1 || ^19.1.2 || ^19.2.1 @@ -5488,8 +5481,8 @@ packages: resolution: {integrity: sha512-//nshmD55c46FuFw26xV/xFAaB5HF9Xdap7HJBBnrKdAd6/GxDBaNA1870O79+9ueg61cZLSVc+OaFlfmObYVQ==} engines: {node: '>= 14.16'} - payload@3.75.0: - resolution: {integrity: sha512-JYJ545zu6URTMlhst1SBXW8WOAMeSfaIXffKluPUgzNfwWB/NcyzXjea+H7AGnL4nZiWJQhfbaRxvGherByXew==} + payload@3.77.0: + resolution: {integrity: sha512-hIdQ1sWpu0KPb9Okd9HahZxaddhLdFBo476AR5KX/6H9o4NRlQ5a2HZN+pgXO51M9aPbIBkArk8Ph/LvI4U3LQ==} engines: {node: ^18.20.2 || >=20.9.0} hasBin: true peerDependencies: @@ -8002,8 +7995,6 @@ snapshots: '@babel/runtime@7.28.3': {} - '@babel/runtime@7.28.4': {} - '@babel/runtime@7.28.6': {} '@babel/template@7.27.2': @@ -8545,10 +8536,10 @@ snapshots: '@img/sharp-win32-x64@0.34.3': optional: true - '@innovixx/payload-color-picker-field@2.0.2(next@15.5.10(@babel/core@7.28.3)(@opentelemetry/api@1.9.0)(@playwright/test@1.55.0)(react-dom@19.1.3(react@19.1.3))(react@19.1.3)(sass@1.77.4))(payload@3.75.0(graphql@16.11.0)(typescript@5.9.2))(react-dom@19.1.3(react@19.1.3))(react@19.1.3)': + '@innovixx/payload-color-picker-field@2.0.2(next@15.5.10(@babel/core@7.28.3)(@opentelemetry/api@1.9.0)(@playwright/test@1.55.0)(react-dom@19.1.3(react@19.1.3))(react@19.1.3)(sass@1.77.4))(payload@3.77.0(graphql@16.11.0)(typescript@5.9.2))(react-dom@19.1.3(react@19.1.3))(react@19.1.3)': dependencies: next: 15.5.10(@babel/core@7.28.3)(@opentelemetry/api@1.9.0)(@playwright/test@1.55.0)(react-dom@19.1.3(react@19.1.3))(react@19.1.3)(sass@1.77.4) - payload: 3.75.0(graphql@16.11.0)(typescript@5.9.2) + payload: 3.77.0(graphql@16.11.0)(typescript@5.9.2) react: 19.1.3 react-colorful: 5.6.1(react-dom@19.1.3(react@19.1.3))(react@19.1.3) transitivePeerDependencies: @@ -9430,11 +9421,11 @@ snapshots: '@opentelemetry/api': 1.9.0 '@opentelemetry/core': 2.0.1(@opentelemetry/api@1.9.0) - '@payloadcms/db-mongodb@3.74.0(@aws-sdk/credential-providers@3.864.0)(payload@3.75.0(graphql@16.11.0)(typescript@5.9.2))': + '@payloadcms/db-mongodb@3.77.0(@aws-sdk/credential-providers@3.864.0)(payload@3.77.0(graphql@16.11.0)(typescript@5.9.2))': dependencies: mongoose: 8.15.1(@aws-sdk/credential-providers@3.864.0) mongoose-paginate-v2: 1.8.5 - payload: 3.75.0(graphql@16.11.0)(typescript@5.9.2) + payload: 3.77.0(graphql@16.11.0)(typescript@5.9.2) prompts: 2.4.2 uuid: 10.0.0 transitivePeerDependencies: @@ -9447,30 +9438,30 @@ snapshots: - socks - supports-color - '@payloadcms/email-nodemailer@3.74.0(payload@3.75.0(graphql@16.11.0)(typescript@5.9.2))': + '@payloadcms/email-nodemailer@3.77.0(payload@3.77.0(graphql@16.11.0)(typescript@5.9.2))': dependencies: nodemailer: 7.0.12 - payload: 3.75.0(graphql@16.11.0)(typescript@5.9.2) + payload: 3.77.0(graphql@16.11.0)(typescript@5.9.2) - '@payloadcms/graphql@3.74.0(graphql@16.11.0)(payload@3.75.0(graphql@16.11.0)(typescript@5.9.2))(typescript@5.9.2)': + '@payloadcms/graphql@3.77.0(graphql@16.11.0)(payload@3.77.0(graphql@16.11.0)(typescript@5.9.2))(typescript@5.9.2)': dependencies: graphql: 16.11.0 graphql-scalars: 1.22.2(graphql@16.11.0) - payload: 3.75.0(graphql@16.11.0)(typescript@5.9.2) + payload: 3.77.0(graphql@16.11.0)(typescript@5.9.2) pluralize: 8.0.0 ts-essentials: 10.0.3(typescript@5.9.2) tsx: 4.21.0 transitivePeerDependencies: - typescript - '@payloadcms/next@3.74.0(@types/react@19.1.11)(graphql@16.11.0)(monaco-editor@0.52.2)(next@15.5.10(@babel/core@7.28.3)(@opentelemetry/api@1.9.0)(@playwright/test@1.55.0)(react-dom@19.1.3(react@19.1.3))(react@19.1.3)(sass@1.77.4))(payload@3.75.0(graphql@16.11.0)(typescript@5.9.2))(react-dom@19.1.3(react@19.1.3))(react@19.1.3)(typescript@5.9.2)': + '@payloadcms/next@3.77.0(@types/react@19.1.11)(graphql@16.11.0)(monaco-editor@0.52.2)(next@15.5.10(@babel/core@7.28.3)(@opentelemetry/api@1.9.0)(@playwright/test@1.55.0)(react-dom@19.1.3(react@19.1.3))(react@19.1.3)(sass@1.77.4))(payload@3.77.0(graphql@16.11.0)(typescript@5.9.2))(react-dom@19.1.3(react@19.1.3))(react@19.1.3)(typescript@5.9.2)': dependencies: '@dnd-kit/core': 6.3.1(react-dom@19.1.3(react@19.1.3))(react@19.1.3) '@dnd-kit/modifiers': 9.0.0(@dnd-kit/core@6.3.1(react-dom@19.1.3(react@19.1.3))(react@19.1.3))(react@19.1.3) '@dnd-kit/sortable': 10.0.0(@dnd-kit/core@6.3.1(react-dom@19.1.3(react@19.1.3))(react@19.1.3))(react@19.1.3) - '@payloadcms/graphql': 3.74.0(graphql@16.11.0)(payload@3.75.0(graphql@16.11.0)(typescript@5.9.2))(typescript@5.9.2) - '@payloadcms/translations': 3.74.0 - '@payloadcms/ui': 3.74.0(@types/react@19.1.11)(monaco-editor@0.52.2)(next@15.5.10(@babel/core@7.28.3)(@opentelemetry/api@1.9.0)(@playwright/test@1.55.0)(react-dom@19.1.3(react@19.1.3))(react@19.1.3)(sass@1.77.4))(payload@3.75.0(graphql@16.11.0)(typescript@5.9.2))(react-dom@19.1.3(react@19.1.3))(react@19.1.3)(typescript@5.9.2) + '@payloadcms/graphql': 3.77.0(graphql@16.11.0)(payload@3.77.0(graphql@16.11.0)(typescript@5.9.2))(typescript@5.9.2) + '@payloadcms/translations': 3.77.0 + '@payloadcms/ui': 3.77.0(@types/react@19.1.11)(monaco-editor@0.52.2)(next@15.5.10(@babel/core@7.28.3)(@opentelemetry/api@1.9.0)(@playwright/test@1.55.0)(react-dom@19.1.3(react@19.1.3))(react@19.1.3)(sass@1.77.4))(payload@3.77.0(graphql@16.11.0)(typescript@5.9.2))(react-dom@19.1.3(react@19.1.3))(react@19.1.3)(typescript@5.9.2) busboy: 1.6.0 dequal: 2.0.3 file-type: 19.3.0 @@ -9480,7 +9471,7 @@ snapshots: http-status: 2.1.0 next: 15.5.10(@babel/core@7.28.3)(@opentelemetry/api@1.9.0)(@playwright/test@1.55.0)(react-dom@19.1.3(react@19.1.3))(react@19.1.3)(sass@1.77.4) path-to-regexp: 6.3.0 - payload: 3.75.0(graphql@16.11.0)(typescript@5.9.2) + payload: 3.77.0(graphql@16.11.0)(typescript@5.9.2) qs-esm: 7.0.2 sass: 1.77.4 uuid: 10.0.0 @@ -9492,25 +9483,25 @@ snapshots: - supports-color - typescript - '@payloadcms/payload-cloud@3.74.0(payload@3.75.0(graphql@16.11.0)(typescript@5.9.2))': + '@payloadcms/payload-cloud@3.77.0(payload@3.77.0(graphql@16.11.0)(typescript@5.9.2))': dependencies: '@aws-sdk/client-cognito-identity': 3.864.0 '@aws-sdk/client-s3': 3.864.0 '@aws-sdk/credential-providers': 3.864.0 '@aws-sdk/lib-storage': 3.864.0(@aws-sdk/client-s3@3.864.0) - '@payloadcms/email-nodemailer': 3.74.0(payload@3.75.0(graphql@16.11.0)(typescript@5.9.2)) + '@payloadcms/email-nodemailer': 3.77.0(payload@3.77.0(graphql@16.11.0)(typescript@5.9.2)) amazon-cognito-identity-js: 6.3.15 nodemailer: 7.0.12 - payload: 3.75.0(graphql@16.11.0)(typescript@5.9.2) + payload: 3.77.0(graphql@16.11.0)(typescript@5.9.2) transitivePeerDependencies: - aws-crt - encoding - '@payloadcms/plugin-cloud-storage@3.74.0(@types/react@19.1.11)(monaco-editor@0.52.2)(next@15.5.10(@babel/core@7.28.3)(@opentelemetry/api@1.9.0)(@playwright/test@1.55.0)(react-dom@19.1.3(react@19.1.3))(react@19.1.3)(sass@1.77.4))(payload@3.75.0(graphql@16.11.0)(typescript@5.9.2))(react-dom@19.1.3(react@19.1.3))(react@19.1.3)(typescript@5.9.2)': + '@payloadcms/plugin-cloud-storage@3.77.0(@types/react@19.1.11)(monaco-editor@0.52.2)(next@15.5.10(@babel/core@7.28.3)(@opentelemetry/api@1.9.0)(@playwright/test@1.55.0)(react-dom@19.1.3(react@19.1.3))(react@19.1.3)(sass@1.77.4))(payload@3.77.0(graphql@16.11.0)(typescript@5.9.2))(react-dom@19.1.3(react@19.1.3))(react@19.1.3)(typescript@5.9.2)': dependencies: - '@payloadcms/ui': 3.74.0(@types/react@19.1.11)(monaco-editor@0.52.2)(next@15.5.10(@babel/core@7.28.3)(@opentelemetry/api@1.9.0)(@playwright/test@1.55.0)(react-dom@19.1.3(react@19.1.3))(react@19.1.3)(sass@1.77.4))(payload@3.75.0(graphql@16.11.0)(typescript@5.9.2))(react-dom@19.1.3(react@19.1.3))(react@19.1.3)(typescript@5.9.2) + '@payloadcms/ui': 3.77.0(@types/react@19.1.11)(monaco-editor@0.52.2)(next@15.5.10(@babel/core@7.28.3)(@opentelemetry/api@1.9.0)(@playwright/test@1.55.0)(react-dom@19.1.3(react@19.1.3))(react@19.1.3)(sass@1.77.4))(payload@3.77.0(graphql@16.11.0)(typescript@5.9.2))(react-dom@19.1.3(react@19.1.3))(react@19.1.3)(typescript@5.9.2) find-node-modules: 2.1.3 - payload: 3.75.0(graphql@16.11.0)(typescript@5.9.2) + payload: 3.77.0(graphql@16.11.0)(typescript@5.9.2) range-parser: 1.2.1 react: 19.1.3 react-dom: 19.1.3(react@19.1.3) @@ -9521,16 +9512,16 @@ snapshots: - supports-color - typescript - '@payloadcms/plugin-multi-tenant@3.74.0(@payloadcms/ui@3.74.0(@types/react@19.1.11)(monaco-editor@0.52.2)(next@15.5.10(@babel/core@7.28.3)(@opentelemetry/api@1.9.0)(@playwright/test@1.55.0)(react-dom@19.1.3(react@19.1.3))(react@19.1.3)(sass@1.77.4))(payload@3.75.0(graphql@16.11.0)(typescript@5.9.2))(react-dom@19.1.3(react@19.1.3))(react@19.1.3)(typescript@5.9.2))(payload@3.75.0(graphql@16.11.0)(typescript@5.9.2))': + '@payloadcms/plugin-multi-tenant@3.77.0(@payloadcms/ui@3.77.0(@types/react@19.1.11)(monaco-editor@0.52.2)(next@15.5.10(@babel/core@7.28.3)(@opentelemetry/api@1.9.0)(@playwright/test@1.55.0)(react-dom@19.1.3(react@19.1.3))(react@19.1.3)(sass@1.77.4))(payload@3.77.0(graphql@16.11.0)(typescript@5.9.2))(react-dom@19.1.3(react@19.1.3))(react@19.1.3)(typescript@5.9.2))(payload@3.77.0(graphql@16.11.0)(typescript@5.9.2))': dependencies: - '@payloadcms/ui': 3.74.0(@types/react@19.1.11)(monaco-editor@0.52.2)(next@15.5.10(@babel/core@7.28.3)(@opentelemetry/api@1.9.0)(@playwright/test@1.55.0)(react-dom@19.1.3(react@19.1.3))(react@19.1.3)(sass@1.77.4))(payload@3.75.0(graphql@16.11.0)(typescript@5.9.2))(react-dom@19.1.3(react@19.1.3))(react@19.1.3)(typescript@5.9.2) - payload: 3.75.0(graphql@16.11.0)(typescript@5.9.2) + '@payloadcms/ui': 3.77.0(@types/react@19.1.11)(monaco-editor@0.52.2)(next@15.5.10(@babel/core@7.28.3)(@opentelemetry/api@1.9.0)(@playwright/test@1.55.0)(react-dom@19.1.3(react@19.1.3))(react@19.1.3)(sass@1.77.4))(payload@3.77.0(graphql@16.11.0)(typescript@5.9.2))(react-dom@19.1.3(react@19.1.3))(react@19.1.3)(typescript@5.9.2) + payload: 3.77.0(graphql@16.11.0)(typescript@5.9.2) - '@payloadcms/plugin-sentry@3.74.0(@opentelemetry/context-async-hooks@2.0.1(@opentelemetry/api@1.9.0))(@opentelemetry/core@2.0.1(@opentelemetry/api@1.9.0))(@opentelemetry/instrumentation@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.0.1(@opentelemetry/api@1.9.0))(next@15.5.10(@babel/core@7.28.3)(@opentelemetry/api@1.9.0)(@playwright/test@1.55.0)(react-dom@19.1.3(react@19.1.3))(react@19.1.3)(sass@1.77.4))(payload@3.75.0(graphql@16.11.0)(typescript@5.9.2))(react-dom@19.1.3(react@19.1.3))(react@19.1.3)(webpack@5.101.3)': + '@payloadcms/plugin-sentry@3.77.0(@opentelemetry/context-async-hooks@2.0.1(@opentelemetry/api@1.9.0))(@opentelemetry/core@2.0.1(@opentelemetry/api@1.9.0))(@opentelemetry/instrumentation@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.0.1(@opentelemetry/api@1.9.0))(next@15.5.10(@babel/core@7.28.3)(@opentelemetry/api@1.9.0)(@playwright/test@1.55.0)(react-dom@19.1.3(react@19.1.3))(react@19.1.3)(sass@1.77.4))(payload@3.77.0(graphql@16.11.0)(typescript@5.9.2))(react-dom@19.1.3(react@19.1.3))(react@19.1.3)(webpack@5.101.3)': dependencies: '@sentry/nextjs': 8.55.0(@opentelemetry/context-async-hooks@2.0.1(@opentelemetry/api@1.9.0))(@opentelemetry/core@2.0.1(@opentelemetry/api@1.9.0))(@opentelemetry/instrumentation@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.0.1(@opentelemetry/api@1.9.0))(next@15.5.10(@babel/core@7.28.3)(@opentelemetry/api@1.9.0)(@playwright/test@1.55.0)(react-dom@19.1.3(react@19.1.3))(react@19.1.3)(sass@1.77.4))(react@19.1.3)(webpack@5.101.3) '@sentry/types': 8.55.0 - payload: 3.75.0(graphql@16.11.0)(typescript@5.9.2) + payload: 3.77.0(graphql@16.11.0)(typescript@5.9.2) react: 19.1.3 react-dom: 19.1.3(react@19.1.3) transitivePeerDependencies: @@ -9543,11 +9534,11 @@ snapshots: - supports-color - webpack - '@payloadcms/plugin-seo@3.74.0(@types/react@19.1.11)(monaco-editor@0.52.2)(next@15.5.10(@babel/core@7.28.3)(@opentelemetry/api@1.9.0)(@playwright/test@1.55.0)(react-dom@19.1.3(react@19.1.3))(react@19.1.3)(sass@1.77.4))(payload@3.75.0(graphql@16.11.0)(typescript@5.9.2))(react-dom@19.1.3(react@19.1.3))(react@19.1.3)(typescript@5.9.2)': + '@payloadcms/plugin-seo@3.77.0(@types/react@19.1.11)(monaco-editor@0.52.2)(next@15.5.10(@babel/core@7.28.3)(@opentelemetry/api@1.9.0)(@playwright/test@1.55.0)(react-dom@19.1.3(react@19.1.3))(react@19.1.3)(sass@1.77.4))(payload@3.77.0(graphql@16.11.0)(typescript@5.9.2))(react-dom@19.1.3(react@19.1.3))(react@19.1.3)(typescript@5.9.2)': dependencies: - '@payloadcms/translations': 3.74.0 - '@payloadcms/ui': 3.74.0(@types/react@19.1.11)(monaco-editor@0.52.2)(next@15.5.10(@babel/core@7.28.3)(@opentelemetry/api@1.9.0)(@playwright/test@1.55.0)(react-dom@19.1.3(react@19.1.3))(react@19.1.3)(sass@1.77.4))(payload@3.75.0(graphql@16.11.0)(typescript@5.9.2))(react-dom@19.1.3(react@19.1.3))(react@19.1.3)(typescript@5.9.2) - payload: 3.75.0(graphql@16.11.0)(typescript@5.9.2) + '@payloadcms/translations': 3.77.0 + '@payloadcms/ui': 3.77.0(@types/react@19.1.11)(monaco-editor@0.52.2)(next@15.5.10(@babel/core@7.28.3)(@opentelemetry/api@1.9.0)(@playwright/test@1.55.0)(react-dom@19.1.3(react@19.1.3))(react@19.1.3)(sass@1.77.4))(payload@3.77.0(graphql@16.11.0)(typescript@5.9.2))(react-dom@19.1.3(react@19.1.3))(react@19.1.3)(typescript@5.9.2) + payload: 3.77.0(graphql@16.11.0)(typescript@5.9.2) react: 19.1.3 react-dom: 19.1.3(react@19.1.3) transitivePeerDependencies: @@ -9557,7 +9548,7 @@ snapshots: - supports-color - typescript - '@payloadcms/richtext-lexical@3.74.0(@faceless-ui/modal@3.0.0(react-dom@19.1.3(react@19.1.3))(react@19.1.3))(@faceless-ui/scroll-info@2.0.0(react-dom@19.1.3(react@19.1.3))(react@19.1.3))(@payloadcms/next@3.74.0(@types/react@19.1.11)(graphql@16.11.0)(monaco-editor@0.52.2)(next@15.5.10(@babel/core@7.28.3)(@opentelemetry/api@1.9.0)(@playwright/test@1.55.0)(react-dom@19.1.3(react@19.1.3))(react@19.1.3)(sass@1.77.4))(payload@3.75.0(graphql@16.11.0)(typescript@5.9.2))(react-dom@19.1.3(react@19.1.3))(react@19.1.3)(typescript@5.9.2))(@types/react@19.1.11)(monaco-editor@0.52.2)(next@15.5.10(@babel/core@7.28.3)(@opentelemetry/api@1.9.0)(@playwright/test@1.55.0)(react-dom@19.1.3(react@19.1.3))(react@19.1.3)(sass@1.77.4))(payload@3.75.0(graphql@16.11.0)(typescript@5.9.2))(react-dom@19.1.3(react@19.1.3))(react@19.1.3)(typescript@5.9.2)(yjs@13.6.27)': + '@payloadcms/richtext-lexical@3.77.0(@faceless-ui/modal@3.0.0(react-dom@19.1.3(react@19.1.3))(react@19.1.3))(@faceless-ui/scroll-info@2.0.0(react-dom@19.1.3(react@19.1.3))(react@19.1.3))(@payloadcms/next@3.77.0(@types/react@19.1.11)(graphql@16.11.0)(monaco-editor@0.52.2)(next@15.5.10(@babel/core@7.28.3)(@opentelemetry/api@1.9.0)(@playwright/test@1.55.0)(react-dom@19.1.3(react@19.1.3))(react@19.1.3)(sass@1.77.4))(payload@3.77.0(graphql@16.11.0)(typescript@5.9.2))(react-dom@19.1.3(react@19.1.3))(react@19.1.3)(typescript@5.9.2))(@types/react@19.1.11)(monaco-editor@0.52.2)(next@15.5.10(@babel/core@7.28.3)(@opentelemetry/api@1.9.0)(@playwright/test@1.55.0)(react-dom@19.1.3(react@19.1.3))(react@19.1.3)(sass@1.77.4))(payload@3.77.0(graphql@16.11.0)(typescript@5.9.2))(react-dom@19.1.3(react@19.1.3))(react@19.1.3)(typescript@5.9.2)(yjs@13.6.27)': dependencies: '@faceless-ui/modal': 3.0.0(react-dom@19.1.3(react@19.1.3))(react@19.1.3) '@faceless-ui/scroll-info': 2.0.0(react-dom@19.1.3(react@19.1.3))(react@19.1.3) @@ -9572,9 +9563,9 @@ snapshots: '@lexical/selection': 0.35.0 '@lexical/table': 0.35.0 '@lexical/utils': 0.35.0 - '@payloadcms/next': 3.74.0(@types/react@19.1.11)(graphql@16.11.0)(monaco-editor@0.52.2)(next@15.5.10(@babel/core@7.28.3)(@opentelemetry/api@1.9.0)(@playwright/test@1.55.0)(react-dom@19.1.3(react@19.1.3))(react@19.1.3)(sass@1.77.4))(payload@3.75.0(graphql@16.11.0)(typescript@5.9.2))(react-dom@19.1.3(react@19.1.3))(react@19.1.3)(typescript@5.9.2) - '@payloadcms/translations': 3.74.0 - '@payloadcms/ui': 3.74.0(@types/react@19.1.11)(monaco-editor@0.52.2)(next@15.5.10(@babel/core@7.28.3)(@opentelemetry/api@1.9.0)(@playwright/test@1.55.0)(react-dom@19.1.3(react@19.1.3))(react@19.1.3)(sass@1.77.4))(payload@3.75.0(graphql@16.11.0)(typescript@5.9.2))(react-dom@19.1.3(react@19.1.3))(react@19.1.3)(typescript@5.9.2) + '@payloadcms/next': 3.77.0(@types/react@19.1.11)(graphql@16.11.0)(monaco-editor@0.52.2)(next@15.5.10(@babel/core@7.28.3)(@opentelemetry/api@1.9.0)(@playwright/test@1.55.0)(react-dom@19.1.3(react@19.1.3))(react@19.1.3)(sass@1.77.4))(payload@3.77.0(graphql@16.11.0)(typescript@5.9.2))(react-dom@19.1.3(react@19.1.3))(react@19.1.3)(typescript@5.9.2) + '@payloadcms/translations': 3.77.0 + '@payloadcms/ui': 3.77.0(@types/react@19.1.11)(monaco-editor@0.52.2)(next@15.5.10(@babel/core@7.28.3)(@opentelemetry/api@1.9.0)(@playwright/test@1.55.0)(react-dom@19.1.3(react@19.1.3))(react@19.1.3)(sass@1.77.4))(payload@3.77.0(graphql@16.11.0)(typescript@5.9.2))(react-dom@19.1.3(react@19.1.3))(react@19.1.3)(typescript@5.9.2) '@types/uuid': 10.0.0 acorn: 8.12.1 bson-objectid: 2.0.4 @@ -9586,7 +9577,7 @@ snapshots: mdast-util-from-markdown: 2.0.2 mdast-util-mdx-jsx: 3.1.3 micromark-extension-mdx-jsx: 3.0.1 - payload: 3.75.0(graphql@16.11.0)(typescript@5.9.2) + payload: 3.77.0(graphql@16.11.0)(typescript@5.9.2) qs-esm: 7.0.2 react: 19.1.3 react-dom: 19.1.3(react@19.1.3) @@ -9601,13 +9592,13 @@ snapshots: - typescript - yjs - '@payloadcms/storage-s3@3.74.0(@types/react@19.1.11)(monaco-editor@0.52.2)(next@15.5.10(@babel/core@7.28.3)(@opentelemetry/api@1.9.0)(@playwright/test@1.55.0)(react-dom@19.1.3(react@19.1.3))(react@19.1.3)(sass@1.77.4))(payload@3.75.0(graphql@16.11.0)(typescript@5.9.2))(react-dom@19.1.3(react@19.1.3))(react@19.1.3)(typescript@5.9.2)': + '@payloadcms/storage-s3@3.77.0(@types/react@19.1.11)(monaco-editor@0.52.2)(next@15.5.10(@babel/core@7.28.3)(@opentelemetry/api@1.9.0)(@playwright/test@1.55.0)(react-dom@19.1.3(react@19.1.3))(react@19.1.3)(sass@1.77.4))(payload@3.77.0(graphql@16.11.0)(typescript@5.9.2))(react-dom@19.1.3(react@19.1.3))(react@19.1.3)(typescript@5.9.2)': dependencies: '@aws-sdk/client-s3': 3.864.0 '@aws-sdk/lib-storage': 3.864.0(@aws-sdk/client-s3@3.864.0) '@aws-sdk/s3-request-presigner': 3.891.0 - '@payloadcms/plugin-cloud-storage': 3.74.0(@types/react@19.1.11)(monaco-editor@0.52.2)(next@15.5.10(@babel/core@7.28.3)(@opentelemetry/api@1.9.0)(@playwright/test@1.55.0)(react-dom@19.1.3(react@19.1.3))(react@19.1.3)(sass@1.77.4))(payload@3.75.0(graphql@16.11.0)(typescript@5.9.2))(react-dom@19.1.3(react@19.1.3))(react@19.1.3)(typescript@5.9.2) - payload: 3.75.0(graphql@16.11.0)(typescript@5.9.2) + '@payloadcms/plugin-cloud-storage': 3.77.0(@types/react@19.1.11)(monaco-editor@0.52.2)(next@15.5.10(@babel/core@7.28.3)(@opentelemetry/api@1.9.0)(@playwright/test@1.55.0)(react-dom@19.1.3(react@19.1.3))(react@19.1.3)(sass@1.77.4))(payload@3.77.0(graphql@16.11.0)(typescript@5.9.2))(react-dom@19.1.3(react@19.1.3))(react@19.1.3)(typescript@5.9.2) + payload: 3.77.0(graphql@16.11.0)(typescript@5.9.2) transitivePeerDependencies: - '@types/react' - aws-crt @@ -9618,15 +9609,11 @@ snapshots: - supports-color - typescript - '@payloadcms/translations@3.74.0': + '@payloadcms/translations@3.77.0': dependencies: date-fns: 4.1.0 - '@payloadcms/translations@3.75.0': - dependencies: - date-fns: 4.1.0 - - '@payloadcms/ui@3.74.0(@types/react@19.1.11)(monaco-editor@0.52.2)(next@15.5.10(@babel/core@7.28.3)(@opentelemetry/api@1.9.0)(@playwright/test@1.55.0)(react-dom@19.1.3(react@19.1.3))(react@19.1.3)(sass@1.77.4))(payload@3.75.0(graphql@16.11.0)(typescript@5.9.2))(react-dom@19.1.3(react@19.1.3))(react@19.1.3)(typescript@5.9.2)': + '@payloadcms/ui@3.77.0(@types/react@19.1.11)(monaco-editor@0.52.2)(next@15.5.10(@babel/core@7.28.3)(@opentelemetry/api@1.9.0)(@playwright/test@1.55.0)(react-dom@19.1.3(react@19.1.3))(react@19.1.3)(sass@1.77.4))(payload@3.77.0(graphql@16.11.0)(typescript@5.9.2))(react-dom@19.1.3(react@19.1.3))(react@19.1.3)(typescript@5.9.2)': dependencies: '@date-fns/tz': 1.2.0 '@dnd-kit/core': 6.3.1(react-dom@19.1.3(react@19.1.3))(react@19.1.3) @@ -9636,14 +9623,14 @@ snapshots: '@faceless-ui/scroll-info': 2.0.0(react-dom@19.1.3(react@19.1.3))(react@19.1.3) '@faceless-ui/window-info': 3.0.1(react-dom@19.1.3(react@19.1.3))(react@19.1.3) '@monaco-editor/react': 4.7.0(monaco-editor@0.52.2)(react-dom@19.1.3(react@19.1.3))(react@19.1.3) - '@payloadcms/translations': 3.74.0 + '@payloadcms/translations': 3.77.0 bson-objectid: 2.0.4 date-fns: 4.1.0 dequal: 2.0.3 md5: 2.3.0 next: 15.5.10(@babel/core@7.28.3)(@opentelemetry/api@1.9.0)(@playwright/test@1.55.0)(react-dom@19.1.3(react@19.1.3))(react@19.1.3)(sass@1.77.4) object-to-formdata: 4.5.1 - payload: 3.75.0(graphql@16.11.0)(typescript@5.9.2) + payload: 3.77.0(graphql@16.11.0)(typescript@5.9.2) qs-esm: 7.0.2 react: 19.1.3 react-datepicker: 7.6.0(react-dom@19.1.3(react@19.1.3))(react@19.1.3) @@ -10692,7 +10679,7 @@ snapshots: '@types/connect@3.4.36': dependencies: - '@types/node': 24.10.0 + '@types/node': 24.10.13 '@types/connect@3.4.38': dependencies: @@ -10738,7 +10725,7 @@ snapshots: '@types/mysql@2.15.26': dependencies: - '@types/node': 24.10.0 + '@types/node': 24.10.13 '@types/mysql@2.15.27': dependencies: @@ -13313,10 +13300,10 @@ snapshots: pathval@2.0.1: {} - payload@3.75.0(graphql@16.11.0)(typescript@5.9.2): + payload@3.77.0(graphql@16.11.0)(typescript@5.9.2): dependencies: '@next/env': 15.5.12 - '@payloadcms/translations': 3.75.0 + '@payloadcms/translations': 3.77.0 '@types/busboy': 1.5.4 ajv: 8.17.1 bson-objectid: 2.0.4 @@ -13520,12 +13507,12 @@ snapshots: react-error-boundary@3.1.4(react@19.1.3): dependencies: - '@babel/runtime': 7.28.4 + '@babel/runtime': 7.28.6 react: 19.1.3 react-error-boundary@4.1.2(react@19.1.3): dependencies: - '@babel/runtime': 7.28.4 + '@babel/runtime': 7.28.6 react: 19.1.3 react-image-crop@10.1.8(react@19.1.3): @@ -13542,7 +13529,7 @@ snapshots: react-select@5.9.0(@types/react@19.1.11)(react-dom@19.1.3(react@19.1.3))(react@19.1.3): dependencies: - '@babel/runtime': 7.28.4 + '@babel/runtime': 7.28.6 '@emotion/cache': 11.14.0 '@emotion/react': 11.14.0(@types/react@19.1.11)(react@19.1.3) '@floating-ui/dom': 1.7.3 @@ -14229,7 +14216,7 @@ snapshots: unplugin@1.0.1: dependencies: - acorn: 8.15.0 + acorn: 8.16.0 chokidar: 3.6.0 webpack-sources: 3.3.3 webpack-virtual-modules: 0.5.0 diff --git a/src/payload-types.ts b/src/payload-types.ts index 2ff03574..94e6296b 100644 --- a/src/payload-types.ts +++ b/src/payload-types.ts @@ -124,7 +124,9 @@ export interface Config { 'payload-jobs-stats': PayloadJobsStatsSelect | PayloadJobsStatsSelect; }; locale: 'en' | 'fr'; - user: User; + user: User & { + collection: 'users'; + }; jobs: { tasks: { createTenantFromAirtable: TaskCreateTenantFromAirtable; @@ -768,7 +770,6 @@ export interface User { }[] | null; password?: string | null; - collection: 'users'; } /** * This interface was referenced by `Config`'s JSON-Schema From 781218c7749db8b54b85b60eaa2774d27642d319 Mon Sep 17 00:00:00 2001 From: kelvin <43873157+kelvinkipruto@users.noreply.github.com> Date: Fri, 27 Feb 2026 12:17:06 +0300 Subject: [PATCH 3/7] fix(tasks): restore retries and skip invalid Airtable docs --- src/tasks/downloadDocuments.ts | 14 +--- src/tasks/extractDocuments.ts | 14 +--- src/tasks/extractPromises.ts | 14 +--- src/tasks/fetchAirtableDocuments.ts | 96 +++++++++++++++++---------- src/tasks/fetchMeedanPromiseStatus.ts | 13 +--- src/tasks/syncMeedanPromises.ts | 15 +---- src/tasks/updatePromiseStatus.ts | 14 +--- 7 files changed, 68 insertions(+), 112 deletions(-) diff --git a/src/tasks/downloadDocuments.ts b/src/tasks/downloadDocuments.ts index df8df8b3..56a67960 100644 --- a/src/tasks/downloadDocuments.ts +++ b/src/tasks/downloadDocuments.ts @@ -532,19 +532,7 @@ export const DownloadDocuments: TaskConfig<"downloadDocuments"> = { (input as TaskInput | undefined)?.documentIds?.filter(Boolean) ?? [], error: errorMessage, }); - - logger.warn({ - message: - "downloadDocuments:: Continuing workflow despite task-level failure", - recoverable: true, - }); - - return { - output: { - recoverableError: true, - error: errorMessage, - }, - }; + throw error; } }), }; diff --git a/src/tasks/extractDocuments.ts b/src/tasks/extractDocuments.ts index 63fbd027..eca07389 100644 --- a/src/tasks/extractDocuments.ts +++ b/src/tasks/extractDocuments.ts @@ -323,19 +323,7 @@ export const ExtractDocuments: TaskConfig<"extractDocuments"> = { (input as TaskInput | undefined)?.documentIds?.filter(Boolean) ?? [], error: errorMessage, }); - - logger.warn({ - message: - "extractDocuments:: Continuing workflow despite task-level failure", - recoverable: true, - }); - - return { - output: { - recoverableError: true, - error: errorMessage, - }, - }; + throw error; } }), }; diff --git a/src/tasks/extractPromises.ts b/src/tasks/extractPromises.ts index 86195886..806c53e3 100644 --- a/src/tasks/extractPromises.ts +++ b/src/tasks/extractPromises.ts @@ -308,19 +308,7 @@ export const ExtractPromises: TaskConfig<"extractPromises"> = { (input as TaskInput | undefined)?.documentIds?.filter(Boolean) ?? [], error: errorMessage, }); - - logger.warn({ - message: - "extractPromises:: Continuing workflow despite task-level failure", - recoverable: true, - }); - - return { - output: { - recoverableError: true, - error: errorMessage, - }, - }; + throw error; } }), }; diff --git a/src/tasks/fetchAirtableDocuments.ts b/src/tasks/fetchAirtableDocuments.ts index a4a4726b..c59c3b90 100644 --- a/src/tasks/fetchAirtableDocuments.ts +++ b/src/tasks/fetchAirtableDocuments.ts @@ -148,25 +148,59 @@ export const FetchAirtableDocuments: TaskConfig<"fetchAirtableDocuments"> = { limit: 0, depth: 2, }); + const entityByAirtableID = new Map( + entities + .filter((entity) => entity.airtableID) + .map((entity) => [entity.airtableID as string, entity]), + ); - const creationResults = await Promise.allSettled( - docsToCreate.map(async (doc) => { - const politicalEntityAirtableID = doc.politicalEntity?.[0]; + const failedDocs: Array<{ + docID: string; + docName: string | null; + politicalEntityAirtableID: string | null; + reason: unknown; + }> = []; - if (!politicalEntityAirtableID) { - throw new Error( - "Missing political entity Airtable ID for document", - ); - } + const docsReadyToCreate: AirtableDocumentCandidate[] = []; + for (const doc of docsToCreate) { + const politicalEntityAirtableID = doc.politicalEntity?.[0] ?? null; + if (!politicalEntityAirtableID) { + const reason = "Missing required field: Political Entity"; + failedDocs.push({ + docID: doc.id, + docName: getAirtableDocumentName(doc), + politicalEntityAirtableID: null, + reason, + }); + await setDocumentStatus(doc.id, `Failed: ${reason}`); + continue; + } + + const entity = entityByAirtableID.get(politicalEntityAirtableID); + if (!entity) { + const reason = `No political entity found for Airtable ID ${politicalEntityAirtableID}`; + failedDocs.push({ + docID: doc.id, + docName: getAirtableDocumentName(doc), + politicalEntityAirtableID, + reason, + }); + await setDocumentStatus(doc.id, `Failed: ${reason}`); + continue; + } + + docsReadyToCreate.push(doc); + } - const entity = entities.find( - (t) => t.airtableID === politicalEntityAirtableID, - ); + const creationResults = await Promise.allSettled( + docsReadyToCreate.map(async (doc) => { + const politicalEntityAirtableID = doc.politicalEntity?.[0]; + const entity = politicalEntityAirtableID + ? entityByAirtableID.get(politicalEntityAirtableID) + : null; if (!entity) { - throw new Error( - `No political entity found for Airtable ID ${politicalEntityAirtableID}`, - ); + return null; } const title = getAirtableDocumentName(doc); @@ -192,18 +226,24 @@ export const FetchAirtableDocuments: TaskConfig<"fetchAirtableDocuments"> = { }), ); - const failedDocs: Array<{ - docID: string; - docName: string | null; - politicalEntityAirtableID: string | null; - reason: unknown; - }> = []; let createdDocsCount = 0; for (const [index, result] of creationResults.entries()) { - const doc = docsToCreate[index]; + const doc = docsReadyToCreate[index]; if (result.status === "fulfilled") { + if (!result.value) { + const errorMessage = "Missing related political entity"; + failedDocs.push({ + docID: doc.id, + docName: getAirtableDocumentName(doc), + politicalEntityAirtableID: doc.politicalEntity?.[0] ?? null, + reason: errorMessage, + }); + await setDocumentStatus(doc.id, `Failed: ${errorMessage}`); + continue; + } + createdDocsCount += 1; await setDocumentStatus(doc.id, "Fetched"); continue; @@ -262,19 +302,7 @@ export const FetchAirtableDocuments: TaskConfig<"fetchAirtableDocuments"> = { "fetchAirtableDocuments:: Error fetching documents from Airtable", error: errorMessage, }); - - logger.warn({ - message: - "fetchAirtableDocuments:: Continuing workflow despite task-level failure", - recoverable: true, - }); - - return { - output: { - recoverableError: true, - error: errorMessage, - }, - }; + throw error; } }), }; diff --git a/src/tasks/fetchMeedanPromiseStatus.ts b/src/tasks/fetchMeedanPromiseStatus.ts index 09dd0e91..59936f20 100644 --- a/src/tasks/fetchMeedanPromiseStatus.ts +++ b/src/tasks/fetchMeedanPromiseStatus.ts @@ -106,18 +106,7 @@ export const FetchPromiseStatuses: TaskConfig<"fetchPromiseStatuses"> = { teamId, error: errorMessage, }); - logger.warn({ - message: - "fetchPromiseStatuses:: Continuing workflow despite task-level failure", - recoverable: true, - }); - return { - output: { - created: 0, - recoverableError: true, - error: errorMessage, - }, - }; + throw error; } }), }; diff --git a/src/tasks/syncMeedanPromises.ts b/src/tasks/syncMeedanPromises.ts index c6e1ea6a..56cc102a 100644 --- a/src/tasks/syncMeedanPromises.ts +++ b/src/tasks/syncMeedanPromises.ts @@ -55,20 +55,7 @@ export const SyncMeedanPromises: TaskConfig<"syncMeedanPromises"> = { teamId, error: errorMessage, }); - logger.warn({ - message: - "syncMeedanPromises:: Continuing workflow despite task-level failure", - recoverable: true, - }); - return { - output: { - created: 0, - updated: 0, - total: 0, - recoverableError: true, - error: errorMessage, - }, - }; + throw error; } }), }; diff --git a/src/tasks/updatePromiseStatus.ts b/src/tasks/updatePromiseStatus.ts index 148da90b..1ad6c1e0 100644 --- a/src/tasks/updatePromiseStatus.ts +++ b/src/tasks/updatePromiseStatus.ts @@ -178,19 +178,7 @@ export const UpdatePromiseStatus: TaskConfig<"updatePromiseStatus"> = { (input as TaskInput | undefined)?.documentIds?.filter(Boolean) ?? [], error: errorMessage, }); - logger.warn({ - message: - "updatePromiseStatus:: Continuing workflow despite task-level failure", - recoverable: true, - }); - - return { - output: { - updated: 0, - recoverableError: true, - error: errorMessage, - }, - }; + throw error; } }), }; From a5916f95dfb599f27586ad10128fa1b1e2feb6ff Mon Sep 17 00:00:00 2001 From: kelvin <43873157+kelvinkipruto@users.noreply.github.com> Date: Fri, 27 Feb 2026 12:29:47 +0300 Subject: [PATCH 4/7] refactor(fetchAirtableDocuments): remove unreachable entity branch --- src/tasks/fetchAirtableDocuments.ts | 35 +++++++++-------------------- 1 file changed, 10 insertions(+), 25 deletions(-) diff --git a/src/tasks/fetchAirtableDocuments.ts b/src/tasks/fetchAirtableDocuments.ts index c59c3b90..fe0608d0 100644 --- a/src/tasks/fetchAirtableDocuments.ts +++ b/src/tasks/fetchAirtableDocuments.ts @@ -161,7 +161,10 @@ export const FetchAirtableDocuments: TaskConfig<"fetchAirtableDocuments"> = { reason: unknown; }> = []; - const docsReadyToCreate: AirtableDocumentCandidate[] = []; + const docsReadyToCreate: Array<{ + doc: AirtableDocumentCandidate; + entity: (typeof entities)[number]; + }> = []; for (const doc of docsToCreate) { const politicalEntityAirtableID = doc.politicalEntity?.[0] ?? null; if (!politicalEntityAirtableID) { @@ -189,20 +192,14 @@ export const FetchAirtableDocuments: TaskConfig<"fetchAirtableDocuments"> = { continue; } - docsReadyToCreate.push(doc); + docsReadyToCreate.push({ + doc, + entity, + }); } const creationResults = await Promise.allSettled( - docsReadyToCreate.map(async (doc) => { - const politicalEntityAirtableID = doc.politicalEntity?.[0]; - const entity = politicalEntityAirtableID - ? entityByAirtableID.get(politicalEntityAirtableID) - : null; - - if (!entity) { - return null; - } - + docsReadyToCreate.map(async ({ doc, entity }) => { const title = getAirtableDocumentName(doc); const sourceUrl = getAirtableDocumentSourceUrl(doc); const docURLs = (doc.documents ?? []) @@ -229,21 +226,9 @@ export const FetchAirtableDocuments: TaskConfig<"fetchAirtableDocuments"> = { let createdDocsCount = 0; for (const [index, result] of creationResults.entries()) { - const doc = docsReadyToCreate[index]; + const { doc } = docsReadyToCreate[index]; if (result.status === "fulfilled") { - if (!result.value) { - const errorMessage = "Missing related political entity"; - failedDocs.push({ - docID: doc.id, - docName: getAirtableDocumentName(doc), - politicalEntityAirtableID: doc.politicalEntity?.[0] ?? null, - reason: errorMessage, - }); - await setDocumentStatus(doc.id, `Failed: ${errorMessage}`); - continue; - } - createdDocsCount += 1; await setDocumentStatus(doc.id, "Fetched"); continue; From bbb1536c3bddb042d3294babb3b34a1b14f0f581 Mon Sep 17 00:00:00 2001 From: kelvin <43873157+kelvinkipruto@users.noreply.github.com> Date: Fri, 27 Feb 2026 12:45:00 +0300 Subject: [PATCH 5/7] refactor: inline error message construction in logger calls Remove redundant errorMessage variable declarations and directly construct error messages within logger.error calls. This reduces code verbosity and improves readability by eliminating unnecessary intermediate variables. --- src/tasks/downloadDocuments.ts | 13 ++++++++----- src/tasks/extractDocuments.ts | 4 +--- src/tasks/extractPromises.ts | 4 +--- src/tasks/fetchMeedanPromiseStatus.ts | 4 +--- src/tasks/syncMeedanPromises.ts | 4 +--- src/tasks/updatePromiseStatus.ts | 7 +++---- 6 files changed, 15 insertions(+), 21 deletions(-) diff --git a/src/tasks/downloadDocuments.ts b/src/tasks/downloadDocuments.ts index 56a67960..5a0b7260 100644 --- a/src/tasks/downloadDocuments.ts +++ b/src/tasks/downloadDocuments.ts @@ -229,7 +229,10 @@ export const DownloadDocuments: TaskConfig<"downloadDocuments"> = { const sourceUrls = getDocumentSourceUrls(existingDoc); const sourceSignature = createSourceSignature(sourceUrls); - if (!sourceSignature || dedupeSourcesBySignature.has(sourceSignature)) { + if ( + !sourceSignature || + dedupeSourcesBySignature.has(sourceSignature) + ) { continue; } @@ -302,7 +305,9 @@ export const DownloadDocuments: TaskConfig<"downloadDocuments"> = { title: doc.title, }); await setDocumentStatus(doc.airtableID, "Downloading"); - const urlsToFetch = getDocumentSourceUrls(doc as DownloadableDocument); + const urlsToFetch = getDocumentSourceUrls( + doc as DownloadableDocument, + ); const sourceSignature = createSourceSignature(urlsToFetch); if (urlsToFetch.length === 0) { @@ -524,13 +529,11 @@ export const DownloadDocuments: TaskConfig<"downloadDocuments"> = { output: {}, }; } catch (error) { - const errorMessage = - error instanceof Error ? error.message : String(error ?? ""); logger.error({ message: "downloadDocuments:: Error in document download task", requestedDocumentIds: (input as TaskInput | undefined)?.documentIds?.filter(Boolean) ?? [], - error: errorMessage, + error: error instanceof Error ? error.message : String(error ?? ""), }); throw error; } diff --git a/src/tasks/extractDocuments.ts b/src/tasks/extractDocuments.ts index eca07389..7a6536e5 100644 --- a/src/tasks/extractDocuments.ts +++ b/src/tasks/extractDocuments.ts @@ -315,13 +315,11 @@ export const ExtractDocuments: TaskConfig<"extractDocuments"> = { output: {}, }; } catch (error) { - const errorMessage = - error instanceof Error ? error.message : String(error ?? ""); logger.error({ message: "extractDocuments:: Error in document extraction task", requestedDocumentIds: (input as TaskInput | undefined)?.documentIds?.filter(Boolean) ?? [], - error: errorMessage, + error: error instanceof Error ? error.message : String(error ?? ""), }); throw error; } diff --git a/src/tasks/extractPromises.ts b/src/tasks/extractPromises.ts index 806c53e3..70001763 100644 --- a/src/tasks/extractPromises.ts +++ b/src/tasks/extractPromises.ts @@ -300,13 +300,11 @@ export const ExtractPromises: TaskConfig<"extractPromises"> = { output: {}, }; } catch (error) { - const errorMessage = - error instanceof Error ? error.message : String(error ?? ""); logger.error({ message: "extractPromises:: Error in promise extraction task", requestedDocumentIds: (input as TaskInput | undefined)?.documentIds?.filter(Boolean) ?? [], - error: errorMessage, + error: error instanceof Error ? error.message : String(error ?? ""), }); throw error; } diff --git a/src/tasks/fetchMeedanPromiseStatus.ts b/src/tasks/fetchMeedanPromiseStatus.ts index 59936f20..fbf6a4c3 100644 --- a/src/tasks/fetchMeedanPromiseStatus.ts +++ b/src/tasks/fetchMeedanPromiseStatus.ts @@ -99,12 +99,10 @@ export const FetchPromiseStatuses: TaskConfig<"fetchPromiseStatuses"> = { output: { created }, }; } catch (error) { - const errorMessage = - error instanceof Error ? error.message : String(error ?? ""); logger.error({ message: "fetchPromiseStatuses:: Failed to fetch/save statuses", teamId, - error: errorMessage, + error: error instanceof Error ? error.message : String(error ?? ""), }); throw error; } diff --git a/src/tasks/syncMeedanPromises.ts b/src/tasks/syncMeedanPromises.ts index 56cc102a..d87f5bb2 100644 --- a/src/tasks/syncMeedanPromises.ts +++ b/src/tasks/syncMeedanPromises.ts @@ -48,12 +48,10 @@ export const SyncMeedanPromises: TaskConfig<"syncMeedanPromises"> = { output: result, }; } catch (error) { - const errorMessage = - error instanceof Error ? error.message : String(error ?? ""); logger.error({ message: "syncMeedanPromises:: Failed syncing published reports", teamId, - error: errorMessage, + error: error instanceof Error ? error.message : String(error ?? ""), }); throw error; } diff --git a/src/tasks/updatePromiseStatus.ts b/src/tasks/updatePromiseStatus.ts index 1ad6c1e0..685f023c 100644 --- a/src/tasks/updatePromiseStatus.ts +++ b/src/tasks/updatePromiseStatus.ts @@ -145,7 +145,8 @@ export const UpdatePromiseStatus: TaskConfig<"updatePromiseStatus"> = { } catch (extractionDocError) { failedExtractions += 1; logger.error({ - message: "updatePromiseStatus:: Failed processing AI extraction doc", + message: + "updatePromiseStatus:: Failed processing AI extraction doc", extractionDocId: extractionDoc.id, extractionDocTitle: extractionDoc.title, extractionCount: extractionDoc.extractions?.length ?? 0, @@ -170,13 +171,11 @@ export const UpdatePromiseStatus: TaskConfig<"updatePromiseStatus"> = { }, }; } catch (error) { - const errorMessage = - error instanceof Error ? error.message : String(error ?? ""); logger.error({ message: "updatePromiseStatus:: Failed to sync statuses", requestedDocumentIds: (input as TaskInput | undefined)?.documentIds?.filter(Boolean) ?? [], - error: errorMessage, + error: error instanceof Error ? error.message : String(error ?? ""), }); throw error; } From 267dbd6b73d5f60079ae4c03abfe7d95135dede3 Mon Sep 17 00:00:00 2001 From: kelvin <43873157+kelvinkipruto@users.noreply.github.com> Date: Fri, 27 Feb 2026 12:47:56 +0300 Subject: [PATCH 6/7] refactor(logging): simplify error string conversion in task handlers Remove unnecessary nullish coalescing with empty string when converting errors to strings. The String() constructor already handles null/undefined by converting them to "null"/"undefined", making the ?? "" redundant. --- src/tasks/downloadDocuments.ts | 2 +- src/tasks/extractDocuments.ts | 2 +- src/tasks/extractPromises.ts | 2 +- src/tasks/fetchMeedanPromiseStatus.ts | 2 +- src/tasks/syncMeedanPromises.ts | 2 +- src/tasks/updatePromiseStatus.ts | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/tasks/downloadDocuments.ts b/src/tasks/downloadDocuments.ts index 5a0b7260..e6d1b820 100644 --- a/src/tasks/downloadDocuments.ts +++ b/src/tasks/downloadDocuments.ts @@ -533,7 +533,7 @@ export const DownloadDocuments: TaskConfig<"downloadDocuments"> = { message: "downloadDocuments:: Error in document download task", requestedDocumentIds: (input as TaskInput | undefined)?.documentIds?.filter(Boolean) ?? [], - error: error instanceof Error ? error.message : String(error ?? ""), + error: error instanceof Error ? error.message : String(error), }); throw error; } diff --git a/src/tasks/extractDocuments.ts b/src/tasks/extractDocuments.ts index 7a6536e5..0bf41536 100644 --- a/src/tasks/extractDocuments.ts +++ b/src/tasks/extractDocuments.ts @@ -319,7 +319,7 @@ export const ExtractDocuments: TaskConfig<"extractDocuments"> = { message: "extractDocuments:: Error in document extraction task", requestedDocumentIds: (input as TaskInput | undefined)?.documentIds?.filter(Boolean) ?? [], - error: error instanceof Error ? error.message : String(error ?? ""), + error: error instanceof Error ? error.message : String(error), }); throw error; } diff --git a/src/tasks/extractPromises.ts b/src/tasks/extractPromises.ts index 70001763..82a42d44 100644 --- a/src/tasks/extractPromises.ts +++ b/src/tasks/extractPromises.ts @@ -304,7 +304,7 @@ export const ExtractPromises: TaskConfig<"extractPromises"> = { message: "extractPromises:: Error in promise extraction task", requestedDocumentIds: (input as TaskInput | undefined)?.documentIds?.filter(Boolean) ?? [], - error: error instanceof Error ? error.message : String(error ?? ""), + error: error instanceof Error ? error.message : String(error), }); throw error; } diff --git a/src/tasks/fetchMeedanPromiseStatus.ts b/src/tasks/fetchMeedanPromiseStatus.ts index fbf6a4c3..dc3c8394 100644 --- a/src/tasks/fetchMeedanPromiseStatus.ts +++ b/src/tasks/fetchMeedanPromiseStatus.ts @@ -102,7 +102,7 @@ export const FetchPromiseStatuses: TaskConfig<"fetchPromiseStatuses"> = { logger.error({ message: "fetchPromiseStatuses:: Failed to fetch/save statuses", teamId, - error: error instanceof Error ? error.message : String(error ?? ""), + error: error instanceof Error ? error.message : String(error), }); throw error; } diff --git a/src/tasks/syncMeedanPromises.ts b/src/tasks/syncMeedanPromises.ts index d87f5bb2..571372c3 100644 --- a/src/tasks/syncMeedanPromises.ts +++ b/src/tasks/syncMeedanPromises.ts @@ -51,7 +51,7 @@ export const SyncMeedanPromises: TaskConfig<"syncMeedanPromises"> = { logger.error({ message: "syncMeedanPromises:: Failed syncing published reports", teamId, - error: error instanceof Error ? error.message : String(error ?? ""), + error: error instanceof Error ? error.message : String(error), }); throw error; } diff --git a/src/tasks/updatePromiseStatus.ts b/src/tasks/updatePromiseStatus.ts index 685f023c..cdd139b2 100644 --- a/src/tasks/updatePromiseStatus.ts +++ b/src/tasks/updatePromiseStatus.ts @@ -175,7 +175,7 @@ export const UpdatePromiseStatus: TaskConfig<"updatePromiseStatus"> = { message: "updatePromiseStatus:: Failed to sync statuses", requestedDocumentIds: (input as TaskInput | undefined)?.documentIds?.filter(Boolean) ?? [], - error: error instanceof Error ? error.message : String(error ?? ""), + error: error instanceof Error ? error.message : String(error), }); throw error; } From 46c32fb4d07d51cf9d5f4f32e7ae34d12474c4de Mon Sep 17 00:00:00 2001 From: kelvin <43873157+kelvinkipruto@users.noreply.github.com> Date: Fri, 27 Feb 2026 12:49:29 +0300 Subject: [PATCH 7/7] refactor(payload-types): update types --- src/payload-types.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/payload-types.ts b/src/payload-types.ts index 94e6296b..2ff03574 100644 --- a/src/payload-types.ts +++ b/src/payload-types.ts @@ -124,9 +124,7 @@ export interface Config { 'payload-jobs-stats': PayloadJobsStatsSelect | PayloadJobsStatsSelect; }; locale: 'en' | 'fr'; - user: User & { - collection: 'users'; - }; + user: User; jobs: { tasks: { createTenantFromAirtable: TaskCreateTenantFromAirtable; @@ -770,6 +768,7 @@ export interface User { }[] | null; password?: string | null; + collection: 'users'; } /** * This interface was referenced by `Config`'s JSON-Schema