Keep track of shared expenses and balances with housemates, trips, groups, friends, and family.
- Simplified Currency Handling: Amounts are treated as integers in micro units (e.g., cents).
- No Authentication: No security or authentication mechanisms are in place.
- Open Transactions: Anyone can create transactions.
- Clearing Balances: Clearing a user’s balance resets all +ve and -ve balances to zero.
- Immediate Processing: Transactions are processed immediately.
- Percentage Rounding: Percentages are rounded to the nearest natural number.
- Backend: Live Deployment
- API Documentation: ReDoc
- YouTube Video: Overview
git clone git@github.com:subhrashisdas/splitwise.git
cd splitwise
pip install -r requirements.txt
export PYTHONPATH=$(pwd)
export DATABASE_URL=sqlite:///./splitwise.db
fastapi dev main.py
erDiagram
User {
int id PK
string email
}
Transaction {
int id PK
string description
int total_amount
datetime deleted_at
}
Ledger {
int id PK
int from_user_id FK
int to_user_id FK
int amount
int transaction_id FK
datetime created_at
}
User ||--o{ Ledger : "sends"
User ||--o{ Ledger : "receives"
Transaction ||--o{ Ledger : "includes"
- Codebase: Single version-controlled codebase.
- Dependencies: Managed via
requirements.txt
or similar. - Configuration: Stored in environment variables.
- Backing Services: Configured via environment variables.
- Build, Release, Run: Automated processes and versioned artifacts.
- Processes: Stateless and concurrency-friendly.
- Port Binding: Listen on a port; use service discovery if needed.
- Concurrency: Managed with process managers; conduct load testing.
- Disposability: Quick startup/shutdown and graceful shutdown.
- Dev/Prod Parity: Maintain similar environments; automate and test thoroughly.
- Logs: Centralized logging; avoid local log storage.
- Admin Processes: Run as one-off processes; automate where possible.
- Automatic Migrations: Manual migrations to avoid unintended schema changes.
- Core Logic for Transactions: Modular and predictable transaction handling.
- Rounding Handling: Rounding errors assigned to the last user in percentage splits.
- Payload Validation: Extensive validation to prevent incorrect/malicious inputs.
- Update Logic: Soft-delete old transactions and create new ones to maintain history.
- Database Flexibility: Supports MySQL, PostgreSQL, and SQLite.
- Optimistic Amount Assignment: Handles all cases including partials.
- Cache User Balances: Improve performance with caching.
- Currency Handling: Support multiple currency types.
- Sharding and Scaling: Consider for scalability.
- Enhanced Security: Implement authentication and authorization.
- Asynchronous Processing: Handle high request volumes efficiently.
- Proper Transaction Management: Ensure data integrity and avoid blocking operations.
- Advanced Error Handling: Develop robust error handling and feedback.
- User Interface: Build a user-friendly interface for transactions and balances.
- Comprehensive Testing: Expand test coverage for reliability.
- Knapsack Algorithm: Optimize ledger allocation.
- Pagination: Implement pagination for list endpoints.
Endpoint: POST /users
Request:
curl --location 'https://sd-splitwise.vercel.app/users' \
--data-raw '{"email": "test_4@gmail.com"}'
Response:
{
"id": 5,
"email": "test_5@gmail.com"
}
Endpoint: GET /users/{user_id}/balance
Request:
curl --location 'https://sd-splitwise.vercel.app/users/1/balance'
Response:
[
{ "user_id": 3, "total_amount": 9000 },
{ "user_id": 4, "total_amount": 9000 }
]
Endpoint: POST /users/{user_id}/clear
Request:
curl --location 'https://sd-splitwise.vercel.app/users/1/clear' \
--data '{}'
Endpoint: POST /transactions/
Request:
curl --location 'https://sd-splitwise.vercel.app/transactions/' \
--data '{
"description": "Office supplies",
"total_amount": 30000,
"split_type": "uneven",
"computation_type": "amount",
"from_users": [{"user_id": 1, "value": 10000}, {"user_id": 2, "value": 20000}],
"to_users": [{"user_id": 1, "value": 12000}, {"user_id": 3, "value": 15000}, {"user_id": 4, "value": 3000}]
}'
Response:
{
"description": "Office supplies",
"total_amount": 30000,
"id": 13,
"ledgers": [
{ "amount": 10000, "from_user_id": 1, "to_user_id": 1, "transaction_id": 13 },
{ "amount": 2000, "from_user_id": 2, "to_user_id": 1, "transaction_id": 13 },
{ "amount": 15000, "from_user_id": 2, "to_user_id": 3, "transaction_id": 13 },
{ "amount": 3000, "from_user_id": 2, "to_user_id": 4, "transaction_id": 13 }
]
}
Endpoint: POST /transactions/
Request:
curl --location 'https://sd-splitwise.vercel.app/transactions/' \
--data '{
"description": "Office supplies",
"total_amount": 30000,
"split_type": "even",
"computation_type": "amount",
"from_users": [{"user_id": 1}, {"user_id": 2}],
"to_users": [{"user_id": 1}, {"user_id": 3}]
}'
Response:
Response will depend on transaction processing logic.
Endpoint: POST /transactions/
Request:
curl --location 'https://sd-splitwise.vercel.app/transactions/' \
--data '{
"description": "Office supplies",
"total_amount": 30000,
"split_type": "uneven",
"computation_type": "percentage",
"from_users": [{"user_id": 1, "value": 60}, {"user_id": 2, "value": 40}],
"to_users": [{"user_id": 3, "value": 30}, {"user_id": 4, "value": 70}]
}'
Response:
Response will depend on transaction processing logic.
Endpoint: PUT /transactions/{transaction_id}
Request:
curl --location --request PUT 'https://sd-splitwise.vercel.app/transactions/2' \
--data '{
"description": "Office supplies",
"total_amount": 30000,
"split_type": "uneven",
"computation_type": "amount",
"from_users": [{"user_id": 1, "value": 10000}, {"user_id": 2, "value": 20000}],
"to_users": [{"user_id": 1, "value": 12000}, {"user_id": 3, "value": 15000}, {"user_id": 4, "value": 3000}]
}'
Response:
{
"description": "Office supplies",
"total_amount": 30000,
"id": 2,
"ledgers": [
{ "amount": 10000, "from_user_id": 1, "to_user_id": 1, "transaction_id": 2 },
{ "amount": 20000, "from_user_id": 2, "to_user_id": 1, "transaction_id": 2 },
{ "amount": 12000, "from_user_id": 1, "to_user_id": 1, "transaction_id": 2 },
{ "amount": 15000, "from_user_id": 2, "to_user_id": 3, "transaction_id": 2 },
{ "amount": 3000, "from_user_id": 2, "to_user_id": 4, "transaction_id": 2 }
]
}
© 2024 Subhrashis Das. All rights reserved.