160 lines
5.0 KiB
SQL
Executable File
160 lines
5.0 KiB
SQL
Executable File
CREATE TABLE users (
|
|
id SERIAL PRIMARY KEY,
|
|
username VARCHAR(255) UNIQUE NOT NULL,
|
|
password TEXT NOT NULL,
|
|
created TIMESTAMPTZ,
|
|
email VARCHAR(255),
|
|
last_login TIMESTAMPTZ,
|
|
owner INTEGER
|
|
);
|
|
|
|
CREATE TABLE service_categories (
|
|
id SERIAL PRIMARY KEY,
|
|
name VARCHAR(255) NOT NULL,
|
|
description TEXT NOT NULL,
|
|
clicks_total INTEGER DEFAULT 0,
|
|
total_companies INTEGER DEFAULT 0
|
|
);
|
|
|
|
CREATE TABLE company (
|
|
id SERIAL PRIMARY KEY,
|
|
active BOOLEAN DEFAULT true,
|
|
created DATE NOT NULL DEFAULT CURRENT_DATE,
|
|
name VARCHAR(255) NOT NULL,
|
|
address VARCHAR(255),
|
|
town VARCHAR(255),
|
|
state VARCHAR(2),
|
|
phone VARCHAR(20),
|
|
owner_name VARCHAR(255),
|
|
owner_phone_number VARCHAR(20),
|
|
email VARCHAR(255),
|
|
user_id INTEGER
|
|
);
|
|
|
|
-- Counties (populated by scripts/add_county_to_db.py)
|
|
CREATE TABLE county (
|
|
id SERIAL PRIMARY KEY,
|
|
name VARCHAR(255) NOT NULL,
|
|
state VARCHAR(2) NOT NULL,
|
|
UNIQUE(name, state)
|
|
);
|
|
|
|
CREATE TABLE listings (
|
|
id SERIAL PRIMARY KEY,
|
|
company_name VARCHAR(255) NOT NULL,
|
|
is_active BOOLEAN DEFAULT true,
|
|
price_per_gallon DOUBLE PRECISION NOT NULL,
|
|
price_per_gallon_cash DOUBLE PRECISION,
|
|
note TEXT,
|
|
minimum_order INTEGER,
|
|
service BOOLEAN DEFAULT false,
|
|
bio_percent INTEGER NOT NULL,
|
|
phone VARCHAR(20),
|
|
online_ordering VARCHAR(20) NOT NULL DEFAULT 'none',
|
|
county_id INTEGER NOT NULL,
|
|
town VARCHAR(100),
|
|
url VARCHAR(255),
|
|
logo_url VARCHAR(255),
|
|
banner_url VARCHAR(255),
|
|
facebook_url VARCHAR(255),
|
|
instagram_url VARCHAR(255),
|
|
google_business_url VARCHAR(255),
|
|
user_id INTEGER NOT NULL,
|
|
created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
|
|
last_edited TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP
|
|
);
|
|
|
|
-- Oil prices (scraped from NewEnglandOil.com / MaineOil.com)
|
|
CREATE TABLE oil_prices (
|
|
id SERIAL PRIMARY KEY,
|
|
state VARCHAR(100),
|
|
zone INTEGER,
|
|
name VARCHAR(255),
|
|
price DOUBLE PRECISION,
|
|
date VARCHAR(20),
|
|
scrapetimestamp TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
|
|
company_id INTEGER,
|
|
county_id INTEGER
|
|
);
|
|
|
|
-- If the table already exists, add county_id
|
|
-- ALTER TABLE oil_prices ADD COLUMN county_id INTEGER;
|
|
|
|
-- If the table already exists, add the new columns
|
|
-- ALTER TABLE listings ADD COLUMN price_per_gallon_cash DOUBLE PRECISION;
|
|
-- ALTER TABLE listings ADD COLUMN note TEXT;
|
|
-- ALTER TABLE listings ADD COLUMN minimum_order INTEGER;
|
|
-- ALTER TABLE listings ADD COLUMN last_edited TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP;
|
|
|
|
-- If the table already exists, drop the company_id column
|
|
-- ALTER TABLE listings DROP COLUMN company_id;
|
|
|
|
CREATE TABLE stats_prices (
|
|
id SERIAL PRIMARY KEY,
|
|
state VARCHAR(2) NOT NULL,
|
|
price DOUBLE PRECISION NOT NULL,
|
|
created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP
|
|
);
|
|
|
|
-- Boiler/HVAC service companies (separate from fuel price listings)
|
|
CREATE TABLE service_listings (
|
|
id SERIAL PRIMARY KEY,
|
|
company_name VARCHAR(255) NOT NULL,
|
|
is_active BOOLEAN DEFAULT true,
|
|
twenty_four_hour BOOLEAN DEFAULT false, -- 24/7 emergency coverage
|
|
emergency_service BOOLEAN DEFAULT false, -- emergency same-day response
|
|
town VARCHAR(100),
|
|
county_id INTEGER NOT NULL,
|
|
phone VARCHAR(20),
|
|
website VARCHAR(255),
|
|
email VARCHAR(255),
|
|
description TEXT, -- short description of services offered
|
|
licensed_insured BOOLEAN DEFAULT false, -- licensed and insured
|
|
service_area VARCHAR(255), -- e.g. "All of Middlesex County", "Greater Boston"
|
|
years_experience INTEGER, -- years in business
|
|
logo_url VARCHAR(255),
|
|
banner_url VARCHAR(255),
|
|
facebook_url VARCHAR(255),
|
|
instagram_url VARCHAR(255),
|
|
google_business_url VARCHAR(255),
|
|
user_id INTEGER NOT NULL,
|
|
created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
|
|
last_edited TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP
|
|
);
|
|
|
|
-- Run this to create the table if not exists (after initial schema is deployed):
|
|
-- CREATE TABLE IF NOT EXISTS service_listings ( ... same as above ... );
|
|
|
|
-- Subscription tracking (one per company, auto-created with 1-year trial)
|
|
CREATE TABLE subscriptions (
|
|
id SERIAL PRIMARY KEY,
|
|
company_id INTEGER NOT NULL UNIQUE,
|
|
trial_start DATE NOT NULL DEFAULT CURRENT_DATE,
|
|
trial_end DATE NOT NULL DEFAULT (CURRENT_DATE + INTERVAL '1 year'),
|
|
status VARCHAR(20) NOT NULL DEFAULT 'trial',
|
|
plan VARCHAR(50),
|
|
created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP
|
|
);
|
|
|
|
-- Admin-managed site-wide banners
|
|
CREATE TABLE banners (
|
|
id SERIAL PRIMARY KEY,
|
|
message TEXT NOT NULL,
|
|
is_active BOOLEAN DEFAULT true,
|
|
created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP
|
|
);
|
|
|
|
CREATE TABLE listing_towns (
|
|
id SERIAL PRIMARY KEY,
|
|
listing_id INTEGER NOT NULL REFERENCES listings(id) ON DELETE CASCADE,
|
|
town VARCHAR(100) NOT NULL,
|
|
UNIQUE(listing_id, town)
|
|
);
|
|
|
|
CREATE TABLE service_listing_towns (
|
|
id SERIAL PRIMARY KEY,
|
|
service_listing_id INTEGER NOT NULL REFERENCES service_listings(id) ON DELETE CASCADE,
|
|
town VARCHAR(100) NOT NULL,
|
|
UNIQUE(service_listing_id, town)
|
|
);
|