v1.6.5: fix attendance unique constraint, schema sync, seed script
- Change attendance idx_attendance_user_date from unique to index (allow multiple shifts per day) - Reset migrations to single baseline init migration - Add seed script with admin user (admin/admin) - Update CLAUDE.md with migration workflow documentation - Various frontend fixes (queries, pages, hooks) Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -1,2 +0,0 @@
|
||||
-- Add billing_text column to invoices table
|
||||
ALTER TABLE `invoices` ADD COLUMN `billing_text` VARCHAR(500) NULL AFTER `issued_by`;
|
||||
@@ -1,3 +0,0 @@
|
||||
-- Add lock fields to quotations table for pessimistic locking
|
||||
ALTER TABLE `quotations` ADD COLUMN `locked_by` INT NULL AFTER `scope_description`;
|
||||
ALTER TABLE `quotations` ADD COLUMN `locked_at` DATETIME NULL AFTER `locked_by`;
|
||||
@@ -1,9 +0,0 @@
|
||||
CREATE TABLE `invoice_alert_log` (
|
||||
`id` INT NOT NULL AUTO_INCREMENT,
|
||||
`invoice_type` VARCHAR(20) NOT NULL,
|
||||
`invoice_id` INT NOT NULL,
|
||||
`alert_type` VARCHAR(20) NOT NULL,
|
||||
`sent_at` DATETIME(0) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `invoice_type_invoice_id_alert_type` (`invoice_type`, `invoice_id`, `alert_type`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
@@ -1 +0,0 @@
|
||||
ALTER TABLE `invoices` ADD COLUMN `language` VARCHAR(5) DEFAULT 'cs' AFTER `billing_text`;
|
||||
@@ -1,2 +0,0 @@
|
||||
-- Add file_path column for NAS storage of received invoice files
|
||||
ALTER TABLE `received_invoices` ADD COLUMN `file_path` VARCHAR(500) NULL AFTER `file_data`;
|
||||
@@ -1,4 +0,0 @@
|
||||
-- Remove file_data (BLOB) and file_path columns — files are now stored on NAS
|
||||
-- Path is derived from year, month, and file_name
|
||||
ALTER TABLE `received_invoices` DROP COLUMN `file_data`;
|
||||
ALTER TABLE `received_invoices` DROP COLUMN `file_path`;
|
||||
@@ -1 +0,0 @@
|
||||
ALTER TABLE `company_settings` ADD COLUMN `logo_data_dark` MEDIUMBLOB NULL AFTER `logo_data`;
|
||||
@@ -1,4 +0,0 @@
|
||||
ALTER TABLE `company_settings`
|
||||
ADD COLUMN `offer_number_pattern` VARCHAR(100) NULL,
|
||||
ADD COLUMN `order_number_pattern` VARCHAR(100) NULL,
|
||||
ADD COLUMN `invoice_number_pattern` VARCHAR(100) NULL;
|
||||
@@ -1,3 +0,0 @@
|
||||
ALTER TABLE `company_settings`
|
||||
ADD COLUMN `smtp_from` VARCHAR(255) NULL,
|
||||
ADD COLUMN `smtp_from_name` VARCHAR(255) NULL;
|
||||
@@ -1,13 +0,0 @@
|
||||
-- System settings columns on company_settings
|
||||
ALTER TABLE `company_settings`
|
||||
ADD COLUMN `break_threshold_hours` DECIMAL(4,2) DEFAULT 6,
|
||||
ADD COLUMN `break_duration_short` INT DEFAULT 15,
|
||||
ADD COLUMN `break_duration_long` INT DEFAULT 30,
|
||||
ADD COLUMN `clock_rounding_minutes` INT DEFAULT 15,
|
||||
ADD COLUMN `invoice_alert_email` VARCHAR(255) NULL,
|
||||
ADD COLUMN `leave_notify_email` VARCHAR(255) NULL,
|
||||
ADD COLUMN `max_login_attempts` INT DEFAULT 5,
|
||||
ADD COLUMN `lockout_minutes` INT DEFAULT 15,
|
||||
ADD COLUMN `max_requests_per_minute` INT DEFAULT 300,
|
||||
ADD COLUMN `available_vat_rates` LONGTEXT NULL,
|
||||
ADD COLUMN `available_currencies` LONGTEXT NULL;
|
||||
@@ -1,18 +0,0 @@
|
||||
-- Create new unified permission
|
||||
INSERT INTO permissions (name, display_name, description, module)
|
||||
VALUES ('settings.manage', 'Správa nastavení', 'Správa všech nastavení systému', 'settings')
|
||||
ON DUPLICATE KEY UPDATE display_name = VALUES(display_name);
|
||||
|
||||
-- Grant to all roles that had any of the old 3
|
||||
INSERT IGNORE INTO role_permissions (role_id, permission_id)
|
||||
SELECT DISTINCT rp.role_id, (SELECT id FROM permissions WHERE name = 'settings.manage')
|
||||
FROM role_permissions rp
|
||||
JOIN permissions p ON p.id = rp.permission_id
|
||||
WHERE p.name IN ('offers.settings', 'settings.roles', 'settings.security');
|
||||
|
||||
-- Clean up old role_permissions
|
||||
DELETE FROM role_permissions
|
||||
WHERE permission_id IN (SELECT id FROM permissions WHERE name IN ('offers.settings', 'settings.roles', 'settings.security'));
|
||||
|
||||
-- Remove old permissions
|
||||
DELETE FROM permissions WHERE name IN ('offers.settings', 'settings.roles', 'settings.security');
|
||||
@@ -1,2 +0,0 @@
|
||||
-- Add unique constraint on number_sequences(type, year) for atomic numbering
|
||||
ALTER TABLE number_sequences ADD UNIQUE INDEX idx_number_sequences_type_year (`type`, `year`);
|
||||
@@ -1,2 +0,0 @@
|
||||
-- AlterTable
|
||||
ALTER TABLE `users` ADD COLUMN `totp_last_used_counter` INTEGER NULL;
|
||||
@@ -98,6 +98,7 @@ CREATE TABLE `company_settings` (
|
||||
`vat_id` VARCHAR(50) NULL,
|
||||
`custom_fields` LONGTEXT NULL,
|
||||
`logo_data` LONGBLOB NULL,
|
||||
`logo_data_dark` MEDIUMBLOB NULL,
|
||||
`quotation_prefix` VARCHAR(20) NULL,
|
||||
`default_currency` VARCHAR(10) NULL DEFAULT 'CZK',
|
||||
`default_vat_rate` DECIMAL(5, 2) NULL DEFAULT 21.00,
|
||||
@@ -108,7 +109,24 @@ CREATE TABLE `company_settings` (
|
||||
`order_type_code` VARCHAR(10) NULL,
|
||||
`invoice_type_code` VARCHAR(10) NULL,
|
||||
`require_2fa` BOOLEAN NOT NULL DEFAULT false,
|
||||
`break_threshold_hours` DECIMAL(4, 2) NULL DEFAULT 6.00,
|
||||
`break_duration_short` INTEGER NULL DEFAULT 15,
|
||||
`break_duration_long` INTEGER NULL DEFAULT 30,
|
||||
`clock_rounding_minutes` INTEGER NULL DEFAULT 15,
|
||||
`invoice_alert_email` VARCHAR(255) NULL,
|
||||
`leave_notify_email` VARCHAR(255) NULL,
|
||||
`max_login_attempts` INTEGER NULL DEFAULT 5,
|
||||
`lockout_minutes` INTEGER NULL DEFAULT 15,
|
||||
`max_requests_per_minute` INTEGER NULL DEFAULT 300,
|
||||
`available_vat_rates` LONGTEXT NULL,
|
||||
`available_currencies` LONGTEXT NULL,
|
||||
`smtp_from` VARCHAR(255) NULL,
|
||||
`smtp_from_name` VARCHAR(255) NULL,
|
||||
`offer_number_pattern` VARCHAR(100) NULL,
|
||||
`order_number_pattern` VARCHAR(100) NULL,
|
||||
`invoice_number_pattern` VARCHAR(100) NULL,
|
||||
|
||||
UNIQUE INDEX `company_settings_uuid_key`(`uuid`),
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
@@ -167,14 +185,18 @@ CREATE TABLE `invoices` (
|
||||
`tax_date` DATE NULL,
|
||||
`paid_date` DATE NULL,
|
||||
`issued_by` VARCHAR(255) NULL,
|
||||
`billing_text` VARCHAR(500) NULL,
|
||||
`language` VARCHAR(5) NULL DEFAULT 'cs',
|
||||
`notes` TEXT NULL,
|
||||
`internal_notes` TEXT NULL,
|
||||
`created_at` DATETIME(0) NULL DEFAULT CURRENT_TIMESTAMP(0),
|
||||
`modified_at` DATETIME(0) NULL,
|
||||
|
||||
UNIQUE INDEX `idx_invoices_number_unique`(`invoice_number`),
|
||||
INDEX `customer_id`(`customer_id`),
|
||||
INDEX `idx_invoices_due_date`(`due_date`),
|
||||
INDEX `idx_invoices_status_issue`(`status`, `issue_date`),
|
||||
INDEX `idx_invoices_status_due`(`status`, `due_date`),
|
||||
INDEX `order_id`(`order_id`),
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
@@ -239,6 +261,7 @@ CREATE TABLE `number_sequences` (
|
||||
`year` INTEGER NULL,
|
||||
`last_number` INTEGER NULL DEFAULT 0,
|
||||
|
||||
UNIQUE INDEX `idx_number_sequences_type_year`(`type`, `year`),
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
@@ -294,6 +317,7 @@ CREATE TABLE `orders` (
|
||||
`created_at` DATETIME(0) NULL DEFAULT CURRENT_TIMESTAMP(0),
|
||||
`modified_at` DATETIME(0) NULL,
|
||||
|
||||
UNIQUE INDEX `idx_orders_number_unique`(`order_number`),
|
||||
INDEX `customer_id`(`customer_id`),
|
||||
INDEX `quotation_id`(`quotation_id`),
|
||||
PRIMARY KEY (`id`)
|
||||
@@ -341,6 +365,7 @@ CREATE TABLE `projects` (
|
||||
`created_at` DATETIME(0) NULL DEFAULT CURRENT_TIMESTAMP(0),
|
||||
`modified_at` DATETIME(0) NULL,
|
||||
|
||||
UNIQUE INDEX `projects_project_number_key`(`project_number`),
|
||||
INDEX `customer_id`(`customer_id`),
|
||||
INDEX `fk_projects_responsible_user`(`responsible_user_id`),
|
||||
INDEX `order_id`(`order_id`),
|
||||
@@ -386,10 +411,13 @@ CREATE TABLE `quotations` (
|
||||
`status` VARCHAR(20) NOT NULL DEFAULT 'active',
|
||||
`scope_title` VARCHAR(500) NULL,
|
||||
`scope_description` TEXT NULL,
|
||||
`locked_by` INTEGER NULL,
|
||||
`locked_at` DATETIME(0) NULL,
|
||||
`uuid` VARCHAR(36) NULL,
|
||||
`modified_at` DATETIME(0) NULL,
|
||||
`sync_version` INTEGER NULL DEFAULT 0,
|
||||
|
||||
UNIQUE INDEX `quotations_quotation_number_key`(`quotation_number`),
|
||||
INDEX `customer_id`(`customer_id`),
|
||||
INDEX `idx_quotations_number`(`quotation_number`),
|
||||
PRIMARY KEY (`id`)
|
||||
@@ -411,7 +439,6 @@ CREATE TABLE `received_invoices` (
|
||||
`due_date` DATE NULL,
|
||||
`paid_date` DATE NULL,
|
||||
`status` ENUM('unpaid', 'paid') NOT NULL DEFAULT 'unpaid',
|
||||
`file_data` MEDIUMBLOB NULL,
|
||||
`file_name` VARCHAR(255) NULL,
|
||||
`file_mime` VARCHAR(100) NULL,
|
||||
`file_size` INTEGER UNSIGNED NULL,
|
||||
@@ -572,6 +599,7 @@ CREATE TABLE `users` (
|
||||
`totp_secret` VARCHAR(255) NULL,
|
||||
`totp_enabled` BOOLEAN NOT NULL DEFAULT false,
|
||||
`totp_backup_codes` TEXT NULL,
|
||||
`totp_last_used_counter` INTEGER NULL,
|
||||
|
||||
UNIQUE INDEX `username`(`username`),
|
||||
UNIQUE INDEX `email`(`email`),
|
||||
@@ -597,12 +625,28 @@ CREATE TABLE `vehicles` (
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `invoice_alert_log` (
|
||||
`id` INTEGER NOT NULL AUTO_INCREMENT,
|
||||
`invoice_type` VARCHAR(20) NOT NULL,
|
||||
`invoice_id` INTEGER NOT NULL,
|
||||
`alert_type` VARCHAR(20) NOT NULL,
|
||||
`sent_at` DATETIME(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0),
|
||||
`created_at` DATETIME(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0),
|
||||
|
||||
UNIQUE INDEX `invoice_type_invoice_id_alert_type`(`invoice_type`, `invoice_id`, `alert_type`),
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `attendance` ADD CONSTRAINT `attendance_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON DELETE CASCADE ON UPDATE NO ACTION;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `attendance_project_logs` ADD CONSTRAINT `attendance_project_logs_attendance_id_fkey` FOREIGN KEY (`attendance_id`) REFERENCES `attendance`(`id`) ON DELETE CASCADE ON UPDATE NO ACTION;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `attendance_project_logs` ADD CONSTRAINT `attendance_project_logs_project_id_fkey` FOREIGN KEY (`project_id`) REFERENCES `projects`(`id`) ON DELETE CASCADE ON UPDATE NO ACTION;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `invoice_items` ADD CONSTRAINT `invoice_items_ibfk_1` FOREIGN KEY (`invoice_id`) REFERENCES `invoices`(`id`) ON DELETE CASCADE ON UPDATE NO ACTION;
|
||||
|
||||
@@ -674,4 +718,3 @@ ALTER TABLE `trips` ADD CONSTRAINT `trips_vehicle_fk` FOREIGN KEY (`vehicle_id`)
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `users` ADD CONSTRAINT `users_ibfk_1` FOREIGN KEY (`role_id`) REFERENCES `roles`(`id`) ON DELETE SET NULL ON UPDATE NO ACTION;
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
# Please do not edit this file manually
|
||||
# It should be added in your version-control system (i.e. Git)
|
||||
# It should be added in your version-control system (e.g., Git)
|
||||
provider = "mysql"
|
||||
|
||||
Reference in New Issue
Block a user