Lifehub PWA — Implementation Guide
Complete technical documentation for the Lifehub Family Finance Management module, implemented across 3 phases inside the Lifehub on Steroids Rails 8.1.2 platform.
Table of Contents
- Architecture Overview
- Database Schema
- Phase 1: Accounts, Expenses & Balance Registry
- Phase 2: Investments, Goals & Liquidity
- Phase 3: Analytics, Simulator, Planning & Settings
- Dashboard
- Navigation
- Stimulus Controllers
- Helpers
- Internationalization
- Design System
- Testing
- Metrics
Architecture Overview
Multi-Tenant Model
Lifehub operates within the existing organization-based multi-tenancy system:
User → Membership (admin | member) → Organization ("Family")
├── Accounts
├── Expenses
├── Balance Registries
├── Investments
└── Goals
Every financial resource follows the pattern:
belongs_to :organization # Tenant scope
belongs_to :membership # Creator audit trail (optional for shared resources)
Business Logic Pattern
Complex calculations live in namespaced model classes (not service objects):
Account::BalanceCalculator # Account balance aggregation
Expense::SummaryCalculator # Expense summaries and breakdowns
Investment::PerformanceCalculator # Portfolio performance
Goal::ProgressCalculator # Goal progress tracking
Liquidity::Analyzer # Emergency fund health analysis
Organization::AnalyticsCalculator # Cross-model analytics
Dashboard::DataAggregator # KPI aggregation from all calculators
Request Flow
Request → Organizations::BaseController (set org + membership)
→ Feature Controller (authorize via Pundit)
→ Calculator/Model (business logic)
→ View (Tailwind + Stimulus + Chart.js)
Database Schema
Migrations
| Migration | Phase | Purpose |
|---|---|---|
20260219220318_create_accounts.rb |
1 | Accounts table |
20260219220531_create_expenses.rb |
1 | Expenses table |
20260219220536_create_balance_registries.rb |
1 | Balance snapshots |
20260219220541_add_finance_fields_to_organizations.rb |
1 | Exchange rate + finance_settings JSON |
20260219224824_create_investments.rb |
2 | Investments table |
20260219224825_create_goals.rb |
2 | Goals table |
Tables
accounts
| Column | Type | Details |
|——–|——|———|
| name | string | NOT NULL, unique per org |
| bank | string | NOT NULL — institution name |
| account_type | string | enum: bank, broker, international |
| currency | string | enum: BRL, USD |
| balance | decimal(15,2) | Default: 0.0 |
| color | string | Hex color for UI |
| monthly_history | json | Array of {month, balance} snapshots |
| position | integer | acts_as_list ordering |
| organization_id | FK | NOT NULL |
| membership_id | FK | Creator (nullable for shared) |
Indexes: [org_id, name] unique, [org_id, account_type], [org_id, position]
expenses
| Column | Type | Details |
|——–|——|———|
| description | string | NOT NULL |
| amount | decimal(12,2) | NOT NULL, > 0 |
| date | date | NOT NULL |
| category | string | enum: moradia, alimentacao, educacao, saude, transporte, lazer, impostos, investimentos, vestuario, tecnologia, outros |
| expense_type | string | enum: one_time, fixed_recurring, variable_recurring |
| monthly_values | json | Hash of {month => amount} for recurring |
| observation | text | Optional notes |
| account_id | FK | Optional linked account |
| organization_id | FK | NOT NULL |
| membership_id | FK | Creator |
Indexes: [org_id, category], [org_id, date], [org_id, expense_type]
balance_registries
| Column | Type | Details |
|——–|——|———|
| date | date | NOT NULL |
| balances | json | Array of {account_id, name, balance} snapshots |
| note | text | Optional |
| organization_id | FK | NOT NULL |
| membership_id | FK | Creator |
Indexes: [org_id, date]
investments
| Column | Type | Details |
|——–|——|———|
| name | string | NOT NULL, unique per org |
| investment_type | string | enum: stocks, bonds, funds, crypto, real_estate, fixed_income, other |
| currency | string | enum: BRL, USD |
| shares | decimal(15,6) | Default: 0.0 |
| average_price | decimal(15,2) | Per-share cost basis |
| current_price | decimal(15,2) | Latest price |
| ticker | string | Optional ticker symbol |
| institution | string | Brokerage name |
| purchase_date | date | When acquired |
| dividends | json | Array of {date, amount} |
| price_history | json | Array of {date, price} |
| color | string | Hex color |
| notes | text | Optional |
| account_id | FK | Optional linked account |
| organization_id | FK | NOT NULL |
| membership_id | FK | Creator |
Indexes: [org_id, investment_type], [org_id, name] unique
goals
| Column | Type | Details |
|——–|——|———|
| name | string | NOT NULL |
| goal_type | string | enum: emergency, retirement, travel, education, home, vehicle, custom |
| status | string | enum: active, paused, completed |
| currency | string | enum: BRL, USD |
| target_amount | decimal(15,2) | NOT NULL, > 0 |
| current_amount | decimal(15,2) | Default: 0.0 |
| deadline | date | Optional target date |
| icon | string | Emoji icon (🎯, 🏖️, 🎓, etc.) |
| color | string | Hex color |
| contributions | json | Array of {date, amount, note} |
| notes | text | Optional |
| organization_id | FK | NOT NULL |
| membership_id | FK | Creator |
Indexes: [org_id, goal_type], [org_id, status]
organizations (added columns)
| Column | Type | Details |
|——–|——|———|
| exchange_rate | decimal(8,4) | Default: 5.87 (BRL/USD) |
| exchange_rate_updated_at | datetime | Last update timestamp |
| finance_settings | json | Feature settings (categories, defaults, etc.) |
Phase 1: Accounts, Expenses & Balance Registry
Models
Account (app/models/account.rb — 112 lines)
Key features:
- Enums:
account_type(bank/broker/international),currency(BRL/USD) - acts_as_list: Drag-and-drop ordering scoped to organization
- COLORS constant: 12 preset hex colors for UI differentiation
- monthly_history: JSON array tracking balance changes over time
- Normalization:
normalizes :namewith strip + titleize
# Key associations
belongs_to :organization
belongs_to :membership, optional: true
has_many :expenses, dependent: :nullify
has_many :investments, dependent: :nullify
Account::BalanceCalculator (app/models/account/balance_calculator.rb — 63 lines)
Aggregates balance data across all organization accounts:
total_balance_brl— Sum of BRL account balancestotal_balance_usd— Sum of USD account balancestotal_balance_in_brl— All balances converted to BRL using exchange ratebalance_by_type— Hash of{type => total}for chart dataaccounts_count— Total number of accounts
Expense (app/models/expense.rb — 114 lines)
Key features:
- 11 categories: moradia, alimentacao, educacao, saude, transporte, lazer, impostos, investimentos, vestuario, tecnologia, outros
- 3 expense types: one_time, fixed_recurring, variable_recurring
- monthly_values: JSON hash for recurring expense value tracking by month
- Account linking: Optional
belongs_to :account
Expense::SummaryCalculator (app/models/expense/summary_calculator.rb — 69 lines)
Computes expense analytics:
monthly_total— Total expenses for current monthrecurring_total— Sum of all recurring expensescategory_breakdown— Hash of{category => total}for chartsmonth_over_month_change— Percentage change from previous month
BalanceRegistry (app/models/balance_registry.rb — 72 lines)
Monthly snapshots:
balancesJSON captures all account states at a point in time- Creates audit trail for historical balance tracking
- Used by analytics for patrimony evolution charts
Controllers
AccountsController (87 lines)
- Full CRUD with
update_positionscollection action for drag-and-drop params.expect(account: [...])for strong params- Turbo Stream support for modal CRUD
ExpensesController (84 lines)
- Full CRUD with category and type filtering
- Account association in form
BalanceRegistriesController (78 lines)
- Full CRUD for snapshot management
- Auto-populates current account balances on new
Views
- Accounts index (49 lines): Summary cards grouped by account type, color-coded account cards with balance display
- Expenses index (79 lines): Monthly summary banner, expense list with category icons/colors, filterable by category and type
- Balance Registries index (71 lines): Timeline view of monthly snapshots
- Forms: Account form (66L), Expense form (66L), Balance Registry form (59L)
- Show/Edit: Modal-compatible via Turbo Frames
Phase 2: Investments, Goals & Liquidity
Models
Investment (app/models/investment.rb — 90 lines)
Key features:
- 7 investment types: stocks, bonds, funds, crypto, real_estate, fixed_income, other
- Price tracking:
average_price,current_price,price_historyJSON - Dividends: JSON array of
{date, amount}entries - Computed properties:
total_value,total_profit,profit_percentage - COLORS constant: 12 preset colors
def total_value
shares * current_price
end
def total_profit
total_value - (shares * average_price)
end
def profit_percentage
return 0.0 if average_price.zero?
((current_price - average_price) / average_price * 100).round(2)
end
Investment::PerformanceCalculator (app/models/investment/performance_calculator.rb — 69 lines)
Portfolio-level analytics:
total_invested— Sum of allshares * average_pricetotal_current_value— Sum of allshares * current_pricetotal_profit— Difference (current - invested)profit_percentage— Overall portfolio returnallocation_by_type— Hash for donut chart datatop_performers— Sorted by profit percentage
Goal (app/models/goal.rb — 116 lines)
Key features:
- 7 goal types: emergency, retirement, travel, education, home, vehicle, custom
- Status lifecycle: active → paused → completed (with
toggle_status) - Contributions: JSON array tracking individual contributions with dates and notes
- ICONS constant: 8 emoji icons (🎯, 🏖️, 🎓, 🏠, 🚗, 💰, 🏦, ⭐)
- Computed properties:
progress_percentage,remaining_amount,on_track?
def contribute!(amount, note: nil)
self.current_amount += amount.to_d
contributions << { date: Date.current.to_s, amount: amount.to_f, note: note }
save!
end
Goal::ProgressCalculator (app/models/goal/progress_calculator.rb — 58 lines)
Goal progress analytics:
overall_progress— Weighted average across all active goalsactive_goals_count— Number of in-progress goalscompleted_goals_count— Number of finished goalstotal_saved— Sum of current_amount across all goalstotal_target— Sum of target_amount across all goals
Liquidity::Analyzer (app/models/liquidity/analyzer.rb — 179 lines)
Emergency fund health check — the most complex calculator:
- Inputs: Monthly expenses, available liquid assets (bank + savings accounts)
- Outputs:
months_covered— How many months of expenses the reserve coversideal_reserve— Target amount (6 months of expenses)current_reserve— Available liquid assetsgap_amount— Difference between ideal and currenthealth_status—:healthy(6+mo),:warning(3-6mo),:critical(<3mo),:no_reserverecommendations— Array of actionable advice stringsmonthly_savings_needed— Required monthly savings to reach ideal in 12 months
Controllers
InvestmentsController (91 lines)
- Full CRUD with portfolio value in index
- Form handles complex investment attributes
GoalsController (114 lines)
- Full CRUD +
contributemember action +toggle_statusmember action - Contribution amount/note handling in separate action
LiquidityController (11 lines)
- Index-only (read-only analysis dashboard)
- Instantiates
Liquidity::Analyzerwith org data
Views
- Investments index (72 lines): Portfolio summary banner, investment cards with profit/loss coloring, allocation chart
- Investment show (85 lines): Detailed investment view with price history, dividends, performance metrics
- Goals index (53 lines): Progress overview summary, goal cards with progress bars
- Goal show (125 lines): Detailed goal view with contribution form, contribution history, progress visualization
- Liquidity index (105 lines): Health status gauge, months coverage indicator, gap analysis, recommendations panel
Phase 3: Analytics, Simulator, Planning & Settings
Models
Organization::AnalyticsCalculator (app/models/organization/analytics_calculator.rb — 236 lines)
The most comprehensive calculator, aggregating data from all financial models:
- Net Worth: Total assets (accounts + investments) minus liabilities
- Expense Analysis: Category breakdown, monthly trends, recurring ratio
- Investment Returns: Portfolio performance, best/worst performers
- Goals Summary: Overall progress, active/completed counts
- Patrimony Evolution: Monthly time series from balance registries
- Monthly Comparison: Current vs previous month across all metrics
Dashboard::DataAggregator (app/models/dashboard/data_aggregator.rb — 94 lines)
Orchestrates all calculators into a single KPI hash:
def kpis
{
total_balance_brl: balance_calculator.total_balance_brl,
total_balance_usd: balance_calculator.total_balance_usd,
total_balance_in_brl: balance_calculator.total_balance_in_brl,
monthly_expenses: expense_calculator.monthly_total,
recurring_expenses: expense_calculator.recurring_total,
exchange_rate: organization.exchange_rate,
accounts_count: balance_calculator.accounts_count,
expenses_count: organization.expenses.count,
investments_value: performance_calculator.total_current_value,
investments_profit: performance_calculator.total_profit,
goals_progress: progress_calculator.overall_progress,
goals_active: progress_calculator.active_goals_count
}
end
Also provides chart data methods:
expense_by_category_chart— Donut chart databalance_by_type_chart— Bar chart dataexpense_evolution_chart— Line chart time seriesbalance_evolution_chart— Area chart time series
Controllers
AnalyticsController (11 lines)
def index
authorize :analytics, :index?
@calculator = Organization::AnalyticsCalculator.new(@organization)
end
SimulatorController (13 lines)
- Passes organization data and exchange rate to view
- All simulation logic lives in Stimulus controller (client-side)
PlanningController (42 lines)
- Provides current patrimony and monthly expenses to view
- Preset definitions (car, property, travel) with default values
- All impact calculation in Stimulus controller (client-side)
FinanceSettingsController (40 lines)
- Show + Update actions
- Admin-only (Pundit policy restricts to admin role)
- Manages exchange rate and finance_settings JSON
DashboardController (21 lines)
- Instantiates
Dashboard::DataAggregator - Supports view mode toggle (compact/expanded)
Views
Dashboard (app/views/organizations/dashboard/index.html.erb — 206 lines)
The main financial overview:
- Patrimony Banner: Blue gradient (
linear-gradient(135deg, #1b3a8a → #1d4ed8)), shows total patrimony in BRL, with BRL/USD/exchange rate pills - 4 KPI Trend Cards: Monthly Growth (emerald), Total Invested (blue), Goals Progress (purple), Accounts (amber) — each with colored icon box
- Patrimony Evolution Chart: Full-width area chart showing balance over time
- 3-Column Bottom Row:
- Category distribution donut chart
- Account type bar chart
- Quick links navigation panel
Analytics (app/views/organizations/analytics/index.html.erb — 191 lines)
- 4 KPI Cards: Net Worth (emerald), Monthly Expenses (blue), Investment Returns (purple), Goals Progress (amber)
- Expense Trend Chart: Line chart showing monthly expense evolution
- Category Distribution: Donut chart of expense categories
- Monthly Comparison: Table comparing current vs previous month
Simulator (app/views/organizations/simulator/index.html.erb — 144 lines)
- Parameter Panel: Calculator icon header, 4 range sliders (initial amount, monthly contribution, annual rate, period in years)
- Results Panel: 4 emoji KPI cards (💎 Final Value, 💰 Total Invested, 📈 Total Interest, 🏆 Gain Ratio)
- Growth Chart: Area chart showing compound growth over time
- Yearly Table: Year-by-year breakdown of invested vs total
Planning (app/views/organizations/planning/index.html.erb — 167 lines)
- 2×2 Preset Grid: Car (blue), Property (emerald), Travel (amber), Custom (purple) — with colored icon boxes
- Patrimony Impact Banner: Shows current patrimony with inline gradient style
- Parameters Form: Purchase value, down payment, installments, interest rate
- Impact Analysis: Shows how purchase affects patrimony timeline
Finance Settings (app/views/organizations/finance_settings/show.html.erb — 169 lines)
- Profile Section: Gradient avatar circle (blue→purple), user email, org name
- Exchange Rate: Current rate display, manual update form
- Category Settings: Enable/disable expense categories
- Preferences: Currency display preferences
Dashboard
Data Flow
DashboardController
└── Dashboard::DataAggregator.new(@organization)
├── Account::BalanceCalculator.new(accounts)
├── Expense::SummaryCalculator.new(expenses)
├── Investment::PerformanceCalculator.new(investments)
└── Goal::ProgressCalculator.new(goals)
KPIs Available
| KPI | Source | Display |
|---|---|---|
| Total Patrimony (BRL) | BalanceCalculator | Gradient banner |
| Total Balance (USD) | BalanceCalculator | Banner pill |
| Exchange Rate | Organization | Banner pill |
| Monthly Growth | ExpenseSummary delta | Trend card (emerald) |
| Total Invested | PerformanceCalculator | Trend card (blue) |
| Goals Progress | ProgressCalculator | Trend card (purple) |
| Accounts Count | BalanceCalculator | Trend card (amber) |
Navigation
Sidebar (Desktop — _sidebar_links.html.erb)
Order matches Figma design:
- Dashboard
- Accounts
- Investments
- Expenses
- Liquidity
- Simulator
- Analytics
- Goals
- Planning
- (divider)
- Settings
Bottom Nav (Mobile — _footer_nav.html.erb)
5 items matching Figma:
- Dashboard →
organization_dashboard_path - Expenses →
organization_expenses_path - Investments →
organization_investments_path - Analytics →
organization_analytics_path - Profile →
edit_user_registration_path
Active State Detection
Uses is_active_link? helper in ApplicationHelper to highlight current nav item based on controller/action matching.
Stimulus Controllers
chart_controller.js (93 lines)
Universal Chart.js wrapper:
- Targets:
canvas(the<canvas>element) - Values:
type(line/bar/doughnut),data(JSON),options(JSON) - Handles dark mode colors, responsive sizing, animation
- Destroys chart on disconnect to prevent memory leaks
<canvas data-controller="chart"
data-chart-type-value="doughnut"
data-chart-data-value="<%= @chart_data.to_json %>"
data-chart-options-value="<%= @chart_options.to_json %>">
</canvas>
simulator_controller.js (269 lines)
Client-side compound interest calculator:
- Inputs: Initial amount, monthly contribution, annual rate, period
- Outputs: Final value, total invested, total interest, gain ratio
- Real-time recalculation on slider/input change
- Updates chart via chart_controller integration
- Formats values in BRL using Intl.NumberFormat
planning_controller.js (267 lines)
Purchase impact analyzer:
- Presets: Car (R$80k), Property (R$500k), Travel (R$15k), Custom
- Inputs: Purchase value, down payment %, installments, interest rate
- Outputs: Monthly payment, total cost, patrimony impact timeline
- Loads preset values on button click
- Updates impact visualization in real-time
Helpers
FinanceHelper (app/helpers/finance_helper.rb — 172 lines)
Currency and formatting utilities used across all finance views:
format_brl(value) # "R$ 1.234,56"
format_usd(value) # "$ 1,234.56"
format_currency(value, cur) # Dispatches to format_brl or format_usd
expense_category_label(cat) # "Moradia", "Alimentação", etc.
expense_category_color(cat) # "#EF4444" (red for moradia), etc.
expense_category_icon(cat) # "🏠" (house for moradia), etc.
account_type_label(type) # "Banco", "Corretora", "Internacional"
investment_type_label(type) # "Ações", "Fundos", "Crypto", etc.
profit_loss_color(value) # "text-emerald-400" or "text-red-400"
profit_loss_sign(value) # "+" or "" (minus is inherent)
goal_type_label(type) # "Emergência", "Viagem", etc.
goal_status_badge(status) # CSS class for active/paused/completed
Internationalization
Locale Files
config/locales/finance.en.yml(379 lines)config/locales/finance.pt-BR.yml(379 lines)
Structure
en:
finance:
nav: # Sidebar navigation labels
dashboard: # Dashboard KPIs and labels
accounts: # Account CRUD labels
expenses: # Expense CRUD + category labels
balance_registries: # Snapshot labels
investments: # Investment CRUD + type labels
goals: # Goal CRUD + type/status labels
liquidity: # Analyzer labels + recommendations
analytics: # Analytics page labels
simulator: # Simulator parameters and results
planning: # Planning presets and impact labels
finance_settings: # Settings page labels
shared: # Shared finance UI elements
Categories (11)
| Key | English | Portuguese |
|---|---|---|
| moradia | Housing | Moradia |
| alimentacao | Food | Alimentação |
| educacao | Education | Educação |
| saude | Health | Saúde |
| transporte | Transport | Transporte |
| lazer | Leisure | Lazer |
| impostos | Taxes | Impostos |
| investimentos | Investments | Investimentos |
| vestuario | Clothing | Vestuário |
| tecnologia | Technology | Tecnologia |
| outros | Others | Outros |
Design System
Figma Alignment
All views were aligned with the Figma Make file (key: nZWUxByTWE7DHjqmB8bTyf) using the Figma MCP integration.
Color Palette
| Token | Value | Usage |
|---|---|---|
| Page background | #0d1117 |
bg-[#0d1117] |
| Card background | #161b22 |
bg-[#161b22] |
| Primary | #3b82f6 |
Blue-500, buttons, links |
| Gradient start | #1b3a8a |
Patrimony banner left |
| Gradient end | #1d4ed8 |
Patrimony banner right |
KPI Icon Color System
| Color | Token | Hex | Usage |
|---|---|---|---|
| Emerald | bg-emerald-100 / text-emerald-600 |
#10b981 |
Growth, positive metrics |
| Blue | bg-blue-100 / text-blue-600 |
#3b82f6 |
Investment, neutral metrics |
| Purple | bg-purple-100 / text-purple-600 |
#8b5cf6 |
Goals, progress metrics |
| Amber | bg-amber-100 / text-amber-600 |
#f59e0b |
Accounts, warning metrics |
Component Patterns
Card: rounded-2xl p-5 bg-[#161b22]
Inner element: rounded-xl
Icon box: w-10 h-10 rounded-xl bg-{color}-100 flex items-center justify-center
Gradient: style="background: linear-gradient(135deg, #1b3a8a 0%, #1e3a8a 40%, #1d4ed8 100%)"
Testing
Test Suite Structure
test/
├── models/
│ ├── account_test.rb (121 lines)
│ ├── expense_test.rb (137 lines)
│ ├── balance_registry_test.rb (82 lines)
│ ├── investment_test.rb (183 lines)
│ └── goal_test.rb (203 lines)
├── controllers/organizations/
│ ├── accounts_controller_test.rb (101 lines)
│ ├── expenses_controller_test.rb (91 lines)
│ ├── balance_registries_controller_test.rb (82 lines)
│ ├── investments_controller_test.rb (105 lines)
│ ├── goals_controller_test.rb (143 lines)
│ ├── liquidity_controller_test.rb (29 lines)
│ ├── analytics_controller_test.rb (48 lines)
│ ├── simulator_controller_test.rb (42 lines)
│ ├── planning_controller_test.rb (55 lines)
│ └── finance_settings_controller_test.rb (106 lines)
└── integration/
└── accessible_views_test.rb (55 tests)
Test Coverage
| Category | Tests | Assertions |
|---|---|---|
| Model tests (5 models) | ~150 | ~400 |
| Controller tests (10 controllers) | ~200 | ~500 |
| Integration (accessible views) | 55 | 128 |
| Other (existing platform) | ~97 | ~191 |
| Total | 502 | 1219 |
What's Tested
Models:
- Validations (presence, numericality, uniqueness, inclusion)
- Associations (belongs_to, has_many, through)
- Enums (all values, default values)
- Scopes (filtering, ordering)
- Calculator classes (aggregation, computation accuracy)
- Business methods (contribute!, toggle_status, progress_percentage)
- Edge cases (zero values, nil handling, currency conversion)
Controllers:
- Authentication (redirect when signed out)
- Authorization (admin vs member access)
- CRUD operations (create, read, update, delete)
- Custom actions (contribute, toggle_status, update_positions)
- Turbo Stream responses
- Parameter handling
Integration:
- All 11 index routes accessible by admin
- All 11 index routes accessible by member (except admin-only settings)
- All 5 show routes accessible
- Authentication required on all routes
- Organization isolation (can't access other org)
- Turbo Frame support on show pages
- Navigation structure (sidebar links, bottom nav)
- Content rendering (KPI cards, charts, forms)
Running Tests
# Full suite
bin/rails test
# Phase 1 tests
bin/rails test test/models/account_test.rb test/models/expense_test.rb test/models/balance_registry_test.rb test/controllers/organizations/accounts_controller_test.rb test/controllers/organizations/expenses_controller_test.rb test/controllers/organizations/balance_registries_controller_test.rb
# Phase 2 tests
bin/rails test test/models/investment_test.rb test/models/goal_test.rb test/controllers/organizations/investments_controller_test.rb test/controllers/organizations/goals_controller_test.rb test/controllers/organizations/liquidity_controller_test.rb
# Phase 3 tests
bin/rails test test/controllers/organizations/analytics_controller_test.rb test/controllers/organizations/simulator_controller_test.rb test/controllers/organizations/planning_controller_test.rb test/controllers/organizations/finance_settings_controller_test.rb
# Accessible views
bin/rails test test/integration/accessible_views_test.rb
Metrics
Code Size
| Layer | Files | Total Lines |
|---|---|---|
| Models | 12 | 1,272 |
| Controllers | 11 | 592 |
| Views | 36 | 2,362 |
| Stimulus JS | 3 | 629 |
| Helpers | 1 | 172 |
| Locales | 2 | 758 |
| Tests | 16 | ~1,528 |
| Total | 81 | ~7,313 |
Route Count
| Type | Count |
|---|---|
| CRUD routes (accounts, expenses, balance_registries, investments, goals) | ~35 |
| Custom routes (contribute, toggle_status, update_positions) | 3 |
| Read-only routes (liquidity, analytics, simulator, planning) | 4 |
| Settings route | 2 (show + update) |
| Dashboard + view mode toggle | 2 |
| Total finance routes | ~46 |
Version: 1.0 Last Updated: June 2025