fix: add billing types and fix Supabase type casting for admin routes
- Add src/types/billing.ts with Payment, Coupon, CreditTransaction, Invoice types - Cast all Supabase query results through 'unknown' for untyped billing tables - All routes now build cleanly with strict TypeScript checking Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
@@ -3,6 +3,7 @@ import { getSupabaseAdmin } from "@/lib/admin";
|
||||
import { requireAdmin } from "@/lib/apiAuth";
|
||||
import { sendEmail } from "@/lib/email";
|
||||
import { invoiceEmail } from "@/lib/email-templates";
|
||||
import type { Invoice } from "@/types/billing";
|
||||
|
||||
export async function GET(request: Request) {
|
||||
const authResult = await requireAdmin(request);
|
||||
@@ -29,11 +30,13 @@ export async function GET(request: Request) {
|
||||
if (orgId) query = query.eq("organization_id", orgId);
|
||||
if (status) query = query.eq("status", status);
|
||||
|
||||
const { data: invoices, count, error } = await query;
|
||||
const { data, count, error } = await query;
|
||||
if (error) throw error;
|
||||
|
||||
const invoices = (data || []) as unknown as Invoice[];
|
||||
|
||||
return NextResponse.json({
|
||||
invoices: invoices || [],
|
||||
invoices,
|
||||
pagination: { page, limit, total: count || 0, pages: Math.ceil((count || 0) / limit) },
|
||||
});
|
||||
} catch (error) {
|
||||
@@ -68,7 +71,7 @@ export async function POST(request: Request) {
|
||||
.like("invoice_number", `${prefix}%`);
|
||||
const seq = String((count || 0) + 1).padStart(4, "0");
|
||||
|
||||
const { data: invoice, error } = await supabase
|
||||
const { data, error } = await supabase
|
||||
.from("invoices")
|
||||
.insert({
|
||||
invoice_number: `${prefix}-${seq}`,
|
||||
@@ -85,6 +88,7 @@ export async function POST(request: Request) {
|
||||
.single();
|
||||
|
||||
if (error) throw error;
|
||||
const invoice = data as unknown as Invoice;
|
||||
|
||||
return NextResponse.json({ invoice });
|
||||
} catch (error) {
|
||||
@@ -109,17 +113,19 @@ export async function PATCH(request: Request) {
|
||||
|
||||
// Send invoice via email
|
||||
if (action === "send") {
|
||||
const { data: invoice } = await supabase
|
||||
const { data } = await supabase
|
||||
.from("invoices")
|
||||
.select("*, organization:organizations(id, name, billing_email)")
|
||||
.eq("id", id)
|
||||
.single();
|
||||
|
||||
const invoice = data as unknown as Invoice | null;
|
||||
|
||||
if (!invoice) {
|
||||
return NextResponse.json({ error: "Invoice not found" }, { status: 404 });
|
||||
}
|
||||
|
||||
const org = invoice.organization as { id: string; name: string; billing_email?: string } | null;
|
||||
const org = invoice.organization;
|
||||
const recipientEmail = org?.billing_email;
|
||||
|
||||
if (!recipientEmail) {
|
||||
@@ -131,12 +137,12 @@ export async function PATCH(request: Request) {
|
||||
|
||||
const appUrl = process.env.NEXT_PUBLIC_APP_URL || "http://localhost:3000";
|
||||
const template = invoiceEmail({
|
||||
organizationName: org.name,
|
||||
organizationName: org?.name || "Unknown",
|
||||
invoiceNumber: invoice.invoice_number,
|
||||
amount: invoice.amount,
|
||||
currency: invoice.currency,
|
||||
dueDate: invoice.due_date,
|
||||
items: (invoice.items as Array<{ description: string; amount: number }>) || [],
|
||||
items: (invoice.items) || [],
|
||||
dashboardUrl: `${appUrl}/dashboard/settings`,
|
||||
});
|
||||
|
||||
@@ -161,7 +167,7 @@ export async function PATCH(request: Request) {
|
||||
|
||||
// Mark as paid
|
||||
if (action === "mark_paid") {
|
||||
const { data: invoice, error } = await supabase
|
||||
const { data, error } = await supabase
|
||||
.from("invoices")
|
||||
.update({ status: "paid", paid_at: new Date().toISOString(), updated_at: new Date().toISOString() })
|
||||
.eq("id", id)
|
||||
@@ -169,6 +175,7 @@ export async function PATCH(request: Request) {
|
||||
.single();
|
||||
|
||||
if (error) throw error;
|
||||
const invoice = data as unknown as Invoice;
|
||||
return NextResponse.json({ invoice });
|
||||
}
|
||||
|
||||
@@ -179,7 +186,7 @@ export async function PATCH(request: Request) {
|
||||
if (key in updates) safeUpdates[key] = updates[key];
|
||||
}
|
||||
|
||||
const { data: invoice, error } = await supabase
|
||||
const { data, error } = await supabase
|
||||
.from("invoices")
|
||||
.update(safeUpdates)
|
||||
.eq("id", id)
|
||||
@@ -187,6 +194,7 @@ export async function PATCH(request: Request) {
|
||||
.single();
|
||||
|
||||
if (error) throw error;
|
||||
const invoice = data as unknown as Invoice;
|
||||
|
||||
return NextResponse.json({ invoice });
|
||||
} catch (error) {
|
||||
|
||||
Reference in New Issue
Block a user