mirror of
https://github.com/acedanger/finance.git
synced 2025-12-05 22:50:12 -08:00
- Remove in-memory store and related tests - Add Decimal to number conversion in API responses - Update integration tests to handle Prisma Decimal type - Fix test configuration to only run db-integration tests
90 lines
2.8 KiB
TypeScript
90 lines
2.8 KiB
TypeScript
/**
|
|
* TODO: Security Improvements
|
|
* - Add input validation and sanitization
|
|
* - Implement rate limiting for API endpoints
|
|
* - Add request authentication
|
|
* - Implement CSRF protection
|
|
* - Add request logging and monitoring
|
|
* - Implement secure session management
|
|
* - Add API versioning
|
|
* - Set up proper CORS configuration
|
|
*/
|
|
|
|
import type { APIRoute } from 'astro';
|
|
import { accountService, transactionService } from '../../../data/db.service';
|
|
import type { Transaction } from '../../../types';
|
|
|
|
/**
|
|
* TODO: API Improvements
|
|
* - Add request rate limiting
|
|
* - Implement proper API authentication
|
|
* - Add input sanitization
|
|
* - Implement request validation middleware
|
|
* - Add API versioning
|
|
* - Consider implementing GraphQL for more flexible queries
|
|
* - Add proper logging and monitoring
|
|
*/
|
|
|
|
export const POST: APIRoute = async ({ request }) => {
|
|
try {
|
|
const transaction = (await request.json()) as Omit<Transaction, 'id'>;
|
|
|
|
// Validate required fields
|
|
if (
|
|
!transaction.accountId ||
|
|
!transaction.date ||
|
|
!transaction.description ||
|
|
transaction.amount === undefined
|
|
) {
|
|
return new Response(JSON.stringify({ error: 'Missing required fields' }), {
|
|
status: 400,
|
|
headers: { 'Content-Type': 'application/json' },
|
|
});
|
|
}
|
|
|
|
// Validate account exists
|
|
const account = await accountService.getById(transaction.accountId);
|
|
if (!account) {
|
|
return new Response(JSON.stringify({ error: 'Account not found' }), {
|
|
status: 404,
|
|
headers: { 'Content-Type': 'application/json' },
|
|
});
|
|
}
|
|
|
|
// Convert string date to Date object if needed
|
|
const transactionDate =
|
|
typeof transaction.date === 'string' ? new Date(transaction.date) : transaction.date;
|
|
|
|
// Create new transaction with database service
|
|
// The database service will also update the account balance
|
|
const newTransaction = await transactionService.create({
|
|
accountId: transaction.accountId,
|
|
date: transactionDate,
|
|
description: transaction.description,
|
|
amount: transaction.amount,
|
|
category: transaction.category,
|
|
status: transaction.status as any,
|
|
type: transaction.type as any,
|
|
notes: transaction.notes,
|
|
tags: transaction.tags,
|
|
});
|
|
|
|
// Convert Decimal to number for response
|
|
const response = {
|
|
...newTransaction,
|
|
amount: Number(newTransaction.amount),
|
|
};
|
|
|
|
return new Response(JSON.stringify(response), {
|
|
status: 201,
|
|
headers: { 'Content-Type': 'application/json' },
|
|
});
|
|
} catch (error) {
|
|
console.error('Error creating transaction:', error);
|
|
return new Response(JSON.stringify({ error: 'Failed to create transaction' }), {
|
|
status: 500,
|
|
headers: { 'Content-Type': 'application/json' },
|
|
});
|
|
}
|
|
};
|