A comprehensive invoicing and document management system with a React frontend and Python Flask backend. Runabine helps businesses create, manage, and track invoices, quotations, and receipts with advanced features like audit logging, JWT authentication, and secure token management.
- Document Management: Create, edit, and manage invoices, quotations, and receipts
- Customer Management: Add and organize customer information
- Document Tracking: Track document status (draft, issued, partially paid, paid)
- Archive System: Archive documents for better organization
- Payment Methods: Support for cash, check, credit card, bank transfer, and other payment types
- JWT-based Authentication: Secure token-based user authentication with 8-hour expiration
- Token Revocation: Logout support with token revocation using unique JWT IDs (jti)
- Role-based Access Control: Support for admin, accountant, and user roles
- Bcrypt Password Hashing: Secure password storage and verification
- User Status Management: Active, inactive, and suspended user states
- Audit Logging: Complete audit trail for all entity changes with previous/new state tracking
- Idempotency Support: Prevent duplicate requests and ensure data consistency
- CORS Support: Cross-origin request handling for frontend-backend communication
- Database Constraints: Referential integrity and data validation at database level
- React (v19.2.3) - UI library
- React Router DOM - Client-side routing
- Material-UI (MUI) - Component library
- Emotion - CSS-in-JS styling
- React Testing Library - Testing utilities
- Python 3 - Server language
- Flask - Web framework
- Flask-CORS - Cross-origin request handling
- Flask-Bcrypt - Password hashing
- PyJWT - JWT token handling
- MySQLdb - MySQL database driver
- Playwright - Browser automation (for PDF generation)
- MySQL - Relational database
runabine/
├── frontend/ # React frontend application
│ ├── src/
│ │ ├── components/ # React components
│ │ ├── App.js # Main app component
│ │ ├── Login.js # Login component
│ │ ├── Dashboard.js # Dashboard component
│ │ └── index.js # Entry point
│ └── public/
├── backend/ # Flask backend application
│ ├── app.py # Main Flask application
│ ├── db.py # Database connection
│ ├── exceptions.py # Custom exception classes
│ ├── hash.py # Password hashing utilities
│ ├── auth/
│ │ ├── jwt.py # JWT token generation/decoding
│ │ ├── decorators.py # Authentication decorators
│ │ └── token_cleanup.py # Token cleanup utilities
│ ├── migrations/ # Database migrations
│ └── static/ # Static files (logos, etc.)
├── tools/ # Utility scripts
│ └── remove_comments.py # Comment removal tool
└── package.json # Frontend dependencies
- Node.js (v14 or higher) - For frontend
- Python (v3.7 or higher) - For backend
- MySQL (v5.7 or higher) - Database
- pip - Python package manager
-
Install Python dependencies:
cd backend pip install flask flask-cors flask-bcrypt pyjwt MySQLdb-python playwright -
Configure database connection: Edit
backend/db.pyand update:DB_HOST- Database hostDB_USER- Database userDB_PASSWORD- Database passwordDB_NAME- Database name
-
Initialize database:
python backend/init_audit_db.py
This will run all migrations in the
migrations/folder to set up tables and constraints. -
Set JWT secret:
export JWT_SECRET=your_secret_key_here -
Start the backend server:
python backend/app.py
The server will start on
http://localhost:5000
-
Install dependencies:
npm install
-
Start the development server:
npm start
The application will open at
http://localhost:3000 -
Build for production:
npm build
POST /auth/login- User loginPOST /auth/logout- User logout with token revocation
GET /documents- List user's documentsPOST /documents- Create new documentGET /documents/:id- Get document detailsPUT /documents/:id- Update documentDELETE /documents/:id- Delete document
GET /customers- List customersPOST /customers- Create customerGET /customers/:id- Get customer detailsPUT /customers/:id- Update customer
The application uses custom exception classes for domain-level errors:
- NotFoundError (404) - Resource does not exist
- ForbiddenError (403) - User lacks permission
- ImmutableResourceError (409) - Resource cannot be modified
- ValidationError (400) - Input or business logic validation failed
All errors are mapped to HTTP responses via centralized Flask error handlers.
npm testcd backend
python -m pytest test_exception_handling.py
python -m pytest test_jwt_logout.pyThe database includes the following key tables:
- users - User accounts with roles and status
- customers - Customer information (owned by users)
- documents - Invoices, quotations, receipts
- audit_log - Complete audit trail of all changes
- token_revocation - Revoked JWT tokens
Refer to migrations in backend/migrations/ for detailed schema.
- Change default credentials - Update database connection details in
backend/db.py - Set strong JWT secret - Use a strong, random string for
JWT_SECRETenvironment variable - Enable HTTPS - Use HTTPS in production
- Rate limiting - Consider adding rate limiting for login attempts
- Audit logs - Regularly review audit logs for suspicious activity
- Create a new branch for features:
git checkout -b feature/your-feature - Make your changes and commit:
git commit -am 'Add your feature' - Push to the branch:
git push origin feature/your-feature - Open a pull request
This project is private and proprietary.
This is a portfolio project. For inquiries or suggestions, please contact me! Simbaraymonds@gmail.com XOXO For questions or support, please reach out to the development team.