Phase 6: Expand market rates and enhance AI investment recommendations

- Rate fetcher now scrapes CD, Money Market, and High Yield Savings rates
  from Bankrate.com with pauses between fetches to avoid rate limiting
- Historical rate data is preserved (no longer deleted on each fetch)
- Database migration adds rate_type column and tenant ai_recommendations table
- Backend returns market rates grouped by type with latest-batch-only queries
- AI prompt now includes all three rate types for comprehensive analysis
- AI recommendations are saved per-tenant for retrieval on page load
- Frontend: "Market CD Rates" replaced with "Today's Market Rates" tabbed view
- Rates section is collapsible (expanded by default) to save screen space
- Saved recommendations load automatically with "Last Updated" timestamp

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-26 13:39:19 -05:00
parent d9bb9363dd
commit 2fed5d6ce1
7 changed files with 686 additions and 317 deletions

View File

@@ -77,7 +77,8 @@ CREATE TABLE shared.invitations (
created_at TIMESTAMPTZ DEFAULT NOW()
);
-- CD Rates (cross-tenant market data for investment recommendations)
-- Market Rates (cross-tenant market data for investment recommendations)
-- Supports CD, Money Market, and High Yield Savings rate types
CREATE TABLE shared.cd_rates (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
bank_name VARCHAR(255) NOT NULL,
@@ -85,6 +86,7 @@ CREATE TABLE shared.cd_rates (
min_deposit DECIMAL(15,2),
term VARCHAR(100) NOT NULL,
term_months INTEGER,
rate_type VARCHAR(50) NOT NULL DEFAULT 'cd',
fetched_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
source_url VARCHAR(500),
created_at TIMESTAMPTZ DEFAULT NOW()
@@ -121,6 +123,8 @@ CREATE INDEX idx_invitations_token ON shared.invitations(token);
CREATE INDEX idx_invitations_email ON shared.invitations(email);
CREATE INDEX idx_cd_rates_fetched ON shared.cd_rates(fetched_at DESC);
CREATE INDEX idx_cd_rates_apy ON shared.cd_rates(apy DESC);
CREATE INDEX idx_cd_rates_type ON shared.cd_rates(rate_type);
CREATE INDEX idx_cd_rates_type_fetched ON shared.cd_rates(rate_type, fetched_at DESC);
CREATE INDEX idx_login_history_org_time ON shared.login_history(organization_id, logged_in_at DESC);
CREATE INDEX idx_login_history_user ON shared.login_history(user_id);
CREATE INDEX idx_login_history_time ON shared.login_history(logged_in_at DESC);