SmartSave is a GDPR-compliant smart savings application designed for users in the EU, focusing on transparency, collaboration, and security.
It combines traditional savings with AI-powered financial insights via the SaveBuddy AI assistant, allowing users to manage personal and group savings easily, while keeping their data private and secure.
| Developer | GitHub Username | Responsibilities |
|---|---|---|
| Daniel Adediran | @heisdanielade | Core Backend, DevOps & Frontend - repo management, authentication, profile & wallet management, savings, GDPR, notifications, CI/CD, SaveBuddy AI & frontend dev |
| Danylo Samedov | @DanSamedov | Core Backend & Frontend - authentication, profile & wallet management, transactions, savings, testing, SaveBuddy AI & frontend dev |
| Artem Ruzhevych | @ArtemRuzhevych | AI & Backend integrations - SaveBuddy AI system, logging, notifications, user analytics, GDPR, API metrics, research and testing |
- Features
- Snapshots
- Architecture
- Authentication & Authorization
- GDPR Compliance
- Core Savings
- Technologies & Design Decisions
- Future Improvements
- Closing Note
- Individual and group savings management
- AI savings assistant (SaveBuddy) for automation, requires user consent
- GDPR-compliant data handling and user privacy management
- Email-based OTP verification and secure login (JWT & OAuth)
- Detailed requests logging with hashed IPs
- Rate limiting, and background email notifications
- CI/CD integration for automated deployments
- Redis caching and PostgreSQL indexing for performance
- Modular and scalable monorepo architecture
SmartSave uses a modular architecture within a monorepo setup.
Each feature lives in its own module under the modules/ directory, designed for separation of concerns and ease of scaling.
Modules:
auth— authentication and authorization logicgdpr— GDPR compliance and user data managementuser— user profile and preferenceswallet— wallet creation and balance managementsavings— individual and group savingsnotifications— email-based user notificationsshared— reusable schemas and utilities
Each module contains:
repository.py # Database access layer
models.py # Database models (except Auth module)
schemas.py # Pydantic schemas
service.py # Business logic
helpers.py # Utility functions (optional)- Versioning:
/v1/...URL structure for all endpoints - Docs: Swagger & ReDoc available at
/v1/docs(protected with Basic Auth) - Rate Limiting:
Per-minute/hourrestrictions per IP - Redis: Used for
cachingand fast data retrieval with reasonable TTLs + manual cache invalidation - Logging: Structured
JSON logsper request, with hashed IP addresses - Makefile: Common commands for Docker, Alembic, and Pytest
- Scripts: Dev and prod startup scripts in
scripts/ - Database: PostgreSQL + Alembic for
DB migrations - CI/CD: GitHub Actions workflows (
ci.yml,cd.yml) - Environment:
.env.exampleprovided for configuration variables
Backend System Flow:
Middleware → Router → Service → Repository → Database- User registers with email and password.
- A 6-digit OTP is sent to the user’s email for verification.
- Once verified,
user.is_verifiedis set toTrue. - On successful login, a JWT is issued and used for all authenticated requests.
- Failed logins increment
user.failed_login_attempts; exceeding the limit locks the account. - Locked accounts trigger a notification email to the user.
- Roles are defined as:
- USER: Full access to own data only
- ADMIN: Limited create/read access except GDPR/user/wallet data
- SUPER_ADMIN: Full CRUD access (excluding wallet/transactions modification)
Wallets and transactions are immutable - they cannot be modified or deleted once created.
SmartSave was built around the three core GDPR principles:
- Right to Access Data
- Right to Modify Data
- Right to Delete Data
- IP addresses are stored as irreversible hashes in logs.
- Users can request a data report, delivered as a password-protected PDF via email.
- Data modification is allowed through the app or via support requests.
- Account deletions are soft-deleted for 365 days before anonymization (duration is easily configurable).
- Anonymization Process:
- All PII replaced with random values.
- User can no longer log in.
- Maintains referential integrity for financial auditing.
- Logs older than 30 days are auto-deleted.
- GDPR requests are logged in a dedicated
GDPRRequesttable. - After two years, even the anonymized GDPR requests are removed.
To improve performance and reduce database load, we implemented Redis caching for frequently accessed endpoints, i.e:
GET /user/meGET /wallet/transactions
-
Cache Key Naming:
Keys follow a consistent pattern to avoid collisions and allow easy invalidation:- Current user:
user_current:{user_email} - Wallet transactions:
wallet_transactions:{user_id}:page:{page}:size:{page_size}
- Current user:
-
Cache Retrieval:
Before hitting the database, the application checks Redis for the cached data.- If a cache hit occurs, the JSON data is returned immediately.
- If a cache miss occurs, the data is fetched from the database, cached in Redis, and then returned.
-
Time-to-Live (TTL):
Cached data expires after a default TTL (10 minutes) / custom TTL set for each cache store, to ensure freshness. -
Cache Invalidation:
Whenever the underlying data changes (e.g., user updates, new transactions), the relevant cache keys are invalidated automatically to prevent stale data. -
Performance Impact:
- Cache miss: ~124–150ms (includes DB query)
- Cache hit: ~50-80ms (Redis retrieval + deserialization)
This strategy ensures low-latency responses for frequently accessed endpoints while keeping the database load minimal.
- Each goal (e.g., “Buy a bicycle”) is a single independent saving entry.
- Funds are allocated from the user’s wallet.
user.locked_amounttracks funds currently in use for savings/goals.
- Groups have 2–7 members and one or two admins.
- Each group focuses on one shared goal.
- Contributions and withdrawals appear as chat-like transactions.
- Admins can enable approval for fund withdrawals.
- Users violating group rules (e.g., unauthorized withdrawals) are banned from rejoining for 7 days.
- Group balances are derived from members’ wallets — groups have no separate wallets.
- Groups trigger automatic notifications for:
- Added/removed members
- Contributions
- Target reached (50% or 100%)
- Each verified user automatically gets one wallet.
- Wallet fields:
total_balancelocked_amount- Computed
available_balance = total_balance - locked_amount
- Base app currency is EUR, but users can select from 4 additional currencies for frontend display.
- Exchange rates are fetched from an external API and cached in the DB.
| Technology | Purpose | Design Relation |
|---|---|---|
| FastAPI | High-performance backend & auto-generated docs | Enables clear dependency injection and modular design |
| Pydantic | Data validation and serialization | Supports DRY and type-safe schema sharing |
| SQLModel + SQLAlchemy | ORMs for PostgreSQL | Enforces consistent data access layer (Repository pattern) |
| Alembic | Database migrations | Streamlined schema versioning |
| Slow-api | Rate-limiting | For security and simplified implementation |
| Redis | Caching | Optimizes performance and scalability |
| Docker | Containerization | Simplifies setup and deployment |
| Pytest | Automated testing | Ensures reliability and regression safety |
| GitHub Actions | CI/CD pipeline | Automates testing and deployment |
| React | Frontend | User interface and experience |
| Tailwind CSS | Styling | Responsive and modern design |
| Vite | Build tool | Fast and modern frontend development |
- SOLID: Dependency Injection in routers promotes modular and testable code.
- DRY: Shared helpers and reusable service methods minimize duplication.
- Separation of Concerns: Clear flow: Middleware → Router → Service → Repository.
- Extensibility: Notification service follows the ABC pattern, allowing easy integration of SMS or push services in the future.
- Factory + Registry Pattern: The email notification system uses a combination of design patterns:
- Factory Pattern (
EmailProviderFactory): Dynamically selects the email provider (SMTP or Resend) based on configuration, enabling easy switching between providers without code changes. - Registry Pattern (
EMAIL_TEMPLATES): Maps notification types to their corresponding templates, subjects, and context models in a centralized dictionary, making it simple to add new notification types. - Strategy Pattern (
EmailProviderABC): Defines a common interface for different email providers, allowing interchangeable implementations while maintaining consistent behavior. - This architecture ensures the notification system is flexible, maintainable, and easily extensible for new providers or notification types.
- Factory Pattern (
Few snapshots of the frontend screens, backend endpoints, email templates & API responses.
| Description | Preview |
|---|---|
| Landing Page | ![]() |
| Login Page | ![]() |
| User Dashboard | ![]() |
| User Profile | ![]() |
| Transactions | ![]() |
| Group Details | ![]() |
| Group Members | ![]() |
| Group Chat | ![]() |
| Withdraw from Group | ![]() |
| Data Report Request | ![]() |
| Description | Preview |
|---|---|
| Mobile Dashboard | ![]() |
| Mobile Groups | ![]() |
| Mobile Chat | ![]() |
| Mobile Transactions | ![]() |
| Description | Preview |
|---|---|
| Authentication | ![]() |
| Account & GDPR | ![]() |
| Wallet & Transactions | ![]() |
| Admin & Groups | ![]() |
| Description | Preview |
|---|---|
| Login Notification | ![]() |
| Reset Password | ![]() |
| GDPR Data Export | ![]() |
| Wallet Deposit | ![]() |
| Description | Preview |
|---|---|
| Wallet Deposit | ![]() |
| Wallet Transactions | ![]() |
- Introduce referral system for user growth.
- Split modules into dedicated microservices for better scalability.
- Integrate real banking APIs for live savings and transactions.
- Add SMSNotificationService and push notifications.
- Expand SaveBuddy AI to provide personalized financial recommendations.























