A TypeScript-based backend API for a financial technology application that provides user authentication, transaction management, and advanced financial data operations.
- User Authentication: Secure registration, login, and JWT-based authentication
- Transaction Management: Create, read, update, and delete financial transactions
- Advanced Filtering: Search transactions by payee, category, date range, and more
- Pagination: Efficient data retrieval with pagination support
- Security: Password hashing, JWT tokens, CORS protection, and Helmet security
- Database: SQLite with Knex.js for migrations and query building
- Health Monitoring: Built-in health check endpoints
- Graceful Shutdown: Proper cleanup and database connection management
- Runtime: Node.js with TypeScript
- Framework: Express.js
- Database: SQLite with Knex.js
- Authentication: JWT + bcrypt
- Security: Helmet, CORS
- Development: ts-node, ts-node-dev
- File Processing: Multer, CSV parser
-
Clone the repository
git clone <repository-url> cd TechFin
-
Install dependencies
npm install
-
Set up environment variables Create a
.envfile in the root directory:NODE_ENV=development PORT=3000 JWT_SECRET=your-secret-key JWT_REFRESH_SECRET=your-refresh-secret-key ALLOWED_ORIGINS=http://localhost:3000,http://localhost:3001
-
Run database migrations
npm run migrate
npm run devnpm run dev:watchnpm run build
npm start# Run migrations
npm run migrate
# Rollback migrations
npm run migrate:rollback
# Create new migration
npm run migrate:make <migration-name>http://localhost:3000
POST /auth/register
Content-Type: application/json
{
"email": "user@example.com",
"password": "securepassword"
}cURL Example:
curl -X POST http://localhost:3000/auth/register \
-H "Content-Type: application/json" \
-d '{
"email": "user@example.com",
"password": "securepassword"
}'POST /auth/login
Content-Type: application/json
{
"email": "user@example.com",
"password": "securepassword"
}cURL Example:
curl -X POST http://localhost:3000/auth/login \
-H "Content-Type: application/json" \
-d '{
"email": "user@example.com",
"password": "securepassword"
}'Response:
{
"accessToken": "jwt-access-token",
"refreshToken": "jwt-refresh-token"
}POST /auth/refresh
Content-Type: application/json
{
"userId": 1,
"refreshToken": "jwt-refresh-token"
}cURL Example:
curl -X POST http://localhost:3000/auth/refresh \
-H "Content-Type: application/json" \
-d '{
"userId": 1,
"refreshToken": "jwt-refresh-token"
}'π Note: All transaction endpoints require authentication. Include the JWT token in the Authorization header:
Authorization: Bearer <access-token>How to get access token:
- First register a user using
/auth/register- Then login using
/auth/loginto get the access token- Replace
YOUR_ACCESS_TOKENin the curl examples below with your actual token
POST /api/create-transaction
Content-Type: application/json
{
"payee": "Amazon",
"amount": 49.99,
"category": "shopping",
"transaction_date": "2025-01-15T10:30:00Z",
"note": "Monthly subscription"
}cURL Example:
curl -X POST http://localhost:3000/api/create-transaction \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-d '{
"payee": "Amazon",
"amount": 49.99,
"category": "shopping",
"transaction_date": "2025-01-15T10:30:00Z",
"note": "Monthly subscription"
}'GET /api/transactions?page=1&pageSize=10&search=amazon&category=shopping&start=2025-01-01&end=2025-01-31Query Parameters:
page(optional): Page number (default: 1)pageSize(optional): Items per page (default: 10)search(optional): Search by payee namecategory(optional): Filter by categorystart(optional): Start date (YYYY-MM-DD)end(optional): End date (YYYY-MM-DD)
cURL Examples:
# Get all transactions with pagination
curl -X GET "http://localhost:3000/api/transactions?page=1&pageSize=10" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
# Search transactions by payee
curl -X GET "http://localhost:3000/api/transactions?search=amazon&page=1&pageSize=10" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
# Filter by category and date range
curl -X GET "http://localhost:3000/api/transactions?category=shopping&start=2025-01-01&end=2025-01-31" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"GET /api/transactions/by-date?year=2025&month=1&day=15Query Parameters:
year(required): Yearmonth(optional): Month (1-12)day(optional): Day (1-31)
cURL Examples:
# Get transactions for a specific day
curl -X GET "http://localhost:3000/api/transactions/by-date?year=2025&month=1&day=15" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
# Get transactions for a specific month
curl -X GET "http://localhost:3000/api/transactions/by-date?year=2025&month=1" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
# Get transactions for a specific year
curl -X GET "http://localhost:3000/api/transactions/by-date?year=2025" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"GET /api/transactions/last?days=30cURL Example:
# Get transactions from last 30 days
curl -X GET "http://localhost:3000/api/transactions/last?days=30" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
# Get transactions from last 7 days
curl -X GET "http://localhost:3000/api/transactions/last?days=7" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"PUT /api/:id
Content-Type: application/json
{
"payee": "Updated Payee",
"amount": 59.99,
"category": "updated-category",
"transaction_date": "2025-01-16T10:30:00Z",
"note": "Updated note"
}cURL Example:
curl -X PUT http://localhost:3000/api/123 \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-d '{
"payee": "Updated Payee",
"amount": 59.99,
"category": "updated-category",
"transaction_date": "2025-01-16T10:30:00Z",
"note": "Updated note"
}'DELETE /api/:idcURL Example:
curl -X DELETE http://localhost:3000/api/123 \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"GET /healthcURL Example:
curl -X GET http://localhost:3000/healthGET /health/detailedcURL Example:
curl -X GET http://localhost:3000/health/detailedHere's a complete example workflow using curl commands:
# 1. Register a new user
curl -X POST http://localhost:3000/auth/register \
-H "Content-Type: application/json" \
-d '{"email": "john@example.com", "password": "securepassword123"}'
# 2. Login to get access token
curl -X POST http://localhost:3000/auth/login \
-H "Content-Type: application/json" \
-d '{"email": "john@example.com", "password": "securepassword123"}'
# Save the accessToken from the response and use it in subsequent requests
# 3. Create a transaction
curl -X POST http://localhost:3000/api/create-transaction \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-d '{
"payee": "Starbucks",
"amount": 15.50,
"category": "food",
"transaction_date": "2025-01-15T08:30:00Z",
"note": "Morning coffee"
}'
# 4. Get all transactions
curl -X GET "http://localhost:3000/api/transactions?page=1&pageSize=10" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
# 5. Search for specific transactions
curl -X GET "http://localhost:3000/api/transactions?search=starbucks" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"TechFin/
βββ src/
β βββ database/
β β βββ connection.ts # Database connection setup
β β βββ migrations/ # Database migration files
β β βββ sqlLite.ts # SQLite configuration
β βββ middleware/
β β βββ authMiddleware.ts # JWT authentication middleware
β β βββ errorHandler.ts # Global error handling
β β βββ notFoundHandler.ts # 404 error handler
β βββ repo/
β β βββ baseRepository.ts # Base repository pattern
β β βββ tokenRepo.ts # Token repository
β β βββ transactionRepo.ts # Transaction repository
β β βββ userRepo.ts # User repository
β βββ routes/
β β βββ api.ts # Transaction API routes
β β βββ auth.ts # Authentication routes
β β βββ health.ts # Health check routes
β βββ services/
β β βββ authService.ts # Authentication business logic
β β βββ transactionService.ts # Transaction business logic
β βββ types/
β β βββ express.d.ts # Express type extensions
β β βββ index.ts # Type definitions
β βββ utils/
β β βββ hashPassword.ts # Password hashing utilities
β β βββ jwt.ts # JWT utilities
β β βββ logger.ts # Logging utilities
β β βββ refreshToken.ts # Refresh token utilities
β β βββ validation.ts # Input validation
β βββ index.ts # Application entry point
βββ knexfile.ts # Knex configuration
βββ package.json # Dependencies and scripts
βββ tsconfig.json # TypeScript configuration
npm run migrate:make create_new_tableThe application uses the following main tables:
users- User accounts with authenticationuser_tokens- JWT refresh tokenstransactions- Financial transaction records
- Password hashing with bcrypt
- JWT access and refresh tokens
- CORS protection
- Helmet security headers
- Input validation and sanitization
- Graceful error handling
-
Build the application
npm run build
-
Set production environment variables
NODE_ENV=production PORT=3000 JWT_SECRET=your-production-secret JWT_REFRESH_SECRET=your-production-refresh-secret ALLOWED_ORIGINS=https://yourdomain.com
-
Run migrations
npm run migrate
-
Start the application
npm start
{
"message": "Success message",
"data": { /* response data */ },
"timestamp": "2025-01-15T10:30:00Z"
}{
"message": "Error message",
"error": "Error details",
"timestamp": "2025-01-15T10:30:00Z"
}- Fork the repository
- Create a feature branch:
git checkout -b feature/new-feature - Commit your changes:
git commit -am 'Add new feature' - Push to the branch:
git push origin feature/new-feature - Submit a pull request
This project is licensed under the ISC License.
-
Database Connection Error
- Ensure SQLite database file permissions are correct
- Check if migrations have been run
-
Authentication Errors
- Verify JWT_SECRET is set in environment variables
- Check if access token is properly included in requests
-
Port Already in Use
- Change the PORT in your .env file
- Kill processes using the port:
lsof -ti:3000 | xargs kill
The application uses Morgan for request logging in development mode. Check console output for detailed error messages.