From the 2026-06-09 full-codebase audit. Warehouse line->header relations CASCADE on delete; line->master-data and the financial FKs are explicit RESTRICT; UNIQUE on receipt/issue/session numbers; new indexes on hot FK columns (sklad_issues/receipts, bank_accounts); dropped a duplicate audit_logs created_at index. Applied to dev `app` and `app_test`. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
138 lines
6.2 KiB
SQL
138 lines
6.2 KiB
SQL
-- Audit schema hardening (from the 2026-06-09 codebase audit).
|
|
--
|
|
-- ⚠️ PENDING — NOT YET APPLIED. Review, then apply with the dev server stopped:
|
|
-- npx prisma migrate deploy (prod / already-tracked)
|
|
-- -- or, in dev, `npx prisma migrate dev` will pick it up as pending.
|
|
--
|
|
-- What this does:
|
|
-- • Warehouse line→header relations now CASCADE on delete (deleting a
|
|
-- receipt/issue/inventory session removes its lines/attachments).
|
|
-- • Warehouse line→master-data (item/batch/location) and the financial FKs
|
|
-- (invoices/orders/projects/quotations → customer/order/quotation) are now
|
|
-- explicit ON DELETE RESTRICT — preventing deletion of a referenced master
|
|
-- record / orphaning of a financial record. (Some of these were previously
|
|
-- the optional-relation default SET NULL; RESTRICT is the safer intent.)
|
|
-- • UNIQUE on warehouse document numbers (receipt_number/issue_number/
|
|
-- session_number) — like every other document-number column.
|
|
-- • New indexes on hot FK filters (sklad_issues/receipts, bank_accounts).
|
|
--
|
|
-- ⚠️ BEFORE APPLYING ON PRODUCTION, verify existing data won't violate the new
|
|
-- constraints: no DUPLICATE non-null receipt/issue/session numbers (else the
|
|
-- UNIQUE index fails), and no rows that would break the RESTRICT FKs. Test on
|
|
-- a copy first.
|
|
--
|
|
-- DropForeignKey
|
|
ALTER TABLE `invoices` DROP FOREIGN KEY `invoices_ibfk_1`;
|
|
|
|
-- DropForeignKey
|
|
ALTER TABLE `invoices` DROP FOREIGN KEY `invoices_ibfk_2`;
|
|
|
|
-- DropForeignKey
|
|
ALTER TABLE `orders` DROP FOREIGN KEY `orders_ibfk_1`;
|
|
|
|
-- DropForeignKey
|
|
ALTER TABLE `orders` DROP FOREIGN KEY `orders_ibfk_2`;
|
|
|
|
-- DropForeignKey
|
|
ALTER TABLE `projects` DROP FOREIGN KEY `projects_ibfk_1`;
|
|
|
|
-- DropForeignKey
|
|
ALTER TABLE `projects` DROP FOREIGN KEY `projects_ibfk_2`;
|
|
|
|
-- DropForeignKey
|
|
ALTER TABLE `projects` DROP FOREIGN KEY `projects_ibfk_3`;
|
|
|
|
-- DropForeignKey
|
|
ALTER TABLE `quotations` DROP FOREIGN KEY `quotations_ibfk_1`;
|
|
|
|
-- DropForeignKey
|
|
ALTER TABLE `sklad_receipt_lines` DROP FOREIGN KEY `sklad_receipt_lines_receipt_id_fkey`;
|
|
|
|
-- DropForeignKey
|
|
ALTER TABLE `sklad_receipt_lines` DROP FOREIGN KEY `sklad_receipt_lines_location_id_fkey`;
|
|
|
|
-- DropForeignKey
|
|
ALTER TABLE `sklad_receipt_attachments` DROP FOREIGN KEY `sklad_receipt_attachments_receipt_id_fkey`;
|
|
|
|
-- DropForeignKey
|
|
ALTER TABLE `sklad_issue_lines` DROP FOREIGN KEY `sklad_issue_lines_issue_id_fkey`;
|
|
|
|
-- DropForeignKey
|
|
ALTER TABLE `sklad_issue_lines` DROP FOREIGN KEY `sklad_issue_lines_location_id_fkey`;
|
|
|
|
-- DropForeignKey
|
|
ALTER TABLE `sklad_inventory_lines` DROP FOREIGN KEY `sklad_inventory_lines_session_id_fkey`;
|
|
|
|
-- DropForeignKey
|
|
ALTER TABLE `sklad_inventory_lines` DROP FOREIGN KEY `sklad_inventory_lines_location_id_fkey`;
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX `idx_bank_accounts_is_default` ON `bank_accounts`(`is_default`);
|
|
|
|
-- CreateIndex
|
|
CREATE UNIQUE INDEX `sklad_receipts_receipt_number_key` ON `sklad_receipts`(`receipt_number`);
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX `sklad_receipts_supplier_id` ON `sklad_receipts`(`supplier_id`);
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX `sklad_receipts_received_by` ON `sklad_receipts`(`received_by`);
|
|
|
|
-- CreateIndex
|
|
CREATE UNIQUE INDEX `sklad_issues_issue_number_key` ON `sklad_issues`(`issue_number`);
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX `sklad_issues_project_id` ON `sklad_issues`(`project_id`);
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX `sklad_issues_issued_by` ON `sklad_issues`(`issued_by`);
|
|
|
|
-- CreateIndex
|
|
CREATE UNIQUE INDEX `sklad_inventory_sessions_session_number_key` ON `sklad_inventory_sessions`(`session_number`);
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE `invoices` ADD CONSTRAINT `invoices_ibfk_1` FOREIGN KEY (`order_id`) REFERENCES `orders`(`id`) ON DELETE RESTRICT ON UPDATE NO ACTION;
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE `invoices` ADD CONSTRAINT `invoices_ibfk_2` FOREIGN KEY (`customer_id`) REFERENCES `customers`(`id`) ON DELETE RESTRICT ON UPDATE NO ACTION;
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE `orders` ADD CONSTRAINT `orders_ibfk_1` FOREIGN KEY (`quotation_id`) REFERENCES `quotations`(`id`) ON DELETE RESTRICT ON UPDATE NO ACTION;
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE `orders` ADD CONSTRAINT `orders_ibfk_2` FOREIGN KEY (`customer_id`) REFERENCES `customers`(`id`) ON DELETE RESTRICT ON UPDATE NO ACTION;
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE `projects` ADD CONSTRAINT `projects_ibfk_1` FOREIGN KEY (`customer_id`) REFERENCES `customers`(`id`) ON DELETE RESTRICT ON UPDATE NO ACTION;
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE `projects` ADD CONSTRAINT `projects_ibfk_2` FOREIGN KEY (`quotation_id`) REFERENCES `quotations`(`id`) ON DELETE RESTRICT ON UPDATE NO ACTION;
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE `projects` ADD CONSTRAINT `projects_ibfk_3` FOREIGN KEY (`order_id`) REFERENCES `orders`(`id`) ON DELETE RESTRICT ON UPDATE NO ACTION;
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE `quotations` ADD CONSTRAINT `quotations_ibfk_1` FOREIGN KEY (`customer_id`) REFERENCES `customers`(`id`) ON DELETE RESTRICT ON UPDATE NO ACTION;
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE `sklad_receipt_lines` ADD CONSTRAINT `sklad_receipt_lines_receipt_id_fkey` FOREIGN KEY (`receipt_id`) REFERENCES `sklad_receipts`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE `sklad_receipt_lines` ADD CONSTRAINT `sklad_receipt_lines_location_id_fkey` FOREIGN KEY (`location_id`) REFERENCES `sklad_locations`(`id`) ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE `sklad_receipt_attachments` ADD CONSTRAINT `sklad_receipt_attachments_receipt_id_fkey` FOREIGN KEY (`receipt_id`) REFERENCES `sklad_receipts`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE `sklad_issue_lines` ADD CONSTRAINT `sklad_issue_lines_issue_id_fkey` FOREIGN KEY (`issue_id`) REFERENCES `sklad_issues`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE `sklad_issue_lines` ADD CONSTRAINT `sklad_issue_lines_location_id_fkey` FOREIGN KEY (`location_id`) REFERENCES `sklad_locations`(`id`) ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE `sklad_inventory_lines` ADD CONSTRAINT `sklad_inventory_lines_session_id_fkey` FOREIGN KEY (`session_id`) REFERENCES `sklad_inventory_sessions`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE `sklad_inventory_lines` ADD CONSTRAINT `sklad_inventory_lines_location_id_fkey` FOREIGN KEY (`location_id`) REFERENCES `sklad_locations`(`id`) ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
|