init
This commit is contained in:
@@ -0,0 +1,329 @@
|
||||
export type ColumnType = "uuid" | "string" | "longtext" | "bool" | "double" | "int" | "datetime";
|
||||
|
||||
export type Column = {
|
||||
name: string;
|
||||
type: ColumnType;
|
||||
nullable: boolean;
|
||||
hasDefault: boolean;
|
||||
max?: number;
|
||||
};
|
||||
|
||||
export type TableSpec = {
|
||||
name: string;
|
||||
columns: Column[];
|
||||
};
|
||||
|
||||
function col(
|
||||
name: string,
|
||||
type: ColumnType,
|
||||
extra?: Partial<Pick<Column, "nullable" | "hasDefault" | "max">>,
|
||||
): Column {
|
||||
return {
|
||||
name,
|
||||
type,
|
||||
nullable: extra?.nullable ?? false,
|
||||
hasDefault: extra?.hasDefault ?? false,
|
||||
max: extra?.max,
|
||||
};
|
||||
}
|
||||
|
||||
function tail(): Column[] {
|
||||
return [
|
||||
col("updated_at", "datetime"),
|
||||
col("deleted_at", "datetime", { nullable: true, hasDefault: true }),
|
||||
col("is_dirty", "bool", { hasDefault: true }),
|
||||
];
|
||||
}
|
||||
|
||||
const id = () => col("id", "uuid");
|
||||
const text = (name: string, max: number, hasDefault = false) =>
|
||||
col(name, "string", { max, hasDefault });
|
||||
const ref = (name: string, nullable = false) => col(name, "uuid", { nullable });
|
||||
|
||||
export const SYNC_TABLES: Record<string, TableSpec> = {
|
||||
staff_members: {
|
||||
name: "staff_members",
|
||||
columns: [
|
||||
id(),
|
||||
text("name", 255),
|
||||
text("pin_hash", 255),
|
||||
text("role", 64),
|
||||
col("active", "bool", { hasDefault: true }),
|
||||
...tail(),
|
||||
],
|
||||
},
|
||||
shop_settings: {
|
||||
name: "shop_settings",
|
||||
columns: [
|
||||
id(),
|
||||
text("name", 255),
|
||||
text("address", 4000, true),
|
||||
text("phone", 64, true),
|
||||
text("gstin", 64, true),
|
||||
col("tax_percent", "double", { hasDefault: true }),
|
||||
text("sms_bill_template", 4000),
|
||||
text("sms_status_template", 4000),
|
||||
// v1 does not allocate invoice numbers. next_invoice_number is last-write-wins.
|
||||
// Two tablets incrementing it will clash.
|
||||
col("next_invoice_number", "int", { hasDefault: true }),
|
||||
text("expected_open", 16, true),
|
||||
text("expected_close", 16, true),
|
||||
col("late_grace_minutes", "int", { hasDefault: true }),
|
||||
text("public_base_url", 512),
|
||||
...tail(),
|
||||
],
|
||||
},
|
||||
work_days: {
|
||||
name: "work_days",
|
||||
columns: [
|
||||
id(),
|
||||
text("day_key", 32),
|
||||
col("started_at", "datetime"),
|
||||
col("ended_at", "datetime", { nullable: true }),
|
||||
ref("started_by_staff_id"),
|
||||
...tail(),
|
||||
],
|
||||
},
|
||||
attendance_records: {
|
||||
name: "attendance_records",
|
||||
columns: [
|
||||
id(),
|
||||
ref("work_day_id"),
|
||||
ref("staff_id"),
|
||||
col("check_in_at", "datetime", { nullable: true }),
|
||||
col("check_out_at", "datetime", { nullable: true }),
|
||||
text("notes", 4000, true),
|
||||
...tail(),
|
||||
],
|
||||
},
|
||||
short_leaves: {
|
||||
name: "short_leaves",
|
||||
columns: [
|
||||
id(),
|
||||
ref("work_day_id"),
|
||||
ref("staff_id"),
|
||||
col("from_at", "datetime"),
|
||||
col("to_at", "datetime"),
|
||||
col("minutes", "int"),
|
||||
text("reason", 4000, true),
|
||||
...tail(),
|
||||
],
|
||||
},
|
||||
overtime_logs: {
|
||||
name: "overtime_logs",
|
||||
columns: [
|
||||
id(),
|
||||
ref("work_day_id"),
|
||||
ref("staff_id"),
|
||||
col("from_at", "datetime", { nullable: true }),
|
||||
col("to_at", "datetime", { nullable: true }),
|
||||
col("minutes", "int"),
|
||||
text("reason", 4000, true),
|
||||
...tail(),
|
||||
],
|
||||
},
|
||||
customers: {
|
||||
name: "customers",
|
||||
columns: [
|
||||
id(),
|
||||
text("phone", 64),
|
||||
text("name", 255),
|
||||
col("created_at", "datetime", { hasDefault: true }),
|
||||
...tail(),
|
||||
],
|
||||
},
|
||||
vehicles: {
|
||||
name: "vehicles",
|
||||
columns: [
|
||||
id(),
|
||||
ref("customer_id"),
|
||||
text("registration", 64),
|
||||
text("vin", 64, true),
|
||||
text("make", 255, true),
|
||||
text("model_name", 255, true),
|
||||
col("year", "int", { nullable: true }),
|
||||
col("engine_capacity", "int", { nullable: true }),
|
||||
ref("bike_model_id", true),
|
||||
col("created_at", "datetime", { hasDefault: true }),
|
||||
...tail(),
|
||||
],
|
||||
},
|
||||
job_cards: {
|
||||
name: "job_cards",
|
||||
columns: [
|
||||
id(),
|
||||
ref("vehicle_id"),
|
||||
ref("customer_id"),
|
||||
ref("brought_by_customer_id", true),
|
||||
text("complaint", 4000),
|
||||
text("stage", 64),
|
||||
text("engineer_notes", 4000, true),
|
||||
col("created_at", "datetime", { hasDefault: true }),
|
||||
...tail(),
|
||||
],
|
||||
},
|
||||
odo_readings: {
|
||||
name: "odo_readings",
|
||||
columns: [id(), col("read_at", "datetime"), ref("vehicle_id"), col("reading_km", "int"), ...tail()],
|
||||
},
|
||||
job_card_events: {
|
||||
name: "job_card_events",
|
||||
columns: [
|
||||
id(),
|
||||
ref("job_card_id"),
|
||||
text("stage", 64),
|
||||
text("note", 4000, true),
|
||||
col("at", "datetime"),
|
||||
...tail(),
|
||||
],
|
||||
},
|
||||
part_types: {
|
||||
name: "part_types",
|
||||
columns: [id(), text("name", 255), ...tail()],
|
||||
},
|
||||
bike_models: {
|
||||
name: "bike_models",
|
||||
columns: [id(), text("name", 255), text("brand", 255, true), ...tail()],
|
||||
},
|
||||
bike_groups: {
|
||||
name: "bike_groups",
|
||||
columns: [
|
||||
id(),
|
||||
text("name", 255),
|
||||
ref("part_type_id", true),
|
||||
text("code", 64, true),
|
||||
text("notes", 4000, true),
|
||||
...tail(),
|
||||
],
|
||||
},
|
||||
bike_group_members: {
|
||||
name: "bike_group_members",
|
||||
columns: [id(), ref("group_id"), ref("bike_model_id"), ...tail()],
|
||||
},
|
||||
catalog_parts: {
|
||||
name: "catalog_parts",
|
||||
columns: [
|
||||
id(),
|
||||
ref("part_type_id"),
|
||||
ref("bike_model_id", true),
|
||||
ref("group_id", true),
|
||||
col("is_universal", "bool", { hasDefault: true }),
|
||||
...tail(),
|
||||
],
|
||||
},
|
||||
catalog_part_models: {
|
||||
name: "catalog_part_models",
|
||||
columns: [id(), ref("catalog_part_id"), ref("bike_model_id"), ...tail()],
|
||||
},
|
||||
part_variants: {
|
||||
name: "part_variants",
|
||||
columns: [
|
||||
id(),
|
||||
ref("catalog_part_id"),
|
||||
text("grade", 64),
|
||||
text("brand", 255, true),
|
||||
text("sku", 128, true),
|
||||
col("cost", "double", { hasDefault: true }),
|
||||
col("sale_price", "double"),
|
||||
col("qty_on_hand", "double", { hasDefault: true }),
|
||||
...tail(),
|
||||
],
|
||||
},
|
||||
job_line_items: {
|
||||
name: "job_line_items",
|
||||
columns: [
|
||||
id(),
|
||||
ref("job_card_id"),
|
||||
text("kind", 64),
|
||||
ref("variant_id", true),
|
||||
text("description", 4000),
|
||||
col("qty", "double"),
|
||||
col("unit_price", "double"),
|
||||
...tail(),
|
||||
],
|
||||
},
|
||||
invoices: {
|
||||
name: "invoices",
|
||||
columns: [
|
||||
id(),
|
||||
text("number", 64),
|
||||
ref("public_token"),
|
||||
ref("job_card_id", true),
|
||||
ref("customer_id", true),
|
||||
text("kind", 64),
|
||||
col("subtotal", "double"),
|
||||
col("tax_percent", "double"),
|
||||
col("tax_amount", "double"),
|
||||
col("total", "double"),
|
||||
col("snapshot_json", "longtext"),
|
||||
text("publish_status", 64),
|
||||
col("created_at", "datetime"),
|
||||
...tail(),
|
||||
],
|
||||
},
|
||||
invoice_lines: {
|
||||
name: "invoice_lines",
|
||||
columns: [
|
||||
id(),
|
||||
ref("invoice_id"),
|
||||
text("description", 4000),
|
||||
col("qty", "double"),
|
||||
col("unit_price", "double"),
|
||||
col("line_total", "double"),
|
||||
...tail(),
|
||||
],
|
||||
},
|
||||
payments: {
|
||||
name: "payments",
|
||||
columns: [
|
||||
id(),
|
||||
ref("invoice_id"),
|
||||
text("method", 64),
|
||||
col("amount", "double"),
|
||||
col("at", "datetime"),
|
||||
...tail(),
|
||||
],
|
||||
},
|
||||
demand_logs: {
|
||||
name: "demand_logs",
|
||||
columns: [
|
||||
id(),
|
||||
ref("part_type_id"),
|
||||
ref("bike_model_id"),
|
||||
ref("variant_id", true),
|
||||
col("qty", "double"),
|
||||
text("reason", 4000, true),
|
||||
col("created_at", "datetime"),
|
||||
...tail(),
|
||||
],
|
||||
},
|
||||
sms_outbox: {
|
||||
name: "sms_outbox",
|
||||
columns: [
|
||||
id(),
|
||||
text("to_phone", 64),
|
||||
text("body", 4000),
|
||||
text("status", 64),
|
||||
text("error", 4000, true),
|
||||
ref("invoice_id", true),
|
||||
ref("job_card_id", true),
|
||||
col("created_at", "datetime"),
|
||||
...tail(),
|
||||
],
|
||||
},
|
||||
publish_outbox: {
|
||||
name: "publish_outbox",
|
||||
columns: [
|
||||
id(),
|
||||
ref("invoice_id"),
|
||||
ref("public_token"),
|
||||
col("payload_json", "longtext"),
|
||||
text("status", 64),
|
||||
text("error", 4000, true),
|
||||
col("created_at", "datetime"),
|
||||
...tail(),
|
||||
],
|
||||
},
|
||||
};
|
||||
|
||||
export const SYNC_TABLE_NAMES = Object.keys(SYNC_TABLES);
|
||||
Reference in New Issue
Block a user