fix(number-fields): избегаем потери точности длинных чисел

- number-поля теперь рендерятся как text + inputMode=numeric,
  чтобы браузер не округлял значения через input type=number
- пробелы при вставке в number-поля удаляются
- бэкенд нормализует значения number-полей в строку перед сохранением
- добавлен хелпер normalizeFieldValueForStorage

Closes: искажение расчётного счёта и других длинных числовых полей
This commit is contained in:
2026-07-07 21:03:40 +03:00
commit 1f5ecb6da4
1089 changed files with 237546 additions and 0 deletions

View File

@@ -0,0 +1,113 @@
-- Idempotent column sync v2 for existing databases
-- Adds columns and constraints that may be absent on servers deployed before 0000_baseline.sql.
-- Primary target: status_transitions table (and supporting unique constraints required for composite FKs).
-- Safe to run multiple times: all statements use IF NOT EXISTS / DO $$ BEGIN … END $$.
-- ============================================================
-- status_transitions table: columns added after initial deployment
-- ============================================================
ALTER TABLE status_transitions ADD COLUMN IF NOT EXISTS reject_to_status_id integer;
ALTER TABLE status_transitions ADD COLUMN IF NOT EXISTS assignee_user_id integer;
ALTER TABLE status_transitions ADD COLUMN IF NOT EXISTS assignee_conditions jsonb;
ALTER TABLE status_transitions ADD COLUMN IF NOT EXISTS approve_button_text varchar(50) DEFAULT 'Одобрить';
ALTER TABLE status_transitions ADD COLUMN IF NOT EXISTS approve_button_color varchar(7) DEFAULT '#22c55e';
ALTER TABLE status_transitions ADD COLUMN IF NOT EXISTS reject_button_text varchar(50) DEFAULT 'Отклонить';
ALTER TABLE status_transitions ADD COLUMN IF NOT EXISTS reject_button_color varchar(7) DEFAULT '#ef4444';
--> statement-breakpoint
-- ============================================================
-- form_statuses: unique(id, form_id) — required as FK target for
-- composite foreign keys on status_transitions
-- ============================================================
DO $$ BEGIN
IF NOT EXISTS (
SELECT 1 FROM information_schema.table_constraints
WHERE constraint_name = 'form_statuses_id_form_id_unique'
AND table_name = 'form_statuses'
) THEN
ALTER TABLE form_statuses ADD CONSTRAINT "form_statuses_id_form_id_unique" UNIQUE ("id", "form_id");
END IF;
END $$;
--> statement-breakpoint
-- ============================================================
-- form_fields: unique(id, form_id) — mirrors baseline constraint,
-- required as FK target for other composite references
-- ============================================================
DO $$ BEGIN
IF NOT EXISTS (
SELECT 1 FROM information_schema.table_constraints
WHERE constraint_name = 'form_fields_id_form_id_unique'
AND table_name = 'form_fields'
) THEN
ALTER TABLE form_fields ADD CONSTRAINT "form_fields_id_form_id_unique" UNIQUE ("id", "form_id");
END IF;
END $$;
--> statement-breakpoint
-- ============================================================
-- status_transitions: composite FK — from_status_id must belong
-- to the same form as form_id
-- ============================================================
DO $$ BEGIN
IF NOT EXISTS (
SELECT 1 FROM information_schema.table_constraints
WHERE constraint_name = 'fk_transition_from_status_same_form'
AND table_name = 'status_transitions'
) THEN
ALTER TABLE status_transitions
ADD CONSTRAINT "fk_transition_from_status_same_form"
FOREIGN KEY ("from_status_id", "form_id")
REFERENCES form_statuses ("id", "form_id");
END IF;
END $$;
--> statement-breakpoint
-- ============================================================
-- status_transitions: composite FK — to_status_id must belong
-- to the same form as form_id
-- ============================================================
DO $$ BEGIN
IF NOT EXISTS (
SELECT 1 FROM information_schema.table_constraints
WHERE constraint_name = 'fk_transition_to_status_same_form'
AND table_name = 'status_transitions'
) THEN
ALTER TABLE status_transitions
ADD CONSTRAINT "fk_transition_to_status_same_form"
FOREIGN KEY ("to_status_id", "form_id")
REFERENCES form_statuses ("id", "form_id");
END IF;
END $$;
--> statement-breakpoint
-- ============================================================
-- status_transitions: FK — reject_to_status_id -> form_statuses.id
-- ============================================================
DO $$ BEGIN
IF NOT EXISTS (
SELECT 1 FROM pg_constraint
WHERE conname = 'status_transitions_reject_to_status_id_form_statuses_id_fk'
) THEN
ALTER TABLE status_transitions
ADD CONSTRAINT "status_transitions_reject_to_status_id_form_statuses_id_fk"
FOREIGN KEY ("reject_to_status_id") REFERENCES form_statuses ("id")
ON DELETE no action ON UPDATE no action;
END IF;
END $$;
--> statement-breakpoint
-- ============================================================
-- status_transitions: FK — assignee_user_id -> users.id
-- ============================================================
DO $$ BEGIN
IF NOT EXISTS (
SELECT 1 FROM pg_constraint
WHERE conname = 'status_transitions_assignee_user_id_users_id_fk'
) THEN
ALTER TABLE status_transitions
ADD CONSTRAINT "status_transitions_assignee_user_id_users_id_fk"
FOREIGN KEY ("assignee_user_id") REFERENCES users ("id")
ON DELETE no action ON UPDATE no action;
END IF;
END $$;