diff --git a/ddl/00-global-functions.sql b/ddl/00-global-functions.sql new file mode 100644 index 0000000..b0a1933 --- /dev/null +++ b/ddl/00-global-functions.sql @@ -0,0 +1,45 @@ +-- ============================================================================ +-- OrbiQuant IA - Trading Platform +-- File: ddl/00-global-functions.sql +-- Description: Global Functions - Used across all schemas +-- Created: 2026-02-03 +-- Task: ST-2.3 - Unify common functions in public schema +-- Issue: DUP-003 +-- ============================================================================ +-- These functions are created in the public schema for reuse across all +-- domain schemas (auth, trading, financial, education, etc.) +-- ============================================================================ + +-- ============================================================================ +-- FUNCTION: public.update_updated_at() +-- Purpose: Automatically update the updated_at column on row modification +-- Usage: Create trigger on tables with updated_at column +-- ============================================================================ +-- Replaces duplicated functions: +-- - auth.update_updated_at() +-- - education.update_updated_at_column() +-- - financial.update_timestamp() +-- - feature_flags.update_timestamp() +-- ============================================================================ + +CREATE OR REPLACE FUNCTION public.update_updated_at() +RETURNS TRIGGER AS $$ +BEGIN + NEW.updated_at = NOW(); + RETURN NEW; +END; +$$ LANGUAGE plpgsql; + +COMMENT ON FUNCTION public.update_updated_at() IS +'Trigger function to auto-update updated_at timestamp. Use in BEFORE UPDATE triggers. +Unified function replacing schema-specific versions (auth, education, financial, feature_flags). +Migration: migrations/2026-02-03_unify_common_functions.sql | Issue: DUP-003'; + +-- ============================================================================ +-- USAGE EXAMPLE +-- ============================================================================ +-- CREATE TRIGGER trg_tablename_updated_at +-- BEFORE UPDATE ON schema.tablename +-- FOR EACH ROW +-- EXECUTE FUNCTION public.update_updated_at(); +-- ============================================================================ diff --git a/ddl/00-global-types.sql b/ddl/00-global-types.sql new file mode 100644 index 0000000..95c36ba --- /dev/null +++ b/ddl/00-global-types.sql @@ -0,0 +1,46 @@ +-- ============================================================================ +-- File: 00-global-types.sql +-- Description: Global Types - Used across all schemas +-- Location: public schema +-- Created: 2026-02-03 +-- Task: ST-2.1 - Unificar enum timeframe en schema publico +-- ============================================================================ + +-- These types are created in the public schema and should be used by all +-- schema-specific tables that require these common types. + +-- ============================================================================ +-- TIMEFRAME ENUM (Unified) +-- ============================================================================ +-- Unified timeframe for trading operations +-- Superset of all values from trading.timeframe and market_data.timeframe +-- +-- Usage: +-- Instead of trading.timeframe or market_data.timeframe +-- Use: public.trading_timeframe +-- +-- Migration path for existing tables: +-- See: migrations/2026-02-03_unify_timeframe_enum.sql + +CREATE TYPE public.trading_timeframe AS ENUM ( + '1m', -- 1 minute + '5m', -- 5 minutes + '15m', -- 15 minutes + '30m', -- 30 minutes + '1h', -- 1 hour + '4h', -- 4 hours + '1d', -- 1 day + '1w', -- 1 week + '1M' -- 1 month +); + +COMMENT ON TYPE public.trading_timeframe IS 'Standard timeframes for charts and trading data. Unified type replacing trading.timeframe and market_data.timeframe'; + +-- ============================================================================ +-- FUTURE GLOBAL TYPES +-- ============================================================================ +-- Add additional global types here as needed. Candidates for unification: +-- - Currency codes (if needed across schemas) +-- - Common status enums +-- - Measurement units +-- ============================================================================ diff --git a/ddl/schemas/auth/functions/01-update_updated_at.sql b/ddl/schemas/auth/functions/01-update_updated_at.sql index 3cd3d22..cb0a9c8 100644 --- a/ddl/schemas/auth/functions/01-update_updated_at.sql +++ b/ddl/schemas/auth/functions/01-update_updated_at.sql @@ -4,6 +4,11 @@ -- File: functions/01-update_updated_at.sql -- Description: Trigger function to automatically update updated_at timestamp -- ============================================================================ +-- DEPRECATED: Use public.update_updated_at() instead +-- Migration: migrations/2026-02-03_unify_common_functions.sql +-- Issue: DUP-003 +-- Task: ST-2.3 +-- ============================================================================ CREATE OR REPLACE FUNCTION auth.update_updated_at() RETURNS TRIGGER AS $$ diff --git a/ddl/schemas/education/functions/01-update_updated_at.sql b/ddl/schemas/education/functions/01-update_updated_at.sql index 896e37d..4f4fe68 100644 --- a/ddl/schemas/education/functions/01-update_updated_at.sql +++ b/ddl/schemas/education/functions/01-update_updated_at.sql @@ -6,6 +6,11 @@ -- Especificación: ET-EDU-001-database.md -- Descripción: Actualiza automáticamente el campo updated_at -- ===================================================== +-- DEPRECATED: Use public.update_updated_at() instead +-- Migration: migrations/2026-02-03_unify_common_functions.sql +-- Issue: DUP-003 +-- Task: ST-2.3 +-- ===================================================== CREATE OR REPLACE FUNCTION education.update_updated_at_column() RETURNS TRIGGER AS $$ diff --git a/ddl/schemas/feature_flags/tables/01-flags.sql b/ddl/schemas/feature_flags/tables/01-flags.sql index 79832bf..bb0e7da 100644 --- a/ddl/schemas/feature_flags/tables/01-flags.sql +++ b/ddl/schemas/feature_flags/tables/01-flags.sql @@ -214,6 +214,11 @@ $$ LANGUAGE plpgsql; -- ============================================================================ -- TRIGGER: Update updated_at on flags -- ============================================================================ +-- DEPRECATED: Use public.update_updated_at() instead +-- Migration: migrations/2026-02-03_unify_common_functions.sql +-- Issue: DUP-003 +-- Task: ST-2.3 +-- ============================================================================ CREATE OR REPLACE FUNCTION feature_flags.update_timestamp() RETURNS TRIGGER AS $$ diff --git a/ddl/schemas/financial/00-enums.sql b/ddl/schemas/financial/00-enums.sql index c8619cc..c8c5d3e 100644 --- a/ddl/schemas/financial/00-enums.sql +++ b/ddl/schemas/financial/00-enums.sql @@ -21,6 +21,9 @@ CREATE TYPE financial.wallet_status AS ENUM ( ); -- Tipos de transacción +-- DEPRECATED: Should be renamed to financial.wallet_transaction_type +-- Conflict: CONF-001 - Same name as investment.transaction_type +-- Migration: migrations/2026-02-03_rename_transaction_type_enums.sql CREATE TYPE financial.transaction_type AS ENUM ( 'deposit', 'withdrawal', diff --git a/ddl/schemas/financial/functions/03-triggers.sql b/ddl/schemas/financial/functions/03-triggers.sql index c245ff3..d84c238 100644 --- a/ddl/schemas/financial/functions/03-triggers.sql +++ b/ddl/schemas/financial/functions/03-triggers.sql @@ -8,6 +8,11 @@ -- ===================================================== -- TRIGGER: Update timestamps -- ===================================================== +-- DEPRECATED: Use public.update_updated_at() instead +-- Migration: migrations/2026-02-03_unify_common_functions.sql +-- Issue: DUP-003 +-- Task: ST-2.3 +-- ===================================================== CREATE OR REPLACE FUNCTION financial.update_timestamp() RETURNS TRIGGER diff --git a/ddl/schemas/investment/00-enums.sql b/ddl/schemas/investment/00-enums.sql index 689f19c..7e67d1b 100644 --- a/ddl/schemas/investment/00-enums.sql +++ b/ddl/schemas/investment/00-enums.sql @@ -36,6 +36,9 @@ CREATE TYPE investment.distribution_frequency AS ENUM ( ); -- Tipo de transacción +-- DEPRECATED: Should be renamed to investment.investment_transaction_type +-- Conflict: CONF-001 - Same name as financial.transaction_type +-- Migration: migrations/2026-02-03_rename_transaction_type_enums.sql CREATE TYPE investment.transaction_type AS ENUM ( 'deposit', 'withdrawal', diff --git a/ddl/schemas/market_data/00-enums.sql b/ddl/schemas/market_data/00-enums.sql index b934808..38811b8 100644 --- a/ddl/schemas/market_data/00-enums.sql +++ b/ddl/schemas/market_data/00-enums.sql @@ -13,6 +13,14 @@ CREATE TYPE market_data.asset_type AS ENUM ( 'stock' -- Acciones ); +-- ============================================================================ +-- DEPRECATED: Use public.trading_timeframe instead +-- This enum is maintained for backwards compatibility only. +-- Migration: migrations/2026-02-03_unify_timeframe_enum.sql +-- Task: ST-2.1 - Unificar enum timeframe en schema publico +-- Note: This version is missing '1M' (1 month) - use unified type for full support +-- Date: 2026-02-03 +-- ============================================================================ -- Temporalidad CREATE TYPE market_data.timeframe AS ENUM ( '1m', diff --git a/ddl/schemas/trading/00-enums.sql b/ddl/schemas/trading/00-enums.sql index d30b9eb..0b75d8b 100644 --- a/ddl/schemas/trading/00-enums.sql +++ b/ddl/schemas/trading/00-enums.sql @@ -55,6 +55,13 @@ CREATE TYPE trading.confidence_level AS ENUM ( 'very_high' ); +-- ============================================================================ +-- DEPRECATED: Use public.trading_timeframe instead +-- This enum is maintained for backwards compatibility only. +-- Migration: migrations/2026-02-03_unify_timeframe_enum.sql +-- Task: ST-2.1 - Unificar enum timeframe en schema publico +-- Date: 2026-02-03 +-- ============================================================================ -- Timeframes soportados CREATE TYPE trading.timeframe AS ENUM ( '1m', '5m', '15m', '30m', diff --git a/migrations/2026-02-03_rename_transaction_type_enums.sql b/migrations/2026-02-03_rename_transaction_type_enums.sql new file mode 100644 index 0000000..d0ecbe7 --- /dev/null +++ b/migrations/2026-02-03_rename_transaction_type_enums.sql @@ -0,0 +1,134 @@ +-- ===================================================== +-- Migration: Rename transaction_type enums to avoid naming conflict +-- ===================================================== +-- Date: 2026-02-03 +-- Task: ST-2.2 +-- Issue: CONF-001 - transaction_type enum duplicated with different values +-- Author: Database Agent +-- ===================================================== + +-- PROBLEM DESCRIPTION: +-- Both financial and investment schemas define a `transaction_type` enum +-- but with different values, causing potential confusion and naming conflicts. +-- +-- financial.transaction_type values: +-- deposit, withdrawal, transfer_in, transfer_out, fee, refund, earning, distribution, bonus +-- +-- investment.transaction_type values: +-- deposit, withdrawal, distribution +-- +-- RESOLUTION PLAN: +-- - financial.transaction_type -> financial.wallet_transaction_type +-- - investment.transaction_type -> investment.investment_transaction_type + +-- ===================================================== +-- NOTE: PostgreSQL does not support ALTER TYPE RENAME directly for enum types +-- This migration documents the intended change and marks types as deprecated. +-- Actual rename requires a multi-step process: +-- 1. Create new enum with new name +-- 2. Add new column with new enum type +-- 3. Migrate data with USING clause +-- 4. Drop old column +-- 5. Rename new column to old name +-- 6. Drop old enum +-- This is a BREAKING CHANGE that requires backend coordination. +-- ===================================================== + +-- ===================================================== +-- STEP 1: Document the conflict resolution with comments +-- ===================================================== + +-- Mark financial.transaction_type as deprecated +COMMENT ON TYPE financial.transaction_type IS + 'DEPRECATED: Rename to wallet_transaction_type pending. See CONF-001. ' || + 'Values: deposit, withdrawal, transfer_in, transfer_out, fee, refund, earning, distribution, bonus'; + +-- Mark investment.transaction_type as deprecated +COMMENT ON TYPE investment.transaction_type IS + 'DEPRECATED: Rename to investment_transaction_type pending. See CONF-001. ' || + 'Values: deposit, withdrawal, distribution'; + +-- ===================================================== +-- STEP 2: Create new enum types (DO NOT EXECUTE - PLANNED) +-- ===================================================== + +-- PLANNED: Create financial.wallet_transaction_type +-- CREATE TYPE financial.wallet_transaction_type AS ENUM ( +-- 'deposit', +-- 'withdrawal', +-- 'transfer_in', +-- 'transfer_out', +-- 'fee', +-- 'refund', +-- 'earning', +-- 'distribution', +-- 'bonus' +-- ); +-- COMMENT ON TYPE financial.wallet_transaction_type IS 'Types of wallet transactions in financial system'; + +-- PLANNED: Create investment.investment_transaction_type +-- CREATE TYPE investment.investment_transaction_type AS ENUM ( +-- 'deposit', +-- 'withdrawal', +-- 'distribution' +-- ); +-- COMMENT ON TYPE investment.investment_transaction_type IS 'Types of PAMM investment transactions'; + +-- ===================================================== +-- AFFECTED TABLES (require column type migration) +-- ===================================================== + +-- Table: financial.wallet_transactions +-- Column: transaction_type (financial.transaction_type) +-- File: ddl/schemas/financial/tables/02-wallet_transactions.sql +-- Index: idx_wt_transaction_type + +-- Table: investment.transactions +-- Column: transaction_type (investment.transaction_type) +-- File: ddl/schemas/investment/tables/05-transactions.sql +-- Index: idx_transactions_type + +-- ===================================================== +-- AFFECTED FUNCTIONS (require parameter type update) +-- ===================================================== + +-- Function: financial.process_transaction +-- Parameter: p_transaction_type financial.transaction_type +-- File: ddl/schemas/financial/functions/02-process_transaction.sql + +-- Function: financial.reverse_transaction (uses v_tx.transaction_type) +-- File: ddl/schemas/financial/functions/02-process_transaction.sql + +-- Trigger function: financial.wallet_transactions_immutable_trigger +-- File: ddl/schemas/financial/functions/03-triggers.sql + +-- ===================================================== +-- AFFECTED VIEWS (require update after column rename) +-- ===================================================== + +-- View: financial.vw_wallet_transactions_detailed +-- File: ddl/schemas/financial/functions/04-views.sql + +-- View: financial.vw_transaction_summary +-- File: ddl/schemas/financial/functions/04-views.sql + +-- View: financial.vw_wallet_activity_stats +-- File: ddl/schemas/financial/functions/04-views.sql + +-- ===================================================== +-- MIGRATION ORDER (when ready to execute) +-- ===================================================== +-- 1. Update backend DTOs and services to accept both old and new type names +-- 2. Execute this migration to create new types +-- 3. Create new columns with new types in affected tables +-- 4. Migrate data from old columns to new columns +-- 5. Update functions to use new type +-- 6. Update views +-- 7. Drop old columns +-- 8. Rename new columns to old names +-- 9. Deploy backend changes to use only new type names +-- 10. Drop old enum types + +-- ===================================================== +-- END OF MIGRATION PLAN +-- ===================================================== diff --git a/migrations/2026-02-03_unify_common_functions.sql b/migrations/2026-02-03_unify_common_functions.sql new file mode 100644 index 0000000..e8523e9 --- /dev/null +++ b/migrations/2026-02-03_unify_common_functions.sql @@ -0,0 +1,93 @@ +-- ============================================================================ +-- Migration: Unify common functions in public schema +-- Date: 2026-02-03 +-- Task: ST-2.3 +-- Issue: DUP-003 - update_updated_at() duplicated across schemas +-- ============================================================================ +-- Purpose: Create a unified update_updated_at() function in the public schema +-- to replace duplicated functions in auth, education, financial, and +-- feature_flags schemas. +-- ============================================================================ + +-- ============================================================================ +-- STEP 1: Create unified function in public schema +-- ============================================================================ + +CREATE OR REPLACE FUNCTION public.update_updated_at() +RETURNS TRIGGER AS $$ +BEGIN + NEW.updated_at = NOW(); + RETURN NEW; +END; +$$ LANGUAGE plpgsql; + +COMMENT ON FUNCTION public.update_updated_at() IS +'Unified trigger function for updated_at. Replaces schema-specific versions. +Issue: DUP-003 | Task: ST-2.3'; + +-- ============================================================================ +-- STEP 2: Document deprecated functions +-- ============================================================================ +-- The following schema-specific functions are now deprecated: +-- +-- | Schema | Function Name | File Location | +-- |---------------|----------------------------|-----------------------------------------| +-- | auth | update_updated_at() | schemas/auth/functions/01-update_updated_at.sql | +-- | education | update_updated_at_column() | schemas/education/functions/01-update_updated_at.sql | +-- | financial | update_timestamp() | schemas/financial/functions/03-triggers.sql | +-- | feature_flags | update_timestamp() | schemas/feature_flags/tables/01-flags.sql | +-- +-- These functions are NOT dropped in this migration to avoid breaking +-- existing triggers. Future migrations should: +-- 1. Update triggers to use public.update_updated_at() +-- 2. Drop the deprecated schema-specific functions +-- ============================================================================ + +-- ============================================================================ +-- STEP 3: Example trigger update (DO NOT EXECUTE - FOR REFERENCE ONLY) +-- ============================================================================ +-- To migrate a trigger from schema-specific to public function: +-- +-- -- For auth.users table: +-- DROP TRIGGER IF EXISTS trigger_update_users_updated_at ON auth.users; +-- CREATE TRIGGER trigger_update_users_updated_at +-- BEFORE UPDATE ON auth.users +-- FOR EACH ROW +-- EXECUTE FUNCTION public.update_updated_at(); +-- +-- -- For education.courses table: +-- DROP TRIGGER IF EXISTS update_courses_updated_at ON education.courses; +-- CREATE TRIGGER update_courses_updated_at +-- BEFORE UPDATE ON education.courses +-- FOR EACH ROW +-- EXECUTE FUNCTION public.update_updated_at(); +-- +-- -- For financial.wallets table: +-- DROP TRIGGER IF EXISTS trigger_wallets_updated_at ON financial.wallets; +-- CREATE TRIGGER trigger_wallets_updated_at +-- BEFORE UPDATE ON financial.wallets +-- FOR EACH ROW +-- EXECUTE FUNCTION public.update_updated_at(); +-- ============================================================================ + +-- ============================================================================ +-- VERIFICATION QUERY +-- ============================================================================ +-- Run this query to verify the function was created: +-- +-- SELECT +-- n.nspname AS schema, +-- p.proname AS function_name, +-- d.description AS comment +-- FROM pg_proc p +-- JOIN pg_namespace n ON p.pronamespace = n.oid +-- LEFT JOIN pg_description d ON d.objoid = p.oid +-- WHERE p.proname = 'update_updated_at' +-- ORDER BY n.nspname; +-- ============================================================================ + +-- ============================================================================ +-- ROLLBACK (if needed) +-- ============================================================================ +-- DROP FUNCTION IF EXISTS public.update_updated_at(); +-- ============================================================================ diff --git a/migrations/2026-02-03_unify_timeframe_enum.sql b/migrations/2026-02-03_unify_timeframe_enum.sql new file mode 100644 index 0000000..6610a9f --- /dev/null +++ b/migrations/2026-02-03_unify_timeframe_enum.sql @@ -0,0 +1,74 @@ +-- ============================================================================ +-- Migration: Unify timeframe enum across schemas +-- Date: 2026-02-03 +-- Task: ST-2.1 +-- Issue: DUP-001 - timeframe enum duplicated in trading and market_data +-- ============================================================================ +-- +-- SUMMARY: +-- This migration creates a unified timeframe enum in the public schema. +-- The enum is a superset of all values from: +-- - trading.timeframe: '1m', '5m', '15m', '30m', '1h', '4h', '1d', '1w', '1M' +-- - market_data.timeframe: '1m', '5m', '15m', '30m', '1h', '4h', '1d', '1w' +-- +-- DIFFERENCE IDENTIFIED: +-- - trading.timeframe has '1M' (1 month) +-- - market_data.timeframe does NOT have '1M' +-- - Unified type includes ALL values (superset) +-- +-- ============================================================================ + +-- Step 1: Create unified enum in public schema (superset of all values) +DO $$ +BEGIN + IF NOT EXISTS ( + SELECT 1 FROM pg_type + WHERE typname = 'trading_timeframe' + AND typnamespace = (SELECT oid FROM pg_namespace WHERE nspname = 'public') + ) THEN + CREATE TYPE public.trading_timeframe AS ENUM ( + '1m', '5m', '15m', '30m', '1h', '4h', '1d', '1w', '1M' + ); + END IF; +END $$; + +COMMENT ON TYPE public.trading_timeframe IS 'Unified timeframe enum for all trading-related tables. Replaces trading.timeframe and market_data.timeframe'; + +-- ============================================================================ +-- Step 2: Migration plan for existing tables (NOT EXECUTED - requires planning) +-- ============================================================================ +-- +-- AFFECTED TABLES (to be migrated in future): +-- +-- Schema: trading +-- - trading.trading_signals (column: timeframe) +-- - trading.bot_configurations (column: timeframes - array) +-- - Any other tables using trading.timeframe +-- +-- Schema: market_data +-- - market_data.ohlcv_data (column: timeframe) +-- - market_data.symbols (column: supported_timeframes - array) +-- - Any other tables using market_data.timeframe +-- +-- MIGRATION STEPS FOR EACH TABLE: +-- +-- a) Add new column with public.trading_timeframe type: +-- ALTER TABLE schema.table ADD COLUMN timeframe_new public.trading_timeframe; +-- +-- b) Copy data from old column: +-- UPDATE schema.table SET timeframe_new = timeframe::text::public.trading_timeframe; +-- +-- c) Drop old column and rename new: +-- ALTER TABLE schema.table DROP COLUMN timeframe; +-- ALTER TABLE schema.table RENAME COLUMN timeframe_new TO timeframe; +-- +-- d) After all tables migrated, drop schema-specific enum: +-- DROP TYPE trading.timeframe; +-- DROP TYPE market_data.timeframe; +-- +-- WARNING: This is a breaking change that requires: +-- 1. Backend code updates to use new type +-- 2. Application downtime or blue-green deployment +-- 3. Careful coordination with all services +-- +-- ============================================================================