From 823d696d86ec2d39ca7fa30e865c946d50a3daaf Mon Sep 17 00:00:00 2001 From: eneller Date: Wed, 18 Mar 2026 09:18:27 +0100 Subject: [PATCH] feat: api send --- server/src/index.ts | 2 ++ server/src/model/user.ts | 7 +++++- server/src/routes/send.ts | 42 +++++++++++++++++++++++++++++++ server/src/routes/transactions.ts | 3 ++- 4 files changed, 52 insertions(+), 2 deletions(-) create mode 100644 server/src/routes/send.ts diff --git a/server/src/index.ts b/server/src/index.ts index 12c5ed9..3cf53cc 100644 --- a/server/src/index.ts +++ b/server/src/index.ts @@ -3,6 +3,7 @@ import cors from "cors"; import cookieParser from "cookie-parser"; import transactionsRouter from './routes/transactions'; import authRouter from './routes/auth'; +import sendRouter from './routes/send'; import dotenv from 'dotenv'; dotenv.config({quiet: true}); import { db, testConnection } from "./util/db"; @@ -20,6 +21,7 @@ app.get("/api/health", (req: Request, res: Response) => { app.use('/api/auth', authRouter); app.use('/api/transactions', transactionsRouter); +app.use('/api/send', sendRouter); const PORT: number = parseInt(process.env.FM_PORT as string) || 3000; diff --git a/server/src/model/user.ts b/server/src/model/user.ts index 8bc839a..d6fb2f2 100644 --- a/server/src/model/user.ts +++ b/server/src/model/user.ts @@ -1,5 +1,10 @@ -import { Table, Column, Model, CreatedAt, DataType} from 'sequelize-typescript'; +import { Table, Column, Model, CreatedAt, DataType, Scopes} from 'sequelize-typescript'; +@Scopes(() => ({ + withoutPassword: { + attributes: { exclude: ['password'] } + } +})) @Table export default class User extends Model{ diff --git a/server/src/routes/send.ts b/server/src/routes/send.ts new file mode 100644 index 0000000..8dc283d --- /dev/null +++ b/server/src/routes/send.ts @@ -0,0 +1,42 @@ +import express from 'express'; +import { logger } from '../util/logging'; +import { requireAuth } from '../util/auth'; +import User from '../model/user'; +import { db } from '../util/db'; +import Transaction from '../model/transaction'; + + +const router = express.Router(); + +router.get('/:recipientID', requireAuth, async (req, res) => { + try { + let sender = res.locals.user as User; + let amount = Number(req.query.amount); + let recipient = await User.findOne({where: {userID: req.params.recipientID}}) + if ( amount <= 0) { + return res.status(400).json({ error: 'Invalid transfer amount' }); + } + if (!recipient) { + return res.status(404).json({ error: 'Recipient not found' }); + } + if (sender.balance < amount){ + res.status(400).json({error: 'Insufficient balance'}) + } + + await db.transaction(async (t) =>{ + await sender.decrement({balance: amount}); + await recipient.increment({balance: amount}); + await Transaction.create({ + amount: amount, + senderID: sender.userID, + receiverID: recipient.userID + }); + }) + res.status(200).json({balance: sender.balance, amount: amount}); + } catch (err) { + logger.error('Failed to commit transaction:', err); + res.status(500).json({ error: 'Failed to commit transaction' }); + } +}); + +export default router; diff --git a/server/src/routes/transactions.ts b/server/src/routes/transactions.ts index 3e3c239..0960f87 100644 --- a/server/src/routes/transactions.ts +++ b/server/src/routes/transactions.ts @@ -1,10 +1,11 @@ import express from 'express'; import { logger } from '../util/logging'; import Transaction from '../model/transaction'; +import { requireAuth } from '../util/auth'; const router = express.Router(); -router.get('/', async (req, res) => { +router.get('/', requireAuth, async (req, res) => { try { const transactions = await Transaction.findAll({ limit: 10 }); res.json(transactions);