From ad774121b0297e75dbce856bd7937ef46d2ce3bc Mon Sep 17 00:00:00 2001 From: Z8MB1E Date: Wed, 12 Aug 2026 12:38:55 -0400 Subject: [PATCH] feat(missions): add generate-mission bin for next Saturday template --- src/payload.config.ts | 4 ++ src/scripts/generateNextMission.ts | 87 ++++++++++++++++++++++++++++++ 2 files changed, 91 insertions(+) create mode 100644 src/scripts/generateNextMission.ts diff --git a/src/payload.config.ts b/src/payload.config.ts index 6839529..6c7c608 100644 --- a/src/payload.config.ts +++ b/src/payload.config.ts @@ -155,6 +155,10 @@ export default buildConfig({ scriptPath: path.resolve(dirname, "scripts/marketTick.ts"), key: "market-tick", }, + { + scriptPath: path.resolve(dirname, "scripts/generateNextMission.ts"), + key: "generate-mission", + }, ], plugins: [ // payloadCloudPlugin(), diff --git a/src/scripts/generateNextMission.ts b/src/scripts/generateNextMission.ts new file mode 100644 index 0000000..3bc9b40 --- /dev/null +++ b/src/scripts/generateNextMission.ts @@ -0,0 +1,87 @@ +import type { SanitizedConfig } from "payload"; +import { getPayload } from "payload"; + +export const script = async (config: SanitizedConfig) => { + const payload = await getPayload({ config }); + + payload.logger.info( + "[Generate Mission] Starting next mission template generation...", + ); + + const latest = await payload.find({ + collection: "missions", + where: { operationType: { equals: "main" } }, + sort: "-createdAt", + limit: 1, + depth: 0, + }); + + const source = latest.docs[0]; + if (!source) { + payload.logger.info( + '[Generate Mission] No "main" operation mission found; skipping. Create the first one manually.', + ); + process.exit(0); + } + + // Same logic as the Missions collection startDateTime default: the upcoming + // Saturday at 20:00, always at least a week out. + const today = new Date(); + const day = today.getDay(); + const diff = (6 - day) % 7; + const nextSaturday = new Date(today); + nextSaturday.setDate(today.getDate() + diff + 7); + nextSaturday.setHours(20, 0, 0, 0); + + const dateStamp = [ + nextSaturday.getFullYear(), + String(nextSaturday.getMonth() + 1).padStart(2, "0"), + String(nextSaturday.getDate()).padStart(2, "0"), + ].join(""); + + const codeName = `${source.codeName}-${dateStamp}`; + + const existing = await payload.find({ + collection: "missions", + where: { codeName: { equals: codeName } }, + limit: 1, + depth: 0, + }); + + if (existing.docs.length > 0) { + payload.logger.info( + `[Generate Mission] Mission with codeName "${codeName}" already exists; skipping.`, + ); + process.exit(0); + } + + const { + id: _sourceId, + createdAt: _sourceCreatedAt, + updatedAt: _sourceUpdatedAt, + ...template + } = source; + + const mission = await payload.create({ + collection: "missions", + data: { + ...template, + codeName, + classification: { + ...template.classification, + startDateTime: nextSaturday.toISOString(), + }, + ownershipAndStatus: { + ...template.ownershipAndStatus, + status: "Concept", + }, + }, + overrideAccess: true, + depth: 0, + }); + + payload.logger.info( + `[Generate Mission] Created next mission template: id=${mission.id} name="${mission.name}" codeName="${mission.codeName}" startDateTime=${mission.classification.startDateTime}`, + ); + process.exit(0); +};