diff --git a/.astro/content-assets.mjs b/.astro/content-assets.mjs deleted file mode 100644 index 2b8b823..0000000 --- a/.astro/content-assets.mjs +++ /dev/null @@ -1 +0,0 @@ -export default new Map(); \ No newline at end of file diff --git a/.astro/content-modules.mjs b/.astro/content-modules.mjs deleted file mode 100644 index 2b8b823..0000000 --- a/.astro/content-modules.mjs +++ /dev/null @@ -1 +0,0 @@ -export default new Map(); \ No newline at end of file diff --git a/.astro/data-store.json b/.astro/data-store.json deleted file mode 100644 index daa2b96..0000000 --- a/.astro/data-store.json +++ /dev/null @@ -1 +0,0 @@ -[["Map",1,2],"meta::meta",["Map",3,4,5,6],"astro-version","5.7.5","astro-config-digest","{\"root\":{},\"srcDir\":{},\"publicDir\":{},\"outDir\":{},\"cacheDir\":{},\"compressHTML\":true,\"base\":\"/\",\"trailingSlash\":\"ignore\",\"output\":\"static\",\"scopedStyleStrategy\":\"attribute\",\"build\":{\"format\":\"directory\",\"client\":{},\"server\":{},\"assets\":\"_astro\",\"serverEntry\":\"entry.mjs\",\"redirects\":true,\"inlineStylesheets\":\"auto\",\"concurrency\":1},\"server\":{\"open\":false,\"host\":false,\"port\":4321,\"streaming\":true,\"allowedHosts\":[]},\"redirects\":{},\"image\":{\"endpoint\":{\"route\":\"/_image\"},\"service\":{\"entrypoint\":\"astro/assets/services/sharp\",\"config\":{}},\"domains\":[],\"remotePatterns\":[]},\"devToolbar\":{\"enabled\":true},\"markdown\":{\"syntaxHighlight\":{\"type\":\"shiki\",\"excludeLangs\":[\"math\"]},\"shikiConfig\":{\"langs\":[],\"langAlias\":{},\"theme\":\"github-dark\",\"themes\":{},\"wrap\":false,\"transformers\":[]},\"remarkPlugins\":[],\"rehypePlugins\":[],\"remarkRehype\":{},\"gfm\":true,\"smartypants\":true},\"security\":{\"checkOrigin\":true},\"env\":{\"schema\":{},\"validateSecrets\":false},\"experimental\":{\"clientPrerender\":false,\"contentIntellisense\":false,\"responsiveImages\":false,\"headingIdCompat\":false,\"preserveScriptOrder\":false},\"legacy\":{\"collections\":false}}"] \ No newline at end of file diff --git a/.astro/settings.json b/.astro/settings.json deleted file mode 100644 index 5b2b775..0000000 --- a/.astro/settings.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "_variables": { - "lastUpdateCheck": 1745454555490 - } -} \ No newline at end of file diff --git a/.astro/types.d.ts b/.astro/types.d.ts deleted file mode 100644 index f964fe0..0000000 --- a/.astro/types.d.ts +++ /dev/null @@ -1 +0,0 @@ -/// diff --git a/.gitignore b/.gitignore index 28b9a40..0966b99 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ # build output dist/ .output/ +.astro/ # dependencies node_modules/ diff --git a/astro.config.mjs b/astro.config.mjs index e762ba5..245b4b2 100644 --- a/astro.config.mjs +++ b/astro.config.mjs @@ -1,5 +1,7 @@ // @ts-check -import { defineConfig } from 'astro/config'; +import { defineConfig } from "astro/config"; // https://astro.build/config -export default defineConfig({}); +export default defineConfig({ + output: "server", +}); diff --git a/src/pages/api/accounts/[id]/index.ts b/src/pages/api/accounts/[id]/index.ts index e69de29..2479188 100644 --- a/src/pages/api/accounts/[id]/index.ts +++ b/src/pages/api/accounts/[id]/index.ts @@ -0,0 +1,22 @@ +import type { APIRoute } from "astro"; +import { accounts } from "../../../../data/store"; + +export const GET: APIRoute = async ({ params }) => { + const account = accounts.find((a) => a.id === params.id); + + if (!account) { + return new Response(JSON.stringify({ error: "Account not found" }), { + status: 404, + headers: { + "Content-Type": "application/json", + }, + }); + } + + return new Response(JSON.stringify(account), { + status: 200, + headers: { + "Content-Type": "application/json", + }, + }); +}; diff --git a/src/pages/api/accounts/[id]/transactions/index.ts b/src/pages/api/accounts/[id]/transactions/index.ts index e69de29..bb8234f 100644 --- a/src/pages/api/accounts/[id]/transactions/index.ts +++ b/src/pages/api/accounts/[id]/transactions/index.ts @@ -0,0 +1,15 @@ +import type { APIRoute } from "astro"; +import { transactions } from "../../../../../data/store"; + +export const GET: APIRoute = async ({ params }) => { + const accountTransactions = transactions.filter( + (t) => t.accountId === params.id + ); + + return new Response(JSON.stringify(accountTransactions), { + status: 200, + headers: { + "Content-Type": "application/json", + }, + }); +}; diff --git a/src/pages/api/transactions/[id]/index.ts b/src/pages/api/transactions/[id]/index.ts index e69de29..8b778e3 100644 --- a/src/pages/api/transactions/[id]/index.ts +++ b/src/pages/api/transactions/[id]/index.ts @@ -0,0 +1,82 @@ +import type { APIRoute } from "astro"; +import { transactions, accounts } from "../../../../data/store"; +import type { Transaction } from "../../../../types"; + +export const PUT: APIRoute = async ({ request, params }) => { + try { + const updates = (await request.json()) as Partial; + const transactionIndex = transactions.findIndex((t) => t.id === params.id); + + if (transactionIndex === -1) { + return new Response(JSON.stringify({ error: "Transaction not found" }), { + status: 404, + headers: { "Content-Type": "application/json" }, + }); + } + + const oldTransaction = transactions[transactionIndex]; + const account = accounts.find((a) => a.id === oldTransaction.accountId); + + if (!account) { + return new Response(JSON.stringify({ error: "Account not found" }), { + status: 404, + headers: { "Content-Type": "application/json" }, + }); + } + + // Revert old transaction amount from account balance + account.balance -= oldTransaction.amount; + + // Update transaction with new data + const updatedTransaction: Transaction = { + ...oldTransaction, + ...updates, + id: params.id, // Ensure ID doesn't change + }; + + // Add new amount to account balance + account.balance += updatedTransaction.amount; + + // Update transaction in array + transactions[transactionIndex] = updatedTransaction; + + return new Response(JSON.stringify(updatedTransaction), { + status: 200, + headers: { "Content-Type": "application/json" }, + }); + } catch (error) { + return new Response(JSON.stringify({ error: "Invalid request body" }), { + status: 400, + headers: { "Content-Type": "application/json" }, + }); + } +}; + +export const DELETE: APIRoute = async ({ params }) => { + const transactionIndex = transactions.findIndex((t) => t.id === params.id); + + if (transactionIndex === -1) { + return new Response(JSON.stringify({ error: "Transaction not found" }), { + status: 404, + headers: { "Content-Type": "application/json" }, + }); + } + + const transaction = transactions[transactionIndex]; + const account = accounts.find((a) => a.id === transaction.accountId); + + if (!account) { + return new Response(JSON.stringify({ error: "Account not found" }), { + status: 404, + headers: { "Content-Type": "application/json" }, + }); + } + + // Update account balance + account.balance -= transaction.amount; + + // Remove transaction from array + transactions.splice(transactionIndex, 1); + + return new Response(null, { status: 204 }); +}; diff --git a/src/pages/api/transactions/index.ts b/src/pages/api/transactions/index.ts index e69de29..91a2b5b 100644 --- a/src/pages/api/transactions/index.ts +++ b/src/pages/api/transactions/index.ts @@ -0,0 +1,56 @@ +import type { APIRoute } from "astro"; +import { transactions, accounts } from "../../../data/store"; +import type { Transaction } from "../../../types"; + +export const POST: APIRoute = async ({ request }) => { + try { + const transaction = (await request.json()) as Omit; + + // 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 = accounts.find((a) => a.id === transaction.accountId); + if (!account) { + return new Response(JSON.stringify({ error: "Account not found" }), { + status: 404, + headers: { "Content-Type": "application/json" }, + }); + } + + // Create new transaction with generated ID + const newTransaction: Transaction = { + ...transaction, + id: (transactions.length + 1).toString(), // Simple ID generation for demo + }; + + // Update account balance + account.balance += transaction.amount; + + // Add to transactions array + transactions.push(newTransaction); + + return new Response(JSON.stringify(newTransaction), { + status: 201, + headers: { "Content-Type": "application/json" }, + }); + } catch (error) { + return new Response(JSON.stringify({ error: "Invalid request body" }), { + status: 400, + headers: { "Content-Type": "application/json" }, + }); + } +};