From 442dac8c045b5f5c476e238c1a00bfc998a78763 Mon Sep 17 00:00:00 2001 From: Ashwin Kumar Sivakumar Date: Tue, 21 Jul 2026 02:21:52 +0530 Subject: [PATCH] fix: portfolio_items/services tables never existed; wallet ledger read used stale column names MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Continuing the migration-chain audit: professional portfolio/services management (PortfolioPage.tsx -> /api/{profession}/portfolio/me, /api/{profession}/services) was broken the same way as lead_requests — portfolio_items and services were only ever defined in a disabled .skip migration (keyed differently: user_id + profession_key, vs. the user_role_profile_id every live query in crates/db/src/models/professional.rs actually uses). Self-created both tables with the schema the live code needs, in the same already-pushed migration (20260317195000_profession_specific_profiles.up.sql) that was unconditionally ALTERing them. Also fixed TracecoinLedgerEntry (professional.rs) — its `type`/`reason` fields didn't match the `transaction_type`/`reference_type` columns TracecoinWalletRepository actually writes (see previous commit), so GET /api/{profession}/wallet/ledger would have failed to deserialize every row. professional.rs has its own duplicate, unreachable try_reserve/debit/release_tracecoins using the old type/reason names — left alone since nothing calls them (send_lead_request and friends all go through TracecoinWalletRepository). --- ...195000_profession_specific_profiles.up.sql | 36 +++++++++++++++++++ crates/db/src/models/professional.rs | 4 +-- 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/crates/db/migrations/20260317195000_profession_specific_profiles.up.sql b/crates/db/migrations/20260317195000_profession_specific_profiles.up.sql index 837965e..42db2d9 100644 --- a/crates/db/migrations/20260317195000_profession_specific_profiles.up.sql +++ b/crates/db/migrations/20260317195000_profession_specific_profiles.up.sql @@ -190,6 +190,42 @@ CREATE TABLE IF NOT EXISTS catering_service_profiles ( updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW() ); +-- Shared: portfolio_items/services — neither was ever created by any active +-- migration (only in the disabled portfolio_payments .skip migration, keyed +-- differently to boot). ProfessionalRepository (crates/db/src/models/ +-- professional.rs) exclusively queries these by user_role_profile_id, so +-- that's the schema self-created here; the legacy user_id/profession_key +-- columns below are added for backwards compatibility with this comment's +-- original (unused) design but aren't required by any current code path. +CREATE TABLE IF NOT EXISTS portfolio_items ( + id UUID PRIMARY KEY DEFAULT gen_random_uuid(), + user_role_profile_id UUID NOT NULL, + title VARCHAR(255) NOT NULL, + description TEXT, + tags TEXT[] DEFAULT '{}', + display_order INTEGER DEFAULT 0, + created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), + updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW() +); + +CREATE TABLE IF NOT EXISTS services ( + id UUID PRIMARY KEY DEFAULT gen_random_uuid(), + user_role_profile_id UUID NOT NULL, + name VARCHAR(255) NOT NULL, + description TEXT, + price INTEGER NOT NULL DEFAULT 0, + duration_minutes INTEGER, + is_active BOOLEAN NOT NULL DEFAULT true, + created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), + updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW() +); + +ALTER TABLE portfolio_items ADD COLUMN IF NOT EXISTS user_role_profile_id UUID; +ALTER TABLE services ADD COLUMN IF NOT EXISTS user_role_profile_id UUID; + +CREATE INDEX IF NOT EXISTS idx_portfolio_items_user_role_profile_id ON portfolio_items(user_role_profile_id); +CREATE INDEX IF NOT EXISTS idx_services_user_role_profile_id ON services(user_role_profile_id); + -- Shared: portfolio_items now uses user_id + profession_key (no foreign key to professionals) -- Drop the professionals-table FK if it was added before ALTER TABLE portfolio_items diff --git a/crates/db/src/models/professional.rs b/crates/db/src/models/professional.rs index 74ab5b6..b674700 100644 --- a/crates/db/src/models/professional.rs +++ b/crates/db/src/models/professional.rs @@ -53,9 +53,9 @@ pub struct Wallet { pub struct TracecoinLedgerEntry { pub id: Uuid, pub wallet_id: Uuid, - pub r#type: String, + pub transaction_type: String, pub amount: i32, - pub reason: String, + pub reference_type: Option, pub reference_id: Option, pub created_at: DateTime, }