Database Layer
Supabase PostgreSQL with Row Level Security, atomic RPC functions, and GDPR-compliant EU data residency.
Database Overview
EU-hosted PostgreSQL with enterprise-grade security and compliance.
Entity Relationship Diagram
Table relationships and data flow across the database schema.
Table Schemas
Detailed column definitions, types, constraints, and defaults for every table.
| Column | Type | Default | Constraints | Notes |
|---|---|---|---|---|
| id | UUID | uuid_generate_v4() | PK | |
| shop_domain | TEXT | - | UNIQUE NOT NULL | |
| shop_name | TEXT | - | ||
| access_token | TEXT | - | Encrypted in prod | |
| is_enabled | BOOLEAN | true | ||
| vat_field_required | BOOLEAN | false | ||
| required_countries | TEXT[] | '{}' | ||
| show_company_info | BOOLEAN | true | ||
| custom_error_message | TEXT | - | ||
| plan | TEXT | 'free' | CHECK | free / starter / pro / enterprise |
| monthly_validations | INTEGER | 0 | Analytics counter | |
| validations_reset_at | TIMESTAMPTZ | - | ||
| monthly_vies_calls | INTEGER | 0 | Billing counter 004 | |
| vies_calls_reset_at | TIMESTAMPTZ | - | 004 | |
| cart_enabled | BOOLEAN | true | 002 | |
| cart_required | BOOLEAN | false | 002 | |
| cart_block_checkout | BOOLEAN | false | 002 | |
| auto_exemption_enabled | BOOLEAN | true | 002 | |
| exemption_same_country | BOOLEAN | false | 002 | |
| checkout_enabled | BOOLEAN | true | 002 | |
| thankyou_enabled | BOOLEAN | true | 002 | |
| account_enabled | BOOLEAN | true | 002 | |
| account_auto_populate | BOOLEAN | true | 002 | |
| is_plus | BOOLEAN | false | 002 | |
| settings_json | JSONB | '{}' | 002 | |
| reverse_charge_enabled | BOOLEAN | true | 002 | |
| reverse_charge_note_template | TEXT | 'VAT Reverse Charge...' | 002 | |
| seller_country_code | VARCHAR(2) | NULL | 002 | |
| cart_drawer_enabled | BOOLEAN | true | 002 | |
| cart_drawer_selector | TEXT | NULL | 002 | |
| installed_at | TIMESTAMPTZ | NOW() | ||
| uninstalled_at | TIMESTAMPTZ | - | ||
| created_at | TIMESTAMPTZ | NOW() | ||
| updated_at | TIMESTAMPTZ | NOW() | Auto-trigger on update |
| Column | Type | Constraints | Notes |
|---|---|---|---|
| id | UUID | PK | |
| shop_id | UUID | FK → shops(id) CASCADE | |
| vat_number | TEXT | NOT NULL | |
| country_code | CHAR(2) | NOT NULL | |
| vat_number_formatted | TEXT | With country prefix | |
| is_valid | BOOLEAN | NOT NULL | |
| validation_source | TEXT | CHECK | vies / cache / format_only |
| company_name | TEXT | From VIES response | |
| company_address | TEXT | From VIES response | |
| order_id | TEXT | ||
| checkout_token | TEXT | ||
| customer_id | TEXT | Numeric string | |
| customer_email | TEXT | ||
| ip_address | INET | ||
| error_code | TEXT | ||
| error_message | TEXT | ||
| surface | TEXT | CHECK | cart / checkout / thank_you / account / api 002 |
| validated_at | TIMESTAMPTZ | DEFAULT NOW() | |
| created_at | TIMESTAMPTZ | DEFAULT NOW() |
| Column | Type | Constraints | Notes |
|---|---|---|---|
| id | UUID | PK | |
| vat_number | TEXT | UNIQUE NOT NULL | |
| country_code | CHAR(2) | NOT NULL | |
| is_valid | BOOLEAN | NOT NULL | |
| company_name | TEXT | ||
| company_address | TEXT | ||
| cached_at | TIMESTAMPTZ | DEFAULT NOW() | |
| expires_at | TIMESTAMPTZ | DEFAULT NOW() + 24h |
| Column | Type | Constraints | Notes |
|---|---|---|---|
| id | UUID | PK | |
| shop_id | UUID | FK → shops(id) CASCADE | |
| customer_id | TEXT | NOT NULL | |
| vat_number | TEXT | NOT NULL | |
| country_code | CHAR(2) | NOT NULL | |
| company_name | TEXT | ||
| is_valid | BOOLEAN | DEFAULT true | |
| last_validated_at | TIMESTAMPTZ | ||
| created_at | TIMESTAMPTZ | ||
| updated_at | TIMESTAMPTZ | ||
| UNIQUE(shop_id, customer_id) | |||
| Column | Type | Constraints | Notes |
|---|---|---|---|
| id | UUID | PK | |
| shop_id | UUID | FK → shops(id) CASCADE | |
| topic | TEXT | NOT NULL | |
| order_id | TEXT | 005 | |
| payload | JSONB | ||
| processed | BOOLEAN | DEFAULT false | |
| processed_at | TIMESTAMPTZ | ||
| error | TEXT | ||
| created_at | TIMESTAMPTZ | DEFAULT NOW() | |
| UNIQUE INDEX on (order_id, topic) WHERE order_id IS NOT NULL 005 | |||
| Column | Type | Constraints | Notes |
|---|---|---|---|
| id | TEXT | PK | |
| shop | TEXT | NOT NULL | |
| state | TEXT | ||
| is_online | BOOLEAN | DEFAULT false | |
| scope | TEXT | ||
| access_token | TEXT | ||
| expires_at | TIMESTAMPTZ | ||
| online_access_info | JSONB | ||
| created_at | TIMESTAMPTZ | ||
| updated_at | TIMESTAMPTZ |
Migrations
Incremental database migrations tracking schema changes across development phases.
RPC Functions
Atomic PostgreSQL functions for cache management, counter incrementing, and scheduled maintenance.
Indexes
14 carefully designed indexes optimizing lookups, filtering, and composite queries across all tables.
Row Level Security
Every table has RLS enabled with service_role bypass for backend access.
Scheduled Jobs
pg_cron jobs for automated cache cleanup and counter resets.
Metafields
App-owned metafields for persisting VAT data on Shopify entities.