diff --git a/src/back/jobs/BadgeAirdrop.ts b/src/back/jobs/BadgeAirdrop.ts index 7ec47a91c..8bbc0508d 100644 --- a/src/back/jobs/BadgeAirdrop.ts +++ b/src/back/jobs/BadgeAirdrop.ts @@ -11,7 +11,7 @@ export async function runAirdropJobs() { await Promise.all([runQueuedAirdropJobs(), giveAndRevokeLandOwnerBadges()]) } -async function runQueuedAirdropJobs() { +export async function runQueuedAirdropJobs() { const pendingJobs = await AirdropJobModel.getPending() if (pendingJobs.length === 0) { return @@ -31,7 +31,7 @@ async function runQueuedAirdropJobs() { }) } -async function giveAndRevokeLandOwnerBadges() { +export async function giveAndRevokeLandOwnerBadges() { if (isProdEnv()) { await BadgesService.giveAndRevokeLandOwnerBadges() } diff --git a/src/back/routes/debug.ts b/src/back/routes/debug.ts index 87859d3b0..75ec36443 100644 --- a/src/back/routes/debug.ts +++ b/src/back/routes/debug.ts @@ -4,6 +4,14 @@ import routes from 'decentraland-gatsby/dist/entities/Route/routes' import { DEBUG_ADDRESSES } from '../../entities/Debug/isDebugAddress' import { ErrorService } from '../../services/ErrorService' +import { giveAndRevokeLandOwnerBadges, giveTopVoterBadges, runQueuedAirdropJobs } from '../jobs/BadgeAirdrop' +import { validateDebugAddress } from '../utils/validations' + +const FUNCTIONS_MAP: { [key: string]: () => Promise } = { + runQueuedAirdropJobs, + giveAndRevokeLandOwnerBadges, + giveTopVoterBadges, +} export default routes((router) => { const withAuth = auth() @@ -12,8 +20,27 @@ export default routes((router) => { handleAPI(async () => DEBUG_ADDRESSES) ) router.post('/debug/report-error', withAuth, handleAPI(reportClientError)) + router.post('/debug/trigger', withAuth, handleAPI(triggerFunction)) }) function reportClientError(req: WithAuth): void { ErrorService.report(req.body.message, { frontend: true, ...req.body.extraInfo }) } + +async function triggerFunction(req: WithAuth) { + const user = req.auth! + validateDebugAddress(user) + + const { functionName } = req.body + + if (FUNCTIONS_MAP[functionName]) { + try { + const result = await FUNCTIONS_MAP[functionName]() + return { message: `Function '${functionName}' executed successfully.`, result } + } catch (error) { + throw new Error(`Error executing '${functionName}' function: ${error}`) + } + } else { + throw new Error(`Function '${functionName}' not found.`) + } +} diff --git a/src/clients/Governance.ts b/src/clients/Governance.ts index 3937b06dc..d20f0aef8 100644 --- a/src/clients/Governance.ts +++ b/src/clients/Governance.ts @@ -449,6 +449,14 @@ export class Governance extends API { return response.data } + async triggerFunction(functionName: string) { + const response = await this.fetch>( + `/debug/trigger`, + this.options().method('POST').authorization({ sign: true }).json({ functionName }) + ) + return response.data + } + async checkUrlTitle(url: string) { const response = await this.fetch>( `/url-title`, diff --git a/src/components/Debug/BadgesAdmin.tsx b/src/components/Debug/BadgesAdmin.tsx index d0c829f88..e3b45e348 100644 --- a/src/components/Debug/BadgesAdmin.tsx +++ b/src/components/Debug/BadgesAdmin.tsx @@ -99,19 +99,14 @@ export default function BadgesAdmin({ className }: Props) { {'Create, Airdrop, Revoke'}
- +
+ + setFunctionName(value as string)} + options={FUNCTION_NAME_OPTIONS} + disabled={formDisabled} + /> + {result && ( + <> + + {result} + + )} + + + {!!errorMessage && } + + ) +} diff --git a/src/pages/debug.tsx b/src/pages/debug.tsx index 64a8289a2..ce2d22759 100644 --- a/src/pages/debug.tsx +++ b/src/pages/debug.tsx @@ -11,6 +11,7 @@ import EnvStatus from '../components/Debug/EnvStatus' import ErrorReporting from '../components/Debug/ErrorReporting' import HttpStatus from '../components/Debug/HttpStatus' import SnapshotStatus from '../components/Debug/SnapshotStatus' +import TriggerFunction from '../components/Debug/TriggerFunction' import Navigation, { NavigationTab } from '../components/Layout/Navigation' import LogIn from '../components/User/LogIn' import useFormatMessage from '../hooks/useFormatMessage' @@ -37,6 +38,7 @@ export default function DebugPage() { + ) diff --git a/src/server.ts b/src/server.ts index af36eeab8..37a8cff69 100644 --- a/src/server.ts +++ b/src/server.ts @@ -40,16 +40,13 @@ import { activateProposals, finishProposal, publishBids } from './entities/Propo import { DiscordService } from './services/DiscordService' import filesystem from './utils/filesystem' -const FIRST_DAY_OF_EACH_MONTH = '0 0 1 * *' -const FIFTH_OF_SEPTEMBER = '0 0 5 9 *' // TODO: remove after 05-09-2013 const jobs = manager() jobs.cron('@eachMinute', finishProposal) jobs.cron('@eachMinute', activateProposals) jobs.cron('@eachMinute', publishBids) jobs.cron('@daily', updateGovernanceBudgets) jobs.cron('@daily', runAirdropJobs) -jobs.cron(FIRST_DAY_OF_EACH_MONTH, giveTopVoterBadges) -jobs.cron(FIFTH_OF_SEPTEMBER, giveTopVoterBadges) // TODO: remove after 05-09-2013 +jobs.cron('@monthly', giveTopVoterBadges) const file = readFileSync('static/api.yaml', 'utf8') const swaggerDocument = YAML.parse(file)