SysOps config backup 2026-06-09 01:38 UTC
This commit is contained in:
@@ -0,0 +1,113 @@
|
||||
-- Retail 360: notes, media, milestones, ownership, RSS, city demographics
|
||||
|
||||
CREATE TABLE IF NOT EXISTS entity_notes (
|
||||
id SERIAL PRIMARY KEY,
|
||||
entity_type VARCHAR(32) NOT NULL,
|
||||
entity_id INTEGER NOT NULL,
|
||||
title VARCHAR(255),
|
||||
body TEXT NOT NULL,
|
||||
note_type VARCHAR(32) DEFAULT 'general',
|
||||
created_by VARCHAR(64) DEFAULT 'team',
|
||||
pinned BOOLEAN DEFAULT FALSE,
|
||||
created_at TIMESTAMPTZ DEFAULT NOW(),
|
||||
updated_at TIMESTAMPTZ DEFAULT NOW()
|
||||
);
|
||||
CREATE INDEX IF NOT EXISTS idx_entity_notes_entity ON entity_notes(entity_type, entity_id);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS entity_media (
|
||||
id SERIAL PRIMARY KEY,
|
||||
entity_type VARCHAR(32) NOT NULL,
|
||||
entity_id INTEGER NOT NULL,
|
||||
filename VARCHAR(255) NOT NULL,
|
||||
content_type VARCHAR(64) DEFAULT 'image/jpeg',
|
||||
storage_path TEXT NOT NULL,
|
||||
caption TEXT,
|
||||
created_at TIMESTAMPTZ DEFAULT NOW()
|
||||
);
|
||||
CREATE INDEX IF NOT EXISTS idx_entity_media_entity ON entity_media(entity_type, entity_id);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS sales_milestones (
|
||||
id SERIAL PRIMARY KEY,
|
||||
supermarket_id INTEGER REFERENCES supermarkets(id) ON DELETE CASCADE,
|
||||
client_id INTEGER REFERENCES clients(id) ON DELETE SET NULL,
|
||||
deal_id INTEGER REFERENCES deals(id) ON DELETE SET NULL,
|
||||
milestone_type VARCHAR(64) NOT NULL DEFAULT 'custom',
|
||||
title VARCHAR(255) NOT NULL,
|
||||
status VARCHAR(32) DEFAULT 'pending',
|
||||
target_date DATE,
|
||||
completed_at TIMESTAMPTZ,
|
||||
value_eur NUMERIC(12,2),
|
||||
notes TEXT,
|
||||
sort_order INTEGER DEFAULT 0,
|
||||
created_at TIMESTAMPTZ DEFAULT NOW()
|
||||
);
|
||||
CREATE INDEX IF NOT EXISTS idx_milestones_store ON sales_milestones(supermarket_id);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS ownership_changes (
|
||||
id SERIAL PRIMARY KEY,
|
||||
entity_type VARCHAR(32) DEFAULT 'supermarket',
|
||||
entity_id INTEGER,
|
||||
chain VARCHAR(100),
|
||||
previous_owner VARCHAR(255),
|
||||
new_owner VARCHAR(255) NOT NULL,
|
||||
change_type VARCHAR(64) DEFAULT 'acquisition',
|
||||
effective_date DATE,
|
||||
source VARCHAR(255),
|
||||
notes TEXT,
|
||||
created_at TIMESTAMPTZ DEFAULT NOW()
|
||||
);
|
||||
CREATE INDEX IF NOT EXISTS idx_ownership_chain ON ownership_changes(chain);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS city_demographics (
|
||||
id SERIAL PRIMARY KEY,
|
||||
city VARCHAR(100) NOT NULL,
|
||||
province VARCHAR(50),
|
||||
gemeente_code VARCHAR(16),
|
||||
population INTEGER,
|
||||
households INTEGER,
|
||||
avg_income NUMERIC(12,2),
|
||||
muslim_proxy_pct NUMERIC(5,2),
|
||||
data_source VARCHAR(100) DEFAULT 'cbs',
|
||||
last_updated TIMESTAMPTZ DEFAULT NOW(),
|
||||
UNIQUE(city, province)
|
||||
);
|
||||
CREATE INDEX IF NOT EXISTS idx_city_demo_city ON city_demographics(city);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS rss_feeds (
|
||||
id SERIAL PRIMARY KEY,
|
||||
name VARCHAR(128) NOT NULL UNIQUE,
|
||||
url TEXT NOT NULL,
|
||||
category VARCHAR(64) DEFAULT 'general',
|
||||
is_active BOOLEAN DEFAULT TRUE,
|
||||
last_fetch_at TIMESTAMPTZ,
|
||||
last_status VARCHAR(32)
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS rss_items (
|
||||
id SERIAL PRIMARY KEY,
|
||||
feed_id INTEGER NOT NULL REFERENCES rss_feeds(id) ON DELETE CASCADE,
|
||||
title TEXT NOT NULL,
|
||||
link TEXT,
|
||||
summary TEXT,
|
||||
published_at TIMESTAMPTZ,
|
||||
fetched_at TIMESTAMPTZ DEFAULT NOW(),
|
||||
UNIQUE(feed_id, link)
|
||||
);
|
||||
CREATE INDEX IF NOT EXISTS idx_rss_items_published ON rss_items(published_at DESC);
|
||||
|
||||
ALTER TABLE calendar_events ADD COLUMN IF NOT EXISTS supermarket_id INTEGER REFERENCES supermarkets(id) ON DELETE SET NULL;
|
||||
ALTER TABLE wholesalers ADD COLUMN IF NOT EXISTS external_id VARCHAR(64);
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS idx_wholesalers_external ON wholesalers(external_id) WHERE external_id IS NOT NULL;
|
||||
|
||||
INSERT INTO rss_feeds (name, url, category) VALUES
|
||||
('Foodlog NL', 'https://www.foodlog.nl/feed/', 'kant-en-klaar'),
|
||||
('RetailDetail', 'https://www.retaildetail.nl/feed/', 'retail'),
|
||||
('VMT Food', 'https://www.vmt.nl/feed/', 'food-industry'),
|
||||
('Nu.nl Economie', 'https://www.nu.nl/rss/Economie', 'economie'),
|
||||
('Google Halal Food NL', 'https://news.google.com/rss/search?q=halal+food+supermarkt+nederland&hl=nl&gl=NL&ceid=NL:nl', 'halal')
|
||||
ON CONFLICT (name) DO NOTHING;
|
||||
|
||||
INSERT INTO data_providers (name, provider_type, config, is_active) VALUES
|
||||
('rss_feeds', 'api', '{"type": "rss"}', true),
|
||||
('wholesale_osm', 'scrape', '{"chains": ["Sligro", "Hanos", "Makro", "Bidfood"]}', true)
|
||||
ON CONFLICT (name) DO UPDATE SET is_active = true;
|
||||
Reference in New Issue
Block a user