create type "delivery_type_enum" as enum ('hand_shipped', 'easypost', 'hand_delivered'); create type "transaction_state_enum" as enum ('started', 'completed', 'cancelled', 'expired'); create type "payment_state_enum" as enum ('ks_reward', 'stripe', 'paypal', 'account_credit'); create table "user" ( user_uuid uuid primary key default uuid_generate_v4(), user_email citext unique not null, user_email_confirmed boolean not null default false, user_password_hash varchar(60), user_time_registered timestamptz not null default now(), user_time_email_confirmed timestamptz ); create table "login_link" ( login_link_uuid uuid primary key default uuid_generate_v4(), login_link_user_uuid uuid not null references "user" (user_uuid), login_link_time_created timestamptz not null default now(), login_link_timeout_length interval not null, login_link_login_hash varchar(60) not null ); create table "cart" ( cart_uuid uuid primary key default uuid_generate_v4() ); create table "session" ( session_uuid uuid primary key default uuid_generate_v4(), session_time_created timestamptz not null default now(), session_time_last_active timestamptz not null default now(), session_timeout_length interval not null, session_ip_address varchar(50) not null, session_user_agent varchar(500) not null, session_referer varchar(500) not null, session_user_uuid uuid not null references "user" (user_uuid), session_originating_link uuid references "login_link" (login_link_uuid), session_cart uuid references "cart" (cart_uuid) ); create table "item" ( item_uuid uuid primary key default uuid_generate_v4(), item_name text not null, item_urlslug citext unique not null, item_price_cents integer not null ); create table "cart_item" ( cart_item_uuid uuid primary key default uuid_generate_v4(), cart_item_item_uuid uuid not null references "item" (item_uuid), cart_item_cart_uuid uuid not null references "cart" (cart_uuid), cart_item_count integer not null default 1, cart_item_time_added timestamptz not null default now() ); create table "address" ( address_uuid uuid primary key default uuid_generate_v4(), address_name text not null, address_company text, address_street1 text not null, address_street2 text, address_city text not null, address_state text not null, address_zip text not null, address_country text not null, address_phone text, address_easypost_id text ); create table "delivery" ( delivery_uuid uuid primary key default uuid_generate_v4(), delivery_type delivery_type_enum not null, unique (delivery_uuid, delivery_type) ); create table "delivery_hand_shipped" ( delivery_uuid uuid not null, delivery_type delivery_type_enum not null, foreign key (delivery_uuid, delivery_type) references "delivery" (delivery_uuid, delivery_type), delivery_tracking_number text not null, delivery_date_shipped timestamptz not null ); create table "delivery_easypost" ( delivery_uuid uuid not null, delivery_type delivery_type_enum not null, foreign key (delivery_uuid, delivery_type) references "delivery" (delivery_uuid, delivery_type), delivery_tracking_number text not null, delivery_date_shipped timestamptz not null, delivery_easypost_id text not null ); create table "delivery_hand_delivered" ( delivery_uuid uuid not null, delivery_type delivery_type_enum not null, foreign key (delivery_uuid, delivery_type) references "delivery" (delivery_uuid, delivery_type), delivery_description text not null, delivery_date_delivered timestamptz not null ); create table "order" ( order_uuid uuid primary key default uuid_generate_v4(), order_number int not null, order_start_time timestamptz not null default now(), order_user_uuid uuid foreign key references "user" (user_uuid), order_address_uuid uuid foreign key references "address" (address_uuid), order_delivery_uuid uuid foreign key references "delivery" (delivery_uuid) ); create table "coupon" ( coupon_uuid uuid primary key default uuid_generate_v4(), coupon_code varchar(50) unique not null, coupon_valid_until timestamptz not null, coupon_free_shipping boolean not null default false, coupon_number_allowed_uses integer not null default 1 check (coupon_number_allowed_uses > 0), coupon_flat_discount_cents integer not null default 0 check (coupon_flat_discount_cents >= 0), coupon_percent_discount integer not null default 0 check (coupon_percent_discount >= 0 and coupon_percent_discount <= 100), coupon_per_sock_discount_cents integer not null default 0 check (coupon_per_sock_discount_cents >= 0), coupon_number_of_socks_free integer not null default 0 check (coupon_number_of_socks_free >= 0) ); create table "transaction" ( transaction_uuid uuid primary key default uuid_generate_v4(), transaction_order_uuid uuid foreign key references "order" (order_uuid), transaction_cart_uuid uuid foreign key references "cart" (cart_uuid), transaction_coupon_uuid uuid foreign key references "transaction" (transaction_uuid), transaction_start_time timestamptz not null default now(), transaction_completion_time timestamptz, transaction_payment_state transaction_state_enum, not null default 'started', transaction_item_total_price integer not null, transaction_coupon_effective_discount integer not null, transaction_shipping_price integer not null ); create table "payment" ( payment_uuid uuid primary key default uuid_generate_v4(), payment_type payment_type_enum )