import { NextResponse } from "next/server" import { and, eq, lte } from "drizzle-orm" import { db } from "@/lib/db" import { rent_payments, expenses } from "@/lib/db/schema" import { isAuthorizedCron } from "@/lib/cron-auth" // Scheduled task: runs daily at 8am UTC (scheduled via DigitalOcean Functions — see DIGITALOCEAN.md) export async function GET(request: Request) { if (!isAuthorizedCron(request)) { return NextResponse.json({ error: "Unauthorized" }, { status: 401 }) } // Find overdue payments older than grace period (default 5 days) that don't yet have a late fee const graceDays = 5 const cutoff = new Date() cutoff.setDate(cutoff.getDate() - graceDays) const cutoffDate = cutoff.toISOString().slice(0, 10) const overduePayments = await db .select({ id: rent_payments.id, user_id: rent_payments.user_id, tenant_id: rent_payments.tenant_id, property_id: rent_payments.property_id, unit_id: rent_payments.unit_id, amount: rent_payments.amount, due_date: rent_payments.due_date, }) .from(rent_payments) .where( and( eq(rent_payments.status, "overdue"), lte(rent_payments.due_date, cutoffDate), eq(rent_payments.late_fee_applied, false) ) ) if (!overduePayments.length) { return NextResponse.json({ processed: 0 }) } let processed = 0 for (const payment of overduePayments) { const lateFeeAmount = Math.round(Number(payment.amount) * 0.05 * 100) / 100 // 5% late fee // Insert late fee as a separate expense await db.insert(expenses).values({ user_id: payment.user_id, property_id: payment.property_id, unit_id: payment.unit_id ?? null, category: "other", description: `Late fee — rent due ${payment.due_date}`, amount: lateFeeAmount, expense_date: new Date().toISOString().slice(0, 10), vendor: "Auto-generated", }) // Mark late fee applied await db .update(rent_payments) .set({ late_fee_applied: true }) .where(eq(rent_payments.id, payment.id)) processed++ } return NextResponse.json({ processed, message: `Applied late fees to ${processed} overdue payment(s).` }) }