- Overview
- Input Format
- Requirements
- API Contract
- Quick Start
- Environment Variables
- Development
- Project Structure
- Architecture
- Testing
- API Examples
- Docker
- Deployment
- Documentation
- Technologies
- Troubleshooting
Build a small fullβstack app that lets users upload a bank statement CSV, view insights, and inspect transaction issues. The application follows Domain-Driven Design with Clean Architecture principles.
Tech Stack:
- Backend: Go 1.23 with Fiber framework and SQLite
- Frontend: Next.js with React
- Database: SQLite (in-memory capable)
- Architecture: Domain-Driven Design (DDD)
# Example CSV payload with decimal amounts
1624507883,JOHN DOE,DEBIT,250000.50,SUCCESS,restaurant
1624608050,E-COMMERCE A,DEBIT,150000,FAILED,clothes
1624512883,COMPANY A,CREDIT,12000000.99,SUCCESS,salary
1624615065,E-COMMERCE B,DEBIT,150000.25,PENDING,clothes
# Format
timestamp,name,type,amount,status,descriptionNotes:
timestampis a Unix epoch (seconds).typeis one ofCREDIT|DEBIT.statusis one ofSUCCESS|FAILED|PENDING.amountcan be integer (250000) or decimal (250000.50) - stored as cents internally
Build REST APIs with inβmemory storage. Clean architecture is a plus (handler β service β repository).
β Implemented:
- Domain-Driven Design architecture
- SQLite database with automatic schema migration
- Comprehensive input validation
- Filtering, sorting, and pagination
- CORS support
- Error handling
Provide a simple UI to upload CSV, show computed end balance, and list nonβsuccessful transactions with visual status.
β Implemented:
- Upload interface with drag-and-drop
- Dashboard with balance display (from
/api/balance) - Transaction list with filtering, sorting, pagination (using
/api/transactions) - Issues count from
/api/issuesendpoint - Status indicators (SUCCESS/FAILED/PENDING)
- Empty state UI for tables
- Real-time API integration with error handling via notifications
- Skeleton/loader states driven by API responses
- Non-blocking file upload with concurrent processing
- NEW: Dropzone loading spinner with opacity overlay during upload
- NEW: Three-state sorting (ASC β DESC β RESET)
- NEW: Debounced search (300ms) for better performance
- NEW: Custom Select dropdown component for filters
Dockerfile, request validation & error handling, CI (GitHub Actions), clean structure, and tests.
β Implemented:
- β Dockerfile (optimized multi-stage)
- β Input validation (file and field validators)
- β Error handling (comprehensive)
- β Clean structure (DDD)
- β Unit tests and coverage
| Method | Endpoint | Description |
|---|---|---|
| POST | /api/upload |
Accepts CSV file upload, parses it, stores transactions in memory |
| GET | /api/balance |
Returns total balance = credits β debits (from SUCCESS transactions only) |
| GET | /api/transactions |
Returns all transactions with filtering, sorting, and pagination |
| GET | /api/issues |
Returns nonβsuccessful transactions (FAILED + PENDING) with filtering/sorting |
| GET | /api/health |
Health check endpoint |
| DELETE | /api/clear |
Clear all transaction data |
API Features:
- β
Decimal Amount Support - CSV accepts decimal values (e.g.,
1234.56) stored as cents - β Duplicate Detection - Automatically detects and skips duplicate transactions
- β Filtering by status, type, amount, date range
- β Searching by name/description
- β Sorting by any field (ASC/DESC, no default sort if not specified)
- β Pagination with navigation links
- β Comprehensive error responses
Response format matches frontend contract with pagination metadata and filters.
- Go 1.23.10+
- Node.js 20+
- Docker (optional)
- make (optional)
cd backend
# Install tools
make install
# Copy environment configuration
cp .env.example .env
# Run server
make runServer runs on http://localhost:9000
cd frontend
# Install dependencies
npm install
# Run development server
npm run devFrontend runs on http://localhost:3000
Backend (backend/.env)
# No configuration needed for local development
# Database defaults to in-memory SQLiteFrontend (.env.local or frontend/.env.local)
# Local development (default if not set)
NEXT_PUBLIC_API_URL=http://localhost:9000/apiFrontend Environment Variable:
NEXT_PUBLIC_API_URL=https://flip-fullstack-test-backend-xxx.run.app/apiHow it's configured:
-
GitHub Secrets - Store sensitive values:
gh secret set NEXT_PUBLIC_API_URL -b "https://your-backend-url.run.app/api"
-
Docker Build - Injected during image build:
ARG NEXT_PUBLIC_API_URL=http://localhost:9000/api ENV NEXT_PUBLIC_API_URL=$NEXT_PUBLIC_API_URL
-
Cloud Run Deployment - Set in service environment:
gcloud run deploy flip-fullstack-test-frontend \ --set-env-vars "NEXT_PUBLIC_API_URL=https://your-backend-url.run.app/api"
Backend Environment Variable:
ENV=production
PORT=9000See DEPLOYMENT.md for complete production setup guide.
From the root directory:
npm install
npm run devThis starts:
- Backend: Go server with Air (hot reload) on
http://localhost:9000 - Frontend: Next.js dev server on
http://localhost:3000
Both will reload automatically when you make changes.
Backend Only:
cd backend
# Development with hot reload (air)
make dev
# Or production mode (standard go run)
make run
# Install tools first
make installFrontend Only:
cd frontend
npm run devnpm run install:all # Install all dependencies
npm run dev # Development with hot reload (both)
npm run dev:backend # Backend only with hot reload
npm run dev:frontend # Frontend only
npm run build # Build both backend & frontend
npm run build:backend # Build backend binary
npm run build:frontend # Build frontend
npm run start # Start both (production)
npm run start:backend # Start backend (production)
npm run start:frontend # Start frontend (production)
npm run test # Run backend tests
npm run coverage # Generate coverage report
npm run lint # Lint both backend & frontend
npm run lint:backend # Lint backend only
npm run lint:frontend # Lint frontend only
npm run format # Format backend code
npm run tidy # Tidy backend dependenciesmake help # Show all available commands
make dev # Development with hot reload (air)
make run # Run server (production mode)
make build # Build binary
make lint # Run code linter
make format # Format code
make test # Run tests
make coverage # Run tests with coverage report
make tidy # Tidy dependencies
make install # Install development toolscd backend
cp .env.example .envExample .env:
PORT=9000
ENV=development
LOG_LEVEL=debug
DATABASE_URL=sqlite:transactions.db
MAX_FILE_SIZE=10485760
ALLOWED_FILE_TYPES=csv
DEFAULT_PAGE_SIZE=10
MAX_PAGE_SIZE=100See backend/.env.example for all options.
- Backend: Changes to Go files automatically rebuild with Air
- Frontend: Changes to Next.js files automatically reload
- Type: SQLite (file-based)
- File:
transactions.db(auto-created) - Migration: Automatic schema creation on startup
Reset database:
rm transactions.db
make run.
βββ backend/ # Go backend (Port 9000)
β βββ cmd/server/
β β βββ main.go # Entry point
β β βββ bootstrap.go # DI & routing
β βββ domain/
β β βββ transaction/ # Transaction domain
β β β βββ handler/
β β β βββ repository/
β β β βββ schemas/
β β β βββ use_case/
β β β βββ *_test.go # Unit tests
β β βββ upload/ # Upload domain
β β βββ handler/
β β βββ repository/
β β βββ use_case/
β β βββ *_test.go # Unit tests
β βββ pkg/
β β βββ db/ # Database setup
β β βββ validator/ # Input validation
β β βββ response/ # Generic response wrapper
β βββ mocks/ # Mock implementations for testing
β βββ .env.example # Environment template
β βββ Dockerfile # Production image
β βββ Makefile # Build commands
β βββ README.md # Backend docs
β
βββ frontend/ # Next.js frontend (Port 3000)
β βββ app/
β β βββ (dashboard)/
β β βββ components/
β β βββ layout.tsx
β βββ package.json
β βββ README.md
β
βββ docs/
β βββ DEPLOYMENT.md # Deployment guide
βββ .env.example # Root env example
βββ README.md # This file
βββ setup-gcp.sh # GCP deployment script
The project follows DDD principles with clean architecture separation:
Handler β Use Case β Repository β Database
- Query transactions
- Calculate balance (credits - debits from SUCCESS transactions)
- Filter and sort issues
- Validate transaction data
- Parse CSV files with validation
- Handle multipart file uploads
- Store transactions in database
- Return upload statistics
Package names match folder names:
Folder: domain/transaction/use_case/
Package: package use_case (not usecase)
Import: "github.com/.../use_case"
Alias: transactionUseCase "github.com/.../use_case"
- CSV Validator: File extension, size, format
- Field Validator: Timestamp, name, type, amount, status, description
# Run all tests
make test
# Run tests with coverage report
make coverageCoverage reports include:
- HTML report:
coverage/coverage.html - Text summary in console output
Tests are provided for:
- Transaction Domain: Balance calculation, filtering, sorting
- Upload Domain: CSV parsing, validation, error handling
- Validators: Field and file validation
curl -X POST http://localhost:9000/api/upload \
-F "file=@transactions.csv"curl http://localhost:9000/api/balance# Filter by status
curl "http://localhost:9000/api/issues?status=FAILED"
# Filter by type
curl "http://localhost:9000/api/issues?type=DEBIT"
# Search
curl "http://localhost:9000/api/issues?search=restaurant"
# Sort and paginate
curl "http://localhost:9000/api/issues?sort_by=amount&sort_order=DESC&page=1&page_size=10"
# Combined filters
curl "http://localhost:9000/api/issues?type=DEBIT&status=PENDING&sort_by=amount&sort_order=DESC"docker build -t flip-bank-backend:latest -f backend/Dockerfile backend/docker run -p 9000:9000 \
-e PORT=9000 \
-e ENV=production \
flip-bank-backend:latestdocker compose up -dQuick deploy to Cloud Run (15 minutes):
# 1. Run automated setup (5 min)
./setup-gcp.sh
# 2. Add GitHub secrets (3 min)
# Follow script output instructions
# 3. Deploy! (2 min each)
git push origin main # Auto-deploys via GitHub ActionsDeployment Features:
- β Separate Cloud Run services for frontend & backend
- β Automated CI/CD via GitHub Actions
- β Path-based triggers (only deploy what changed)
- β Docker multi-stage builds for optimization
- β Auto-scaling (0-10 instances) and HTTPS included
- β ~$0-40/month cost (free tier available)
See docs/DEPLOYMENT.md for complete guide.
- backend/README.md - Architecture, setup, and development guide
- backend/.env.example - Environment configuration template
- frontend/README.md - Frontend setup and component guide
- docs/DEPLOYMENT.md - Complete deployment guide
- setup-gcp.sh - Automated GCP setup script
- Clone repository
- Backend setup:
cd backend && make install && cp .env.example .env && make dev - Frontend setup:
cd frontend && npm install && npm run dev - Combined setup:
cd frontend && npm install && npm run dev:all - Test backend:
curl http://localhost:9000/api/health - Test frontend: Visit
http://localhost:3000 - Read backend/README.md
- Start developing!
- Run
make formatin backend - Run
make lintin backend - Run
make testin backend - Check
make coveragereport - Frontend:
npm run lint(if available)
β οΈ PENDING β warning style (yellow)- β FAILED β danger/red style
- β SUCCESS β success/green style
Bonus UI Features:
- Pagination with smart page numbers
- Reusable component library
- Pure CSS (no Tailwind/UI library)
- TypeScript support
- Responsive design
- Language: Go 1.23.10
- Framework: Fiber v2.52.5
- Database: SQLite with GORM ORM
- Validation: Custom validators
- Architecture: Domain-Driven Design
- Framework: Next.js
- Language: TypeScript
- Styling: CSS Modules
- Components: Reusable component system
- Containerization: Docker
- Orchestration: Docker Compose
- CI/CD: GitHub Actions
- Deployment: Google Cloud Run
- Development: Concurrently, Air (Go hot reload)
Port already in use:
PORT=3000 make runBuild fails:
go clean -modcache
make install
make buildDatabase issues:
rm transactions.db
make runDependencies issue:
rm -rf node_modules package-lock.json
npm install- This is a demonstration project for a fullstack take-home assignment
- All code follows best practices and clean architecture principles
- The project is designed to be production-ready but simplified for demo purposes
- Time-boxed: 4-6 hours for implementation
MIT License - See repository for details
Ready to get started? See Quick Start or Development above! π
For questions or issues, refer to the backend or frontend README files.