- number-поля теперь рендерятся как text + inputMode=numeric, чтобы браузер не округлял значения через input type=number - пробелы при вставке в number-поля удаляются - бэкенд нормализует значения number-полей в строку перед сохранением - добавлен хелпер normalizeFieldValueForStorage Closes: искажение расчётного счёта и других длинных числовых полей
99 lines
3.8 KiB
SQL
99 lines
3.8 KiB
SQL
-- Finance module tables
|
|
|
|
CREATE TABLE IF NOT EXISTS income_categories (
|
|
id SERIAL PRIMARY KEY,
|
|
organization_id INTEGER NOT NULL REFERENCES organizations(id) ON DELETE CASCADE,
|
|
tree_id UUID NOT NULL DEFAULT gen_random_uuid(),
|
|
name VARCHAR(200) NOT NULL,
|
|
categories JSONB NOT NULL DEFAULT '[]',
|
|
created_at TIMESTAMP DEFAULT NOW(),
|
|
updated_at TIMESTAMP DEFAULT NOW()
|
|
);
|
|
|
|
CREATE UNIQUE INDEX IF NOT EXISTS income_categories_org_tree_idx ON income_categories(organization_id, tree_id);
|
|
|
|
CREATE TABLE IF NOT EXISTS expense_categories (
|
|
id SERIAL PRIMARY KEY,
|
|
organization_id INTEGER NOT NULL REFERENCES organizations(id) ON DELETE CASCADE,
|
|
tree_id UUID NOT NULL DEFAULT gen_random_uuid(),
|
|
name VARCHAR(200) NOT NULL,
|
|
categories JSONB NOT NULL DEFAULT '[]',
|
|
created_at TIMESTAMP DEFAULT NOW(),
|
|
updated_at TIMESTAMP DEFAULT NOW()
|
|
);
|
|
|
|
CREATE UNIQUE INDEX IF NOT EXISTS expense_categories_org_tree_idx ON expense_categories(organization_id, tree_id);
|
|
|
|
CREATE TABLE IF NOT EXISTS income_category_overrides (
|
|
id SERIAL PRIMARY KEY,
|
|
organization_id INTEGER NOT NULL REFERENCES organizations(id) ON DELETE CASCADE,
|
|
record_id VARCHAR(100) NOT NULL,
|
|
category_id VARCHAR(100) NOT NULL,
|
|
created_at TIMESTAMP DEFAULT NOW(),
|
|
updated_at TIMESTAMP DEFAULT NOW(),
|
|
UNIQUE(organization_id, record_id)
|
|
);
|
|
|
|
CREATE INDEX IF NOT EXISTS income_overrides_org_record_idx ON income_category_overrides(organization_id, record_id);
|
|
|
|
CREATE TABLE IF NOT EXISTS expense_category_overrides (
|
|
id SERIAL PRIMARY KEY,
|
|
organization_id INTEGER NOT NULL REFERENCES organizations(id) ON DELETE CASCADE,
|
|
record_id VARCHAR(100) NOT NULL,
|
|
category_id VARCHAR(100) NOT NULL,
|
|
created_at TIMESTAMP DEFAULT NOW(),
|
|
updated_at TIMESTAMP DEFAULT NOW(),
|
|
UNIQUE(organization_id, record_id)
|
|
);
|
|
|
|
CREATE INDEX IF NOT EXISTS expense_overrides_org_record_idx ON expense_category_overrides(organization_id, record_id);
|
|
|
|
CREATE TABLE IF NOT EXISTS auto_detect_trees (
|
|
id SERIAL PRIMARY KEY,
|
|
organization_id INTEGER NOT NULL REFERENCES organizations(id) ON DELETE CASCADE,
|
|
context VARCHAR(20) NOT NULL CHECK (context IN ('income', 'expense')),
|
|
tree_id UUID NOT NULL DEFAULT gen_random_uuid(),
|
|
name VARCHAR(200) NOT NULL,
|
|
config JSONB NOT NULL DEFAULT '{}',
|
|
is_primary BOOLEAN NOT NULL DEFAULT false,
|
|
created_at TIMESTAMP DEFAULT NOW(),
|
|
updated_at TIMESTAMP DEFAULT NOW(),
|
|
UNIQUE(organization_id, context, tree_id)
|
|
);
|
|
|
|
CREATE INDEX IF NOT EXISTS auto_detect_trees_org_idx ON auto_detect_trees(organization_id, context);
|
|
|
|
CREATE TABLE IF NOT EXISTS node_tags (
|
|
id SERIAL PRIMARY KEY,
|
|
organization_id INTEGER NOT NULL REFERENCES organizations(id) ON DELETE CASCADE,
|
|
name VARCHAR(100) NOT NULL,
|
|
color VARCHAR(20) NOT NULL DEFAULT '#2563eb',
|
|
created_at TIMESTAMP DEFAULT NOW(),
|
|
UNIQUE(organization_id, name)
|
|
);
|
|
|
|
CREATE INDEX IF NOT EXISTS node_tags_org_idx ON node_tags(organization_id);
|
|
|
|
CREATE TABLE IF NOT EXISTS node_tag_assignments (
|
|
id SERIAL PRIMARY KEY,
|
|
organization_id INTEGER NOT NULL REFERENCES organizations(id) ON DELETE CASCADE,
|
|
node_id VARCHAR(100) NOT NULL,
|
|
tag_id INTEGER NOT NULL REFERENCES node_tags(id) ON DELETE CASCADE,
|
|
context VARCHAR(20) NOT NULL CHECK (context IN ('income', 'expense')),
|
|
created_at TIMESTAMP DEFAULT NOW(),
|
|
UNIQUE(organization_id, node_id, tag_id, context)
|
|
);
|
|
|
|
CREATE INDEX IF NOT EXISTS node_tag_assignments_org_idx ON node_tag_assignments(organization_id, context, node_id);
|
|
|
|
CREATE TABLE IF NOT EXISTS finance_table_settings (
|
|
id SERIAL PRIMARY KEY,
|
|
organization_id INTEGER NOT NULL REFERENCES organizations(id) ON DELETE CASCADE,
|
|
section VARCHAR(20) NOT NULL CHECK (section IN ('income', 'expense')),
|
|
visible_cols JSONB NOT NULL DEFAULT '[]',
|
|
col_order JSONB NOT NULL DEFAULT '[]',
|
|
created_at TIMESTAMP DEFAULT NOW(),
|
|
updated_at TIMESTAMP DEFAULT NOW(),
|
|
UNIQUE(organization_id, section)
|
|
);
|