-- ============================================================ -- v3.4 MercadoLibre Integration -- ============================================================ -- Adds tables for external marketplace listings, orders, -- order items, and a generic sync queue. -- All tables live in the tenant DB. -- ============================================================ -- Listings published on MercadoLibre (extensible to Amazon later) CREATE TABLE IF NOT EXISTS marketplace_listings ( id SERIAL PRIMARY KEY, inventory_id INTEGER REFERENCES inventory(id), channel VARCHAR(20) NOT NULL DEFAULT 'mercadolibre', external_item_id VARCHAR(50) NOT NULL, external_status VARCHAR(30) DEFAULT 'active', external_permalink TEXT, title TEXT, meli_category_id VARCHAR(30), publish_price NUMERIC(12,2), last_sync_at TIMESTAMPTZ, sync_errors TEXT, is_active BOOLEAN DEFAULT true, created_at TIMESTAMPTZ DEFAULT NOW() ); CREATE INDEX IF NOT EXISTS idx_marketplace_listings_inventory ON marketplace_listings(inventory_id); CREATE INDEX IF NOT EXISTS idx_marketplace_listings_external ON marketplace_listings(external_item_id); CREATE UNIQUE INDEX IF NOT EXISTS idx_marketplace_listings_unique ON marketplace_listings(inventory_id, channel) WHERE is_active = true; -- Orders received from MercadoLibre CREATE TABLE IF NOT EXISTS marketplace_orders ( id SERIAL PRIMARY KEY, channel VARCHAR(20) NOT NULL DEFAULT 'mercadolibre', external_order_id VARCHAR(50) NOT NULL UNIQUE, external_status VARCHAR(30) NOT NULL, buyer_name VARCHAR(200), buyer_email VARCHAR(200), buyer_phone VARCHAR(50), buyer_nickname VARCHAR(100), shipping_address JSONB, total_amount NUMERIC(12,2), shipping_cost NUMERIC(12,2), meli_shipping_id VARCHAR(50), nexus_sale_id INTEGER REFERENCES sales(id), status VARCHAR(20) DEFAULT 'pending', notes TEXT, raw_json JSONB, created_at TIMESTAMPTZ DEFAULT NOW(), updated_at TIMESTAMPTZ DEFAULT NOW() ); CREATE INDEX IF NOT EXISTS idx_marketplace_orders_status ON marketplace_orders(status); CREATE INDEX IF NOT EXISTS idx_marketplace_orders_external ON marketplace_orders(external_order_id); -- Items inside a marketplace order CREATE TABLE IF NOT EXISTS marketplace_order_items ( id SERIAL PRIMARY KEY, marketplace_order_id INTEGER REFERENCES marketplace_orders(id) ON DELETE CASCADE, inventory_id INTEGER REFERENCES inventory(id), external_item_id VARCHAR(50), title VARCHAR(300), quantity INTEGER NOT NULL, unit_price NUMERIC(12,2), total_price NUMERIC(12,2), listing_id INTEGER REFERENCES marketplace_listings(id) ); -- Generic sync queue (reusable for future Amazon integration) CREATE TABLE IF NOT EXISTS marketplace_sync_queue ( id SERIAL PRIMARY KEY, inventory_id INTEGER REFERENCES inventory(id), channel VARCHAR(20) NOT NULL, action VARCHAR(20) NOT NULL, status VARCHAR(20) DEFAULT 'pending', payload JSONB, error_message TEXT, retry_count INT DEFAULT 0, created_at TIMESTAMPTZ DEFAULT NOW(), processed_at TIMESTAMPTZ ); CREATE INDEX IF NOT EXISTS idx_marketplace_sync_queue_pending ON marketplace_sync_queue(status, channel) WHERE status = 'pending'; -- Add source column to sales to track origin (POS, ML, Amazon, etc.) -- If the column already exists from another migration, do nothing. DO $$ BEGIN IF NOT EXISTS ( SELECT 1 FROM information_schema.columns WHERE table_name = 'sales' AND column_name = 'source' ) THEN ALTER TABLE sales ADD COLUMN source VARCHAR(30) DEFAULT 'pos'; END IF; END $$; DO $$ BEGIN IF NOT EXISTS ( SELECT 1 FROM information_schema.columns WHERE table_name = 'sales' AND column_name = 'external_order_id' ) THEN ALTER TABLE sales ADD COLUMN external_order_id VARCHAR(50); END IF; END $$;