Add comprehensive platform administration panel

- Database: Add login_history, ai_recommendation_log tables; is_platform_owner
  column on users; subscription fields on organizations (payment_date,
  confirmation_number, renewal_date)
- Backend: New AdminAnalyticsService with platform metrics, tenant detail, and
  health score calculations (0-100 based on activity, budget, transactions,
  members, AI usage)
- Backend: Login/org-switch now records to login_history; AI recommendations
  logged to ai_recommendation_log; platform owner protected from superadmin toggle
- Frontend: 4-tab admin panel (Dashboard, Organizations, Users, Tenant Health)
  with tenant detail drawer, subscription management, health scoring visualization
- Platform owner account (admin@hoaledgeriq.com) auto-redirects to admin panel
- Seed data includes platform owner account and sample login history

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-26 08:51:39 -05:00
parent 0bd30a0eb8
commit a32d4cc179
20 changed files with 3183 additions and 317 deletions

View File

@@ -26,6 +26,9 @@ CREATE TABLE shared.organizations (
email VARCHAR(255),
tax_id VARCHAR(20),
fiscal_year_start_month INTEGER DEFAULT 1 CHECK (fiscal_year_start_month BETWEEN 1 AND 12),
payment_date DATE,
confirmation_number VARCHAR(100),
renewal_date DATE,
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW()
);
@@ -45,6 +48,7 @@ CREATE TABLE shared.users (
oauth_provider_id VARCHAR(255),
last_login_at TIMESTAMPTZ,
is_superadmin BOOLEAN DEFAULT FALSE,
is_platform_owner BOOLEAN DEFAULT FALSE,
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW()
);
@@ -86,6 +90,28 @@ CREATE TABLE shared.cd_rates (
created_at TIMESTAMPTZ DEFAULT NOW()
);
-- Login history (track logins/org-switches for platform analytics)
CREATE TABLE shared.login_history (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
user_id UUID NOT NULL REFERENCES shared.users(id) ON DELETE CASCADE,
organization_id UUID REFERENCES shared.organizations(id) ON DELETE SET NULL,
logged_in_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
ip_address VARCHAR(45),
user_agent TEXT
);
-- AI recommendation log (track AI usage per tenant)
CREATE TABLE shared.ai_recommendation_log (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
tenant_schema VARCHAR(63),
organization_id UUID REFERENCES shared.organizations(id) ON DELETE SET NULL,
user_id UUID REFERENCES shared.users(id) ON DELETE SET NULL,
recommendation_count INTEGER,
response_time_ms INTEGER,
status VARCHAR(20),
requested_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
-- Indexes
CREATE INDEX idx_user_orgs_user ON shared.user_organizations(user_id);
CREATE INDEX idx_user_orgs_org ON shared.user_organizations(organization_id);
@@ -95,3 +121,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_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);
CREATE INDEX idx_ai_rec_log_org ON shared.ai_recommendation_log(organization_id);
CREATE INDEX idx_ai_rec_log_time ON shared.ai_recommendation_log(requested_at DESC);