2026-02-14 02:20:19 +00:00

75 lines
2.2 KiB
TypeScript

// routes/api/create/income.ts
import { define } from "../../../utils.ts";
import { createIncome } from "../../../services/financhalServices.ts";
import { SessionCookie } from "../../auth/callback.ts";
import {
handleApiError,
validateNumber,
validateRequiredString,
withTimeout,
} from "../../../utils/errorHandler.ts";
const REQUEST_TIMEOUT = 30000; // 30 seconds
export const handler = define.handlers({
async POST(ctx) {
try {
const stateData: SessionCookie = ctx.state.data;
// Ensure user is authenticated
if (!stateData.user_id) {
return new Response(
JSON.stringify({ error: "Unauthorized - user_id not found" }),
{ status: 401, headers: { "Content-Type": "application/json" } },
);
}
// Parse form data with timeout
const formData = await withTimeout(
ctx.req.formData(),
REQUEST_TIMEOUT,
"Request timed out while reading form data",
);
const source = formData.get("source")?.toString();
const amountRaw = formData.get("amount")?.toString();
const frequency = formData.get("frequency");
const received_date = formData.get("received_date");
const encrypted_data = formData.get("encrypted_data");
// Validate amount - must be a positive number
const amount = amountRaw
? validateNumber(amountRaw, "amount", { min: 0.01, allowZero: false })
: null;
// Validate source if provided
if (source) {
validateRequiredString(source, "source");
}
// Create income with timeout
await withTimeout(
createIncome(
stateData.user_id,
source || null,
amount,
frequency as string,
received_date
? Date.parse(received_date as string + "T00:00:00") || Date.now()
: Date.now(),
encrypted_data ? encrypted_data.toString() : "",
),
REQUEST_TIMEOUT,
"Request timed out while creating income record",
);
return new Response(
JSON.stringify({ success: true }),
{ status: 200, headers: { "Content-Type": "application/json" } },
);
} catch (e) {
return handleApiError(e);
}
},
});