๐ง Active development in progress. Vercel deployment coming soon.
A secure, production-grade financial analysis platform built with Go. Transform your M-PESA statements into actionable insights with AI-powered categorization and interactive dashboards.
โข Report Bug โข Request Feature
- About The Project
- Features
- Tech Stack
- Getting Started
- Project Structure
- API Documentation
- Development Roadmap
- Contributing
- License
- Contact
- Acknowledgments
M-PESA Statement Analyzer is a comprehensive financial management tool that helps users understand their spending patterns by parsing M-PESA PDF statements, automatically categorizing transactions, and presenting beautiful visualizations.
- Manual analysis of M-PESA statements is time-consuming
- Difficult to track spending across categories
- No built-in tools for financial trend analysis
- Hard to identify spending patterns and anomalies
This application provides:
- Automated PDF parsing - Extract all transactions from your statements instantly
- AI categorization - Intelligently classify transactions (Food, Transport, Bills, etc.)
- Visual analytics - Interactive charts and graphs to understand your finances
- Secure storage - Your financial data is encrypted and protected
- Multi-user support - Each user has their own private workspace
- JWT-based authentication system
- Bcrypt password hashing
- Secure file validation and sanitization
- CORS and security headers protection
- Input validation on all endpoints
- Encrypted data storage (coming in Phase 4)
- PDF statement parsing and text extraction
- AI-powered transaction categorization using OpenAI
- Summary reports (total inflows, outflows, balance)
- Category-wise spending breakdown
- Time-series trend analysis (coming in Phase 3)
- Custom date range filtering (coming in Phase 3)
- Clean architecture with repository pattern
- PostgreSQL with optimized indexes
- Database migration system
- Redis caching (coming in Phase 4)
- Async job processing (coming in Phase 3)
- Docker containerization
- Horizontal scalability ready
- RESTful API design
- Interactive web dashboard
- Real-time job status tracking (coming in Phase 3)
- Export to CSV/Excel (coming in Phase 5)
- Mobile-responsive interface
- Go 1.21+ - Main programming language
- PostgreSQL 15 - Primary database
- Redis 7 - Caching layer (Phase 4)
- JWT - Authentication tokens
- Bcrypt - Password encryption
- HTML5/CSS3 - Dashboard UI
- Chart.js - Data visualization
- Vanilla JavaScript - Client-side logic
- Docker & Docker Compose - Containerization
- golang-migrate - Database migrations
- Air - Hot reload in development
- GitHub Actions - CI/CD (Phase 5)
- OpenAI GPT - Transaction categorization
- pdftotext - PDF parsing
Make sure you have the following installed:
-
Clone the repository
git clone https://github.com/Wendyshiro/M-PESA-Statements-Analyzer.git cd M-PESA-Statements-Analyzer -
Install Go dependencies
go mod download
-
Set up environment variables
cp .env.example .env
Edit
.envwith your configuration:# Server PORT=8080 ENV=development # Database DATABASE_URL=postgresql://mpesa_user:mpesa_pass@localhost:5432/mpesa_analyzer?sslmode=disable # Security (generate secure keys!) JWT_SECRET=your-secret-key-minimum-32-characters ENCRYPTION_KEY=exactly-32-characters-required!! # OpenAI OPENAI_API_KEY=sk-your-openai-api-key
-
Start infrastructure with Docker
docker-compose up -d
This starts:
- PostgreSQL on port 5432
- Redis on port 6379
- pgAdmin on port 5050 (optional)
-
Run database migrations
# Install migrate tool go install -tags 'postgres' github.com/golang-migrate/migrate/v4/cmd/migrate@latest # Apply migrations make migrate-up # OR migrate -path migrations -database "${DATABASE_URL}" up
-
Start the application
# Using Make make run # OR directly with Go go run cmd/api/main.go
-
Access the application
- API: http://localhost:8080
- Dashboard: http://localhost:8080/dashboard
- Health Check: http://localhost:8080/health
# Register a new user
curl -X POST http://localhost:8080/register \
-H "Content-Type: application/json" \
-d '{"email":"test@example.com","password":"password123"}'
# You'll get a token in the response - copy it!
# Upload a statement (replace YOUR_TOKEN)
curl -X POST http://localhost:8080/upload \
-H "Authorization: Bearer YOUR_TOKEN" \
-F "file=@path/to/statement.pdf"M-PESA-Statements-Analyzer/
โ
โโโ cmd/
โ โโโ api/
โ โโโ main.go # Application entry point
โ
โโโ handlers/ # HTTP request handlers
โ โโโ auth.go # Registration & login
โ โโโ upload.go # File upload handling
โ โโโ health.go # Health checks
โ
โโโ models/ # Data models
โ โโโ user.go # User entity
โ โโโ job.go # Processing job entity
โ โโโ transaction.go # Transaction entity
โ
โโโ repository/ # Database layer (Data Access)
โ โโโ user.go # User DB operations
โ โโโ job.go # Job DB operations
โ โโโ transaction.go # Transaction DB operations
โ
โโโ middleware/ # HTTP middleware
โ โโโ auth.go # JWT authentication
โ โโโ security.go # Security headers
โ โโโ validation.go # Input validation
โ
โโโ auth/ # Authentication logic
โ โโโ jwt.go # Token management
โ
โโโ database/ # Database connection
โ โโโ database.go # Pool & health checks
โ
โโโ config/ # Configuration
โ โโโ config.go # Env variable loader
โ
โโโ utils/ # Utility functions
โ โโโ pdf_parser.go # PDF extraction
โ โโโ categorizer.go # AI categorization
โ
โโโ migrations/ # Database migrations
โ โโโ 000001_create_users_table.up.sql
โ โโโ 000001_create_users_table.down.sql
โ โโโ 000002_create_jobs_table.up.sql
โ โโโ ...
โ
โโโ dashboard/ # Frontend
โ โโโ index.html
โ
โโโ .env.example # Environment template
โโโ .gitignore
โโโ docker-compose.yml # Docker services
โโโ Dockerfile # Application container
โโโ Makefile # Development commands
โโโ go.mod
โโโ go.sum
โโโ README.md
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Client Layer โ
โ (Browser / Mobile / Postman) โ
โโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ HTTP/HTTPS
โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ API Gateway Layer โ
โ (Middleware: Auth, CORS, etc) โ
โโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Handlers Layer โ
โ (auth.go, upload.go, health.go) โ
โโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Service Layer โ
โ (Business Logic: PDF Parsing, AI, etc) โ
โโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Repository Layer โ
โ (Database Operations) โ
โโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Database Layer โ
โ PostgreSQL + Redis Cache โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
http://localhost:8080
Most endpoints require authentication. Include the JWT token in the Authorization header:
Authorization: Bearer <your-token>
POST /register - Register a new user
Request:
curl -X POST http://localhost:8080/register \
-H "Content-Type: application/json" \
-d '{
"email": "user@example.com",
"password": "securepassword123"
}'Response (201 Created):
{
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"user": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"email": "user@example.com",
"created_at": "2026-02-16T10:30:00Z",
"updated_at": "2026-02-16T10:30:00Z"
}
}Validation Rules:
- Email must be valid format
- Password must be at least 8 characters
- Email must be unique
POST /login - Login existing user
Request:
curl -X POST http://localhost:8080/login \
-H "Content-Type: application/json" \
-d '{
"email": "user@example.com",
"password": "securepassword123"
}'Response (200 OK):
{
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"user": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"email": "user@example.com",
"created_at": "2026-02-16T10:30:00Z",
"updated_at": "2026-02-16T10:30:00Z"
}
}Error Responses:
- 401: Invalid credentials
- 400: Missing email or password
GET /health - Health check
Request:
curl http://localhost:8080/healthResponse (200 OK):
{
"status": "healthy",
"services": {
"database": "healthy"
}
}POST /upload - Upload M-PESA statement
Request:
curl -X POST http://localhost:8080/upload \
-H "Authorization: Bearer YOUR_TOKEN" \
-F "file=@statement.pdf"Response (202 Accepted):
{
"job_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
"message": "File uploaded successfully and queued for processing",
"filename": "mpesa_statement.pdf"
}File Requirements:
- Must be a PDF file
- Maximum size: 10MB
- Must be a valid M-PESA statement
Error Responses:
- 401: Missing or invalid token
- 400: Invalid file type or size
- 413: File too large
All errors follow this format:
{
"error": "Human-readable error message",
"code": "ERROR_CODE"
}Common Error Codes:
UNAUTHORIZED- Missing or invalid authenticationINVALID_INPUT- Validation failedUSER_EXISTS- Email already registeredINVALID_FILE- File validation failedINTERNAL_ERROR- Server error
Status: โ Complete (Week 1-3)
- File validation and sanitization
- JWT-based authentication
- Security headers (CORS, CSP, XSS protection)
- Password hashing with bcrypt
- Input validation middleware
- Error handling
Status: ๐ In Progress (Week 4)
- PostgreSQL setup with Docker
- Database migration system
- User repository implementation
- Job repository implementation
- Transaction repository implementation
- Database indexes and optimization
- Connection pooling
Status: ๐ Planned (Week 5-6)
- Redis integration
- Message queue setup (RabbitMQ or Redis Queue)
- Background worker for PDF processing
- Job status tracking and updates
- Retry logic for failed jobs
- Job result storage
- Webhook notifications
Status: ๐ Planned (Week 7-8)
- Redis caching layer
- Category result caching
- Database query optimization
- API response caching
- Rate limiting implementation
- Query result pagination
- Database connection pooling tuning
Status: ๐ Planned (Week 9-10)
- Unit tests for all layers
- Integration tests
- End-to-end tests
- GitHub Actions CI/CD pipeline
- Code coverage reporting (target: 80%+)
- Security scanning (gosec)
- Dependency vulnerability scanning
Status: ๐ Planned (Week 11-12)
- Prometheus metrics
- Structured logging
- Distributed tracing (OpenTelemetry)
- Kubernetes deployment manifests
- Horizontal Pod Autoscaling
- Database backup automation
- Disaster recovery procedures
- Documentation site
- Multi-language support (i18n)
- PDF statement templates for other providers
- Budget planning and alerts
- Spending predictions with ML
- Mobile app (Flutter)
- Batch processing for multiple statements
- Export to CSV, Excel, PDF
- Email reports
- Social features (anonymous spending comparisons)
# Run all tests
make test
# Run with coverage
go test -cover ./...
# Run specific package
go test ./handlers/...
# Verbose output
go test -v ./...
# Generate coverage report
go test -coverprofile=coverage.out ./...
go tool cover -html=coverage.out- Download Postman
- Import the collection from
postman_collection.json(if available) - Set up environment variables:
baseUrl:http://localhost:8080token: (auto-filled after login)
Testing Workflow:
- Register โ Get token
- Login โ Verify token
- Upload โ Check file validation
- Health โ Verify services
See Postman Testing Guide for detailed instructions.
The application uses PostgreSQL with the following main tables:
users - User accounts
id(UUID) - Primary keyemail(VARCHAR) - Unique emailpassword_hash(VARCHAR) - Bcrypt hash- Timestamps
jobs - Processing jobs
id(UUID) - Primary keyuser_id(UUID) - Foreign key to usersfile_path(VARCHAR) - File locationstatus(ENUM) - queued, processing, completed, failed- Timestamps
transactions - Parsed M-PESA transactions
id(UUID) - Primary keyjob_id(UUID) - Foreign key to jobsreceipt_no(VARCHAR) - M-PESA receiptamount(DECIMAL) - Transaction amountcategory(VARCHAR) - AI-assigned category- Timestamps
# Create new migration
migrate create -ext sql -dir migrations -seq migration_name
# Apply migrations
make migrate-up
# Rollback
make migrate-down
# Check version
make migrate-version# Start all services
docker-compose up -d
# View logs
docker-compose logs -f
# Stop services
docker-compose down
# Rebuild
docker-compose up -d --build# Build production image
docker build -t mpesa-analyzer:v1.0.0 .
# Run container
docker run -d \
-p 8080:8080 \
--env-file .env.production \
mpesa-analyzer:v1.0.0
# With docker-compose
docker-compose -f docker-compose.prod.yml up -dContributions are what make the open-source community amazing! Any contributions you make are greatly appreciated.
-
Fork the Project
# Click the "Fork" button on GitHub -
Clone your Fork
git clone https://github.com/YOUR_USERNAME/M-PESA-Statements-Analyzer.git cd M-PESA-Statements-Analyzer -
Create a Feature Branch
git checkout -b feature/AmazingFeature
-
Make your Changes
- Write clean, documented code
- Follow Go best practices
- Add tests for new features
- Update documentation
-
Commit your Changes
git add . git commit -m "Add some AmazingFeature"
-
Push to your Fork
git push origin feature/AmazingFeature
-
Open a Pull Request
- Go to the original repository
- Click "New Pull Request"
- Select your feature branch
- Describe your changes
- Code Style: Follow Go conventions (run
gofmt) - Testing: Add tests for new features
- Documentation: Update README and code comments
- Commits: Use clear, descriptive commit messages
- Issues: Check existing issues before creating new ones
Look for issues tagged with good first issue or help wanted:
- Add input validation for edge cases
- Improve error messages
- Write documentation
- Add unit tests
- Fix typos
Distributed under the MIT License. See LICENSE for more information.
MIT License
Copyright (c) 2026 Wendyshiro
Wendyshiro
- GitHub: @Wendyshiro
- Project Link: https://github.com/Wendyshiro/M-PESA-Statements-Analyzer
- Live Demo: coming soon
This project was built with the help of amazing open-source tools and resources:
- Go - Programming language
- PostgreSQL - Database
- Redis - Caching
- JWT-Go - Authentication
- pgx - PostgreSQL driver
- Chart.js - Data visualization
- OpenAI - AI categorization
- M-PESA for revolutionizing mobile money in Kenya and Africa
- The Go community for excellent documentation and support
- Open-source contributors worldwide
Made with โค๏ธ by Wendyshiro