375 lines
13 KiB
SQL
375 lines
13 KiB
SQL
-- 100kmph MariaDB schema (Drift tablet schema version 6, snake_case).
|
|
-- Apply as an admin user. The app user has no DDL and no DELETE.
|
|
-- Synced rows are soft-deleted via deleted_at. Do not hard-delete them.
|
|
-- No foreign keys: the tablet may push children before parents.
|
|
|
|
CREATE TABLE IF NOT EXISTS staff_members (
|
|
id CHAR(36) NOT NULL,
|
|
name VARCHAR(255) NOT NULL,
|
|
pin_hash VARCHAR(255) NOT NULL,
|
|
role VARCHAR(64) NOT NULL,
|
|
active TINYINT(1) NOT NULL DEFAULT 1,
|
|
updated_at DATETIME(3) NOT NULL,
|
|
deleted_at DATETIME(3) NULL,
|
|
is_dirty TINYINT(1) NOT NULL DEFAULT 0,
|
|
PRIMARY KEY (id),
|
|
KEY idx_staff_members_sync (updated_at, id)
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
|
|
|
CREATE TABLE IF NOT EXISTS shop_settings (
|
|
id CHAR(36) NOT NULL,
|
|
name VARCHAR(255) NOT NULL,
|
|
address VARCHAR(4000) NOT NULL DEFAULT '',
|
|
phone VARCHAR(64) NOT NULL DEFAULT '',
|
|
gstin VARCHAR(64) NOT NULL DEFAULT '',
|
|
tax_percent DOUBLE NOT NULL DEFAULT 18,
|
|
sms_bill_template VARCHAR(4000) NOT NULL,
|
|
sms_status_template VARCHAR(4000) NOT NULL,
|
|
-- Last-write-wins. v1 does not allocate invoice numbers on the server. Two tablets incrementing this will clash.
|
|
next_invoice_number INT NOT NULL DEFAULT 1 COMMENT 'Last-write-wins. v1 does not allocate invoice numbers on the server. Two tablets incrementing this will clash.',
|
|
expected_open VARCHAR(16) NOT NULL DEFAULT '09:00',
|
|
expected_close VARCHAR(16) NOT NULL DEFAULT '18:00',
|
|
late_grace_minutes INT NOT NULL DEFAULT 120,
|
|
public_base_url VARCHAR(512) NOT NULL,
|
|
updated_at DATETIME(3) NOT NULL,
|
|
deleted_at DATETIME(3) NULL,
|
|
is_dirty TINYINT(1) NOT NULL DEFAULT 0,
|
|
PRIMARY KEY (id),
|
|
KEY idx_shop_settings_sync (updated_at, id)
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
|
|
|
CREATE TABLE IF NOT EXISTS work_days (
|
|
id CHAR(36) NOT NULL,
|
|
day_key VARCHAR(32) NOT NULL,
|
|
started_at DATETIME(3) NOT NULL,
|
|
ended_at DATETIME(3) NULL,
|
|
started_by_staff_id CHAR(36) NOT NULL,
|
|
updated_at DATETIME(3) NOT NULL,
|
|
deleted_at DATETIME(3) NULL,
|
|
is_dirty TINYINT(1) NOT NULL DEFAULT 0,
|
|
PRIMARY KEY (id),
|
|
KEY idx_work_days_sync (updated_at, id)
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
|
|
|
CREATE TABLE IF NOT EXISTS attendance_records (
|
|
id CHAR(36) NOT NULL,
|
|
work_day_id CHAR(36) NOT NULL,
|
|
staff_id CHAR(36) NOT NULL,
|
|
check_in_at DATETIME(3) NULL,
|
|
check_out_at DATETIME(3) NULL,
|
|
notes VARCHAR(4000) NOT NULL DEFAULT '',
|
|
updated_at DATETIME(3) NOT NULL,
|
|
deleted_at DATETIME(3) NULL,
|
|
is_dirty TINYINT(1) NOT NULL DEFAULT 0,
|
|
PRIMARY KEY (id),
|
|
KEY idx_attendance_records_sync (updated_at, id)
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
|
|
|
CREATE TABLE IF NOT EXISTS short_leaves (
|
|
id CHAR(36) NOT NULL,
|
|
work_day_id CHAR(36) NOT NULL,
|
|
staff_id CHAR(36) NOT NULL,
|
|
from_at DATETIME(3) NOT NULL,
|
|
to_at DATETIME(3) NOT NULL,
|
|
minutes INT NOT NULL,
|
|
reason VARCHAR(4000) NOT NULL DEFAULT '',
|
|
updated_at DATETIME(3) NOT NULL,
|
|
deleted_at DATETIME(3) NULL,
|
|
is_dirty TINYINT(1) NOT NULL DEFAULT 0,
|
|
PRIMARY KEY (id),
|
|
KEY idx_short_leaves_sync (updated_at, id)
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
|
|
|
CREATE TABLE IF NOT EXISTS overtime_logs (
|
|
id CHAR(36) NOT NULL,
|
|
work_day_id CHAR(36) NOT NULL,
|
|
staff_id CHAR(36) NOT NULL,
|
|
from_at DATETIME(3) NULL,
|
|
to_at DATETIME(3) NULL,
|
|
minutes INT NOT NULL,
|
|
reason VARCHAR(4000) NOT NULL DEFAULT '',
|
|
updated_at DATETIME(3) NOT NULL,
|
|
deleted_at DATETIME(3) NULL,
|
|
is_dirty TINYINT(1) NOT NULL DEFAULT 0,
|
|
PRIMARY KEY (id),
|
|
KEY idx_overtime_logs_sync (updated_at, id)
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
|
|
|
CREATE TABLE IF NOT EXISTS customers (
|
|
id CHAR(36) NOT NULL,
|
|
phone VARCHAR(64) NOT NULL,
|
|
name VARCHAR(255) NOT NULL,
|
|
created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
|
updated_at DATETIME(3) NOT NULL,
|
|
deleted_at DATETIME(3) NULL,
|
|
is_dirty TINYINT(1) NOT NULL DEFAULT 0,
|
|
PRIMARY KEY (id),
|
|
KEY idx_customers_phone (phone),
|
|
KEY idx_customers_sync (updated_at, id)
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
|
|
|
CREATE TABLE IF NOT EXISTS vehicles (
|
|
id CHAR(36) NOT NULL,
|
|
customer_id CHAR(36) NOT NULL,
|
|
registration VARCHAR(64) NOT NULL,
|
|
vin VARCHAR(64) NOT NULL DEFAULT '',
|
|
make VARCHAR(255) NOT NULL DEFAULT '',
|
|
model_name VARCHAR(255) NOT NULL DEFAULT '',
|
|
`year` INT NULL,
|
|
engine_capacity INT NULL,
|
|
bike_model_id CHAR(36) NULL,
|
|
created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
|
updated_at DATETIME(3) NOT NULL,
|
|
deleted_at DATETIME(3) NULL,
|
|
is_dirty TINYINT(1) NOT NULL DEFAULT 0,
|
|
PRIMARY KEY (id),
|
|
KEY idx_vehicles_sync (updated_at, id)
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
|
|
|
CREATE TABLE IF NOT EXISTS job_cards (
|
|
id CHAR(36) NOT NULL,
|
|
vehicle_id CHAR(36) NOT NULL,
|
|
customer_id CHAR(36) NOT NULL,
|
|
brought_by_customer_id CHAR(36) NULL,
|
|
complaint VARCHAR(4000) NOT NULL,
|
|
stage VARCHAR(64) NOT NULL,
|
|
engineer_notes VARCHAR(4000) NOT NULL DEFAULT '',
|
|
created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
|
updated_at DATETIME(3) NOT NULL,
|
|
deleted_at DATETIME(3) NULL,
|
|
is_dirty TINYINT(1) NOT NULL DEFAULT 0,
|
|
PRIMARY KEY (id),
|
|
KEY idx_job_cards_customer (customer_id),
|
|
KEY idx_job_cards_vehicle (vehicle_id),
|
|
KEY idx_job_cards_sync (updated_at, id)
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
|
|
|
CREATE TABLE IF NOT EXISTS odo_readings (
|
|
id CHAR(36) NOT NULL,
|
|
read_at DATETIME(3) NOT NULL,
|
|
vehicle_id CHAR(36) NOT NULL,
|
|
reading_km INT NOT NULL,
|
|
updated_at DATETIME(3) NOT NULL,
|
|
deleted_at DATETIME(3) NULL,
|
|
is_dirty TINYINT(1) NOT NULL DEFAULT 0,
|
|
PRIMARY KEY (id),
|
|
KEY idx_odo_readings_sync (updated_at, id)
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
|
|
|
CREATE TABLE IF NOT EXISTS job_card_events (
|
|
id CHAR(36) NOT NULL,
|
|
job_card_id CHAR(36) NOT NULL,
|
|
stage VARCHAR(64) NOT NULL,
|
|
note VARCHAR(4000) NOT NULL DEFAULT '',
|
|
`at` DATETIME(3) NOT NULL,
|
|
updated_at DATETIME(3) NOT NULL,
|
|
deleted_at DATETIME(3) NULL,
|
|
is_dirty TINYINT(1) NOT NULL DEFAULT 0,
|
|
PRIMARY KEY (id),
|
|
KEY idx_job_card_events_sync (updated_at, id)
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
|
|
|
CREATE TABLE IF NOT EXISTS part_types (
|
|
id CHAR(36) NOT NULL,
|
|
name VARCHAR(255) NOT NULL,
|
|
updated_at DATETIME(3) NOT NULL,
|
|
deleted_at DATETIME(3) NULL,
|
|
is_dirty TINYINT(1) NOT NULL DEFAULT 0,
|
|
PRIMARY KEY (id),
|
|
KEY idx_part_types_sync (updated_at, id)
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
|
|
|
CREATE TABLE IF NOT EXISTS bike_models (
|
|
id CHAR(36) NOT NULL,
|
|
name VARCHAR(255) NOT NULL,
|
|
brand VARCHAR(255) NOT NULL DEFAULT '',
|
|
updated_at DATETIME(3) NOT NULL,
|
|
deleted_at DATETIME(3) NULL,
|
|
is_dirty TINYINT(1) NOT NULL DEFAULT 0,
|
|
PRIMARY KEY (id),
|
|
KEY idx_bike_models_sync (updated_at, id)
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
|
|
|
CREATE TABLE IF NOT EXISTS bike_groups (
|
|
id CHAR(36) NOT NULL,
|
|
name VARCHAR(255) NOT NULL,
|
|
part_type_id CHAR(36) NULL,
|
|
code VARCHAR(64) NOT NULL DEFAULT '',
|
|
notes VARCHAR(4000) NOT NULL DEFAULT '',
|
|
updated_at DATETIME(3) NOT NULL,
|
|
deleted_at DATETIME(3) NULL,
|
|
is_dirty TINYINT(1) NOT NULL DEFAULT 0,
|
|
PRIMARY KEY (id),
|
|
KEY idx_bike_groups_sync (updated_at, id)
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
|
|
|
CREATE TABLE IF NOT EXISTS bike_group_members (
|
|
id CHAR(36) NOT NULL,
|
|
group_id CHAR(36) NOT NULL,
|
|
bike_model_id CHAR(36) NOT NULL,
|
|
updated_at DATETIME(3) NOT NULL,
|
|
deleted_at DATETIME(3) NULL,
|
|
is_dirty TINYINT(1) NOT NULL DEFAULT 0,
|
|
PRIMARY KEY (id),
|
|
KEY idx_bike_group_members_sync (updated_at, id)
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
|
|
|
CREATE TABLE IF NOT EXISTS catalog_parts (
|
|
id CHAR(36) NOT NULL,
|
|
part_type_id CHAR(36) NOT NULL,
|
|
bike_model_id CHAR(36) NULL,
|
|
group_id CHAR(36) NULL,
|
|
is_universal TINYINT(1) NOT NULL DEFAULT 0,
|
|
updated_at DATETIME(3) NOT NULL,
|
|
deleted_at DATETIME(3) NULL,
|
|
is_dirty TINYINT(1) NOT NULL DEFAULT 0,
|
|
PRIMARY KEY (id),
|
|
KEY idx_catalog_parts_sync (updated_at, id)
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
|
|
|
CREATE TABLE IF NOT EXISTS catalog_part_models (
|
|
id CHAR(36) NOT NULL,
|
|
catalog_part_id CHAR(36) NOT NULL,
|
|
bike_model_id CHAR(36) NOT NULL,
|
|
updated_at DATETIME(3) NOT NULL,
|
|
deleted_at DATETIME(3) NULL,
|
|
is_dirty TINYINT(1) NOT NULL DEFAULT 0,
|
|
PRIMARY KEY (id),
|
|
KEY idx_catalog_part_models_sync (updated_at, id)
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
|
|
|
CREATE TABLE IF NOT EXISTS part_variants (
|
|
id CHAR(36) NOT NULL,
|
|
catalog_part_id CHAR(36) NOT NULL,
|
|
grade VARCHAR(64) NOT NULL,
|
|
brand VARCHAR(255) NOT NULL DEFAULT '',
|
|
sku VARCHAR(128) NOT NULL DEFAULT '',
|
|
cost DOUBLE NOT NULL DEFAULT 0,
|
|
sale_price DOUBLE NOT NULL,
|
|
qty_on_hand DOUBLE NOT NULL DEFAULT 0,
|
|
updated_at DATETIME(3) NOT NULL,
|
|
deleted_at DATETIME(3) NULL,
|
|
is_dirty TINYINT(1) NOT NULL DEFAULT 0,
|
|
PRIMARY KEY (id),
|
|
KEY idx_part_variants_sync (updated_at, id)
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
|
|
|
CREATE TABLE IF NOT EXISTS job_line_items (
|
|
id CHAR(36) NOT NULL,
|
|
job_card_id CHAR(36) NOT NULL,
|
|
kind VARCHAR(64) NOT NULL,
|
|
variant_id CHAR(36) NULL,
|
|
description VARCHAR(4000) NOT NULL,
|
|
qty DOUBLE NOT NULL,
|
|
unit_price DOUBLE NOT NULL,
|
|
updated_at DATETIME(3) NOT NULL,
|
|
deleted_at DATETIME(3) NULL,
|
|
is_dirty TINYINT(1) NOT NULL DEFAULT 0,
|
|
PRIMARY KEY (id),
|
|
KEY idx_job_line_items_sync (updated_at, id)
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
|
|
|
CREATE TABLE IF NOT EXISTS invoices (
|
|
id CHAR(36) NOT NULL,
|
|
number VARCHAR(64) NOT NULL,
|
|
public_token CHAR(36) NOT NULL,
|
|
job_card_id CHAR(36) NULL,
|
|
customer_id CHAR(36) NULL,
|
|
kind VARCHAR(64) NOT NULL,
|
|
subtotal DOUBLE NOT NULL,
|
|
tax_percent DOUBLE NOT NULL,
|
|
tax_amount DOUBLE NOT NULL,
|
|
total DOUBLE NOT NULL,
|
|
snapshot_json LONGTEXT NOT NULL,
|
|
publish_status VARCHAR(64) NOT NULL,
|
|
created_at DATETIME(3) NOT NULL,
|
|
updated_at DATETIME(3) NOT NULL,
|
|
deleted_at DATETIME(3) NULL,
|
|
is_dirty TINYINT(1) NOT NULL DEFAULT 0,
|
|
PRIMARY KEY (id),
|
|
UNIQUE KEY uq_invoices_public_token (public_token),
|
|
KEY idx_invoices_sync (updated_at, id)
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
|
|
|
CREATE TABLE IF NOT EXISTS invoice_lines (
|
|
id CHAR(36) NOT NULL,
|
|
invoice_id CHAR(36) NOT NULL,
|
|
description VARCHAR(4000) NOT NULL,
|
|
qty DOUBLE NOT NULL,
|
|
unit_price DOUBLE NOT NULL,
|
|
line_total DOUBLE NOT NULL,
|
|
updated_at DATETIME(3) NOT NULL,
|
|
deleted_at DATETIME(3) NULL,
|
|
is_dirty TINYINT(1) NOT NULL DEFAULT 0,
|
|
PRIMARY KEY (id),
|
|
KEY idx_invoice_lines_sync (updated_at, id)
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
|
|
|
CREATE TABLE IF NOT EXISTS payments (
|
|
id CHAR(36) NOT NULL,
|
|
invoice_id CHAR(36) NOT NULL,
|
|
method VARCHAR(64) NOT NULL,
|
|
amount DOUBLE NOT NULL,
|
|
`at` DATETIME(3) NOT NULL,
|
|
updated_at DATETIME(3) NOT NULL,
|
|
deleted_at DATETIME(3) NULL,
|
|
is_dirty TINYINT(1) NOT NULL DEFAULT 0,
|
|
PRIMARY KEY (id),
|
|
KEY idx_payments_sync (updated_at, id)
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
|
|
|
CREATE TABLE IF NOT EXISTS demand_logs (
|
|
id CHAR(36) NOT NULL,
|
|
part_type_id CHAR(36) NOT NULL,
|
|
bike_model_id CHAR(36) NOT NULL,
|
|
variant_id CHAR(36) NULL,
|
|
qty DOUBLE NOT NULL,
|
|
reason VARCHAR(4000) NOT NULL DEFAULT '',
|
|
created_at DATETIME(3) NOT NULL,
|
|
updated_at DATETIME(3) NOT NULL,
|
|
deleted_at DATETIME(3) NULL,
|
|
is_dirty TINYINT(1) NOT NULL DEFAULT 0,
|
|
PRIMARY KEY (id),
|
|
KEY idx_demand_logs_sync (updated_at, id)
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
|
|
|
CREATE TABLE IF NOT EXISTS sms_outbox (
|
|
id CHAR(36) NOT NULL,
|
|
to_phone VARCHAR(64) NOT NULL,
|
|
body VARCHAR(4000) NOT NULL,
|
|
status VARCHAR(64) NOT NULL,
|
|
error VARCHAR(4000) NOT NULL DEFAULT '',
|
|
invoice_id CHAR(36) NULL,
|
|
job_card_id CHAR(36) NULL,
|
|
created_at DATETIME(3) NOT NULL,
|
|
updated_at DATETIME(3) NOT NULL,
|
|
deleted_at DATETIME(3) NULL,
|
|
is_dirty TINYINT(1) NOT NULL DEFAULT 0,
|
|
PRIMARY KEY (id),
|
|
KEY idx_sms_outbox_sync (updated_at, id)
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
|
|
|
CREATE TABLE IF NOT EXISTS publish_outbox (
|
|
id CHAR(36) NOT NULL,
|
|
invoice_id CHAR(36) NOT NULL,
|
|
public_token CHAR(36) NOT NULL,
|
|
payload_json LONGTEXT NOT NULL,
|
|
status VARCHAR(64) NOT NULL,
|
|
error VARCHAR(4000) NOT NULL DEFAULT '',
|
|
created_at DATETIME(3) NOT NULL,
|
|
updated_at DATETIME(3) NOT NULL,
|
|
deleted_at DATETIME(3) NULL,
|
|
is_dirty TINYINT(1) NOT NULL DEFAULT 0,
|
|
PRIMARY KEY (id),
|
|
KEY idx_publish_outbox_sync (updated_at, id)
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
|
|
|
-- Legacy unauthenticated bill publish. Not a synced table.
|
|
-- The posted token is the public token, never invoices.id.
|
|
CREATE TABLE IF NOT EXISTS bill_snapshots (
|
|
token CHAR(36) NOT NULL,
|
|
payload_json LONGTEXT NOT NULL,
|
|
updated_at DATETIME(3) NOT NULL,
|
|
PRIMARY KEY (token)
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|