Files
myeasycms-v2/apps/web/app/api/internal/cron/member-jobs/route.ts
T. Zehetbauer 5c5aaabae5
Some checks failed
Workflow / ʦ TypeScript (pull_request) Failing after 5m57s
Workflow / ⚫️ Test (pull_request) Has been skipped
refactor: remove obsolete member management API module
2026-04-03 14:08:31 +02:00

88 lines
2.5 KiB
TypeScript

import { NextResponse } from 'next/server';
import { createMemberNotificationService } from '@kit/member-management/services';
import { getLogger } from '@kit/shared/logger';
import { getSupabaseServerAdminClient } from '@kit/supabase/server-admin-client';
const CRON_SECRET = process.env.CRON_SECRET;
/**
* Internal cron endpoint for member scheduled jobs.
* Called hourly by pg_cron or external scheduler.
*
* POST /api/internal/cron/member-jobs
* Header: Authorization: Bearer <CRON_SECRET>
*/
export async function POST(request: Request) {
const logger = await getLogger();
// Verify cron secret
const authHeader = request.headers.get('authorization');
const token = authHeader?.replace('Bearer ', '');
if (!CRON_SECRET || token !== CRON_SECRET) {
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
}
try {
const client = getSupabaseServerAdminClient();
const notificationService = createMemberNotificationService(client);
// 1. Process pending notification queue
const queueResult = await notificationService.processPendingNotifications();
// 2. Run scheduled jobs for all accounts with enabled jobs
const { data: accounts } = await (client.from as any)(
'scheduled_job_configs',
)
.select('account_id')
.eq('is_enabled', true)
.or(`next_run_at.is.null,next_run_at.lte.${new Date().toISOString()}`);
const uniqueAccountIds = [
...new Set((accounts ?? []).map((a: any) => a.account_id)),
] as string[];
const jobResults: Record<string, unknown> = {};
for (const accountId of uniqueAccountIds) {
try {
const result = await notificationService.runScheduledJobs(accountId);
jobResults[accountId] = result;
} catch (e) {
logger.error(
{ accountId, error: e, context: 'cron-member-jobs' },
'Failed to run jobs for account',
);
jobResults[accountId] = {
error: e instanceof Error ? e.message : 'Unknown error',
};
}
}
const summary = {
timestamp: new Date().toISOString(),
queue: queueResult,
accounts_processed: uniqueAccountIds.length,
jobs: jobResults,
};
logger.info(
{ context: 'cron-member-jobs', ...summary },
'Member cron jobs completed',
);
return NextResponse.json(summary);
} catch (err) {
logger.error(
{ error: err, context: 'cron-member-jobs' },
'Cron job failed',
);
return NextResponse.json(
{ error: 'Internal server error' },
{ status: 500 },
);
}
}