Commit Graph

15 Commits

Author SHA1 Message Date
Víctor Falcón 70b603e901
feat: Spanish localization (#74)
## Pending
- [x] Translate landing page
- [x] Dashboard
- [x] Accounts list page
- [x] Account page
- [x] Cashflow
- [x] Budgets
- [x] Transactions
- [x] Settings

## Screenshots
<img width="1210" height="969" alt="image"
src="https://github.com/user-attachments/assets/c7935e5c-488d-4941-8f19-8834e5668257"
/>
<img width="1211" height="972" alt="image"
src="https://github.com/user-attachments/assets/e94e1daf-233a-4a49-aa65-5678c772d178"
/>
2026-02-08 11:58:08 +01:00
Víctor Falcón 370d388d99
feat: Enable email verification on sign up (#97)
## Summary
- Enables `MustVerifyEmail` on the `User` model so new users must verify
their email before accessing protected routes
- Unverified users are redirected to `/email/verify` when attempting to
access routes behind the `verified` middleware (subscribe, onboarding,
dashboard)
- A verification email is automatically sent on registration via Fortify

## Screenshot

![Email verification
page](https://raw.githubusercontent.com/whisper-money/whisper-money/mail-verification/storage/videos/email-verification-page.png)

## Video


https://github.com/whisper-money/whisper-money/raw/mail-verification/storage/videos/ac0945c527f014b9cd657f18c911f496.webm

## Test plan
- [x] New test: registration sends a `VerifyEmail` notification
- [x] New test: newly registered users have `email_verified_at` as null
- [x] New test: unverified users are redirected to `verification.notice`
from protected routes (subscribe, onboarding, dashboard)
- [x] New test: verified users are not redirected to verification notice
- [x] Existing email verification and notification tests still pass (31
auth tests, 52 settings tests)
- [x] Browser walkthrough: registration → redirected to `/email/verify`
page with "Resend verification email" button
2026-02-03 10:15:07 +01:00
Víctor Falcón 9b6c30775f
Add Budgeting Feature to Track and Manage Spending (#36)
## Overview

We're excited to introduce budgeting capabilities to Whisper Money! This
feature helps you take control of your finances by setting spending
limits and tracking your progress over time.

## Screenshots
<img width="1316" height="793" alt="image"
src="https://github.com/user-attachments/assets/ac394d36-cded-4ea4-9883-120785e260f1"
/>
<img width="1315" height="907" alt="image"
src="https://github.com/user-attachments/assets/7c682474-5aa7-4388-b626-29b56f5ebbef"
/>
<img width="1315" height="992" alt="image"
src="https://github.com/user-attachments/assets/21eace45-23c6-472d-9aa0-0feb6db3fba4"
/>

## What's New

### Create Flexible Budgets
- Set budgets for specific categories or labels
- Choose from monthly, weekly, bi-weekly, or custom periods
- Set your own budget start date for better alignment with your pay
schedule

### Track Your Spending
- Visual spending charts show how much you've spent vs. your budget
- See at a glance which budgets are on track and which need attention
- View all transactions that count toward each budget

### Smart Budget Management
- **Carry Over**: Unused budget amounts automatically roll into the next
period
- **Reset**: Unused amounts return to your available money pool
- Edit or delete budgets anytime as your needs change

### Easy Access
- New Budgets section in the main navigation
- Quick overview cards showing budget status
- Detailed budget pages with spending history and transaction lists

## How It Works

1. Create a budget by selecting a category or label and setting your
spending limit
2. Your transactions are automatically matched to relevant budgets
3. Track your progress with visual charts and spending summaries
4. Adjust your budgets as needed to stay on track with your financial
goals

This feature is now available behind a feature flag and can be enabled
for users who want to start budgeting their expenses.
2026-01-21 15:25:50 +01:00
Víctor Falcón 439ec86722
chore: Simplify IndexedDB sync by moving to Inertia shared props (#63)
This PR simplifies the IndexedDB synchronization mechanism by removing
individual sync controllers and services, and instead using Inertia.js
shared props to provide data globally across the application.

## Benefits

1. **Simplified Architecture**: Removed complex sync logic for
static/semi-static data (accounts, categories, banks, labels, automation
rules)
2. **Better Performance**: Data is now shared via Inertia props,
eliminating unnecessary API calls and IndexedDB operations
3. **Reduced Complexity**: Significantly reduced codebase size (~2000
lines removed)
4. **Better UX**: Data is immediately available on page load without
waiting for sync operations
5. **Maintainability**: Fewer moving parts means easier to maintain and
debug

## Migration Notes

- Transaction syncing still uses IndexedDB for offline support
- All other data (accounts, categories, banks, labels, automation rules)
is now fetched via Inertia shared props
- Components automatically receive updated data on navigation without
manual sync operations
2026-01-19 19:15:26 +01:00
Víctor Falcón 9bd1fcea37
Demo Account Experience (#51)
## Summary

<img width="1220" height="1001" alt="whispermoney test_"
src="https://github.com/user-attachments/assets/c35751d5-385b-449c-81d6-14b5b6577ff2"
/>

Introduces a fully-functional demo account that lets prospective users
explore Whisper Money without creating an account. Users can click
"Check Demo" on the welcome page to instantly access a pre-populated
account with realistic financial data spanning 12 months.

## What's New

**Try Before You Sign Up**
- New "Check Demo" button on the welcome page for instant access
- Pre-configured demo account with real-world financial scenarios
- 12 months of sample transactions across multiple account types
(checking, savings, credit cards, investments)
- Pre-built automation rules, labels, and categories to showcase the
full app experience

**Demo Account Limitations**
- Demo accounts are read-only for sensitive operations (can't change
password, email, or payment settings)
- Clear messaging throughout the UI when demo restrictions apply
- Settings pages show helpful notices about demo limitations
- Automatic daily reset to maintain fresh demo experience

**Developer Experience**
- `php artisan demo:reset` command for manual resets
- Configurable via environment variables (DEMO_EMAIL, DEMO_PASSWORD,
DEMO_ENCRYPTION_KEY)
- Comprehensive test coverage for demo restrictions and data generation

## User Impact

This feature removes the friction of signing up before understanding the
product's value. Users can:
- Explore all features with realistic data
- Test automation rules and see them in action
- View charts and insights based on a year of financial activity
- Experience the full privacy-first encryption workflow
- Understand the product before committing to create an account

Perfect for demos, screenshots, documentation, and helping users make
informed decisions about whether Whisper Money fits their needs.
2026-01-07 10:58:14 +01:00
Víctor Falcón 700f9325a3 Add currency selection to user profile settings (#41) 2025-12-30 07:22:19 +01:00
Víctor Falcón 46c5b13739 feat: Implement drip email campaign system (#35)
## Summary

- Implement event-driven drip email campaign system for new user signups
- Add 5 targeted emails based on user journey (welcome, onboarding
reminder, promo code, import help, feedback)
- Configure Laravel Horizon with Redis queue for reliable job processing
- Track sent emails in `user_mail_logs` table to prevent duplicates

## Email Schedule

| Email | Timing | Condition |
|-------|--------|-----------|
| Welcome | 30 min after signup | All users |
| Onboarding Reminder | 1 day after signup | Not onboarded |
| Promo Code (FOUNDER) | 1 day after signup | Onboarded + has
transactions + not subscribed |
| Import Help | 1 day after signup | Onboarded + no transactions + not
subscribed |
| Feedback | 5 days after signup | Not subscribed |

## Architecture

```
User Registers → ScheduleDripEmailsListener
    ├─> SendWelcomeEmailJob (30 min delay)
    ├─> SendOnboardingReminderEmailJob (1 day delay)
    ├─> SendPromoCodeEmailJob (1 day delay)
    ├─> SendImportHelpEmailJob (1 day delay)
    └─> SendFeedbackEmailJob (5 days delay)
```

Each job checks conditions at execution time and either sends the email
+ logs it, or silently completes.

## Test plan

- [x] All 23 drip email tests pass
- [x] Migration creates `user_mail_logs` table
- [x] Jobs dispatch with correct delays
- [x] Emails only sent when conditions are met
- [x] Duplicate emails prevented via UserMailLog check
- [ ] Verify Horizon processes jobs in production
2025-12-30 07:22:18 +01:00
Víctor Falcón 4b5d65ba03
feat: add transaction labels feature (#24)
## Summary

Add a labeling system for transactions that differs from categories in
that labels are ephemeral and created on-the-fly when assigned (no
pre-creation required). A transaction can have multiple labels
(many-to-many relationship), and labels can be used for filtering in the
transaction table and as actions in automation rules.

<img width="1372" height="484" alt="image"
src="https://github.com/user-attachments/assets/fd342b11-dafb-44ed-b818-578e1ea856e6"
/>
<img width="1373" height="613" alt="image"
src="https://github.com/user-attachments/assets/aa5cfb8b-50b7-4101-a872-54904924f234"
/>
<img width="1035" height="594" alt="image"
src="https://github.com/user-attachments/assets/ffa946b2-b01f-496b-8cb8-ab55ab5b79ed"
/>


## Changes

### Backend (Laravel)

- Add `labels` table with user_id, name, color, and soft deletes
- Add `label_transaction` pivot table for transaction-label many-to-many
- Add `automation_rule_labels` pivot table for automation rule-label
many-to-many
- Create Label model with relationships to User, Transaction, and
AutomationRule
- Add LabelController for CRUD operations (returns JSON for on-the-fly
creation)
- Add LabelSyncController for frontend sync
- Add LabelPolicy for authorization
- Update TransactionController to handle bulk label updates
- Update AutomationRuleController to handle label actions
- Add validation for label_ids in transactions and automation rules

### Frontend (React/TypeScript)

- Add Label type and color utilities
- Add labels table to IndexedDB (Dexie version 6)
- Create label-sync service with findOrCreate functionality
- Create LabelCombobox component with multi-select and create-on-type
- Add labels column to transactions table
- Add labels filter to transaction filters
- Add bulk label assignment in bulk actions bar
- Add labels action in create automation rule dialog
- Update rule engine to include labels in evaluation results

## Testing

- 11 feature tests for label CRUD
- 3 tests for label sync
- All 241 feature tests pass

## Screenshots

N/A - UI changes can be reviewed in browser
2025-12-13 13:02:19 +01:00
Víctor Falcón c433088806
User Onboarding Flow (#23)
## Summary

Implements a complete user onboarding flow that guides new users through
setting up their account after registration.

## Features

- **Step-by-step wizard UI** with progress indicator and smooth
animations
- **E2E Encryption setup** with password strength indicator and
explanation of how encryption works
- **Account creation** supporting all account types (checking, savings,
credit card, investment, pension)
- **Category customization** with explanation of category types
(expenses, income, transfer)
- **Smart rules explanation** covering why there is no AI
auto-categorization (privacy & E2EE)
- **Transaction/balance import** based on account type
- **Sync integration** to ensure data consistency with backend

## Flow Diagram

```mermaid
flowchart TD
    A[User Registration] --> B[Welcome]

    B --> E[Encryption Explained]
    
    E --> C{Has encryption key?}

    C -->|No|F[Encryption Setup]
    C -->|Yes|G{Has Existing Accounts?}
    G -->|Yes| H[Show Existing Accounts]
    G -->|No| I[Create First Account]
    
    H --> J[Continue]
    I --> K{Account Type?}
    
    K -->|Checking/Savings/Credit Card| L[Import Transactions]
    K -->|Investment/Pension| M[Import Balances]
    
    J --> N[Category Types Explanation]
    L --> N
    M --> N
    
    N --> O[Customize Categories]
    O --> P[Smart Rules Explanation]
    P --> Q[More Accounts?]
    
    Q -->|Add More| I
    Q -->|Finish| R[Complete]
    
    R --> S[Redirect to Dashboard]
    S --> T{Subscribed?}
    T -->|No| U[Subscribe Page]
    T -->|Yes| V[Dashboard]
```

## Technical Changes

### Backend
- Added `onboarded_at` field to users table with migration
- Created `EnsureOnboardingComplete` middleware for redirect logic
- Created `OnboardingController` with index and complete actions
- Custom `RegisterResponse` to redirect new users to onboarding
- Updated `AccountController::store` to return JSON for fetch requests

### Frontend
- `OnboardingLayout` - fullscreen layout with step progress
- `useOnboardingState` hook - manages step navigation and state
- 12 step components for each onboarding screen
- Backend sync after account creation and imports

### Tests
- Feature tests for onboarding middleware
- Updated existing tests to use `onboarded()` factory state
2025-12-12 13:06:08 +01:00
Víctor Falcón 374ce0546b
Subscriptions (#15)
## Subscribe paywall
<img width="1119" height="764" alt="image"
src="https://github.com/user-attachments/assets/55367c91-f2b9-43f5-b450-75faf867bde0"
/>

## Subscribe success page
<img width="1112" height="681" alt="image"
src="https://github.com/user-attachments/assets/a923752a-d506-410e-ac66-e02b96acca20"
/>

## Manage subscription page
<img width="1221" height="705" alt="image"
src="https://github.com/user-attachments/assets/1eba1fec-7fb7-4500-8549-d8def809ddae"
/>
2025-12-06 19:09:56 +01:00
Víctor Falcón 9d57804dc5 Migrate ID's to UUIDv7 2025-11-15 21:25:33 +01:00
Víctor Falcón d5ce7a24b4 Automation rules 2025-11-10 12:08:58 +00:00
Víctor Falcón 635cde021b feat: Add financial models and seeders 2025-11-07 15:45:28 +00:00
Víctor Falcón 292297f483 E2E Encryption 2025-11-07 14:21:25 +00:00
Víctor Falcón fb140bbece Set up a fresh Laravel app 2025-11-07 12:01:36 +00:00