Some checks are pending
Bidi Control Character Guard / bidi-control-guard (push) Waiting to run
Circular Dependency Check / Check for new circular dependencies (push) Waiting to run
Citus Migration Smoke / Combined migrations on single-node Citus (push) Waiting to run
E2E Fresh Install Tests / fresh-install-e2e (push) Waiting to run
ext-v2 guardrails / Run ext-v2 guard and ESLint (push) Waiting to run
Integration Tests / Check for relevant changes (push) Waiting to run
Integration Tests / ${{ (github.event_name == 'schedule' || github.event.inputs.suite == 'full') && 'Full integration suite' || 'Tier-1 integration subset' }} (push) Blocked by required conditions
Mobile checks / Mobile lint + typecheck (push) Waiting to run
Mobile checks / Mobile unit tests (push) Waiting to run
Mobile checks / Mobile dependency audit (report) (push) Waiting to run
Mobile checks / Mobile reproducibility checks (push) Waiting to run
Secrets guard (env backups) / Ensure no tracked env backup files (push) Waiting to run
Temporal Readiness / fast-readiness (push) Waiting to run
Temporal Readiness / docker-parity (push) Waiting to run
TypeScript Type Check / Nx affected typecheck (push) Waiting to run
Unit Tests / Skipped-test budget (push) Waiting to run
Unit Tests / Nx affected unit tests (push) Waiting to run
Unit Tests / Server unit coverage (informational) (push) Waiting to run
Validate Tenant Management Schema / Check for relevant changes (push) Waiting to run
Validate Tenant Management Schema / Validate Tenant Management Schema (push) Blocked by required conditions
EE Workflows Build Guard / ee-workflows-build-guard (push) Waiting to run
Excluded: .git, node_modules, secrets/, compose.env, assemblyscript tgz Source: /opt/alga-psa on psa.joliet.tech
104 lines
4.2 KiB
JavaScript
104 lines
4.2 KiB
JavaScript
'use strict';
|
|
|
|
/**
|
|
* @param { import("knex").Knex } knex
|
|
* @returns { Promise<void> }
|
|
*/
|
|
exports.up = async function(knex) {
|
|
await knex.schema.alterTable('tax_rates', (table) => {
|
|
// Add the new region_code column, initially nullable for data migration phase
|
|
table.string('region_code', 255).nullable();
|
|
|
|
// Drop the old unique constraint involving 'region'
|
|
// Constraint name from schema inspection: tax_rates_tenant_region_start_date_end_date_unique
|
|
table.dropUnique(['tenant', 'region', 'start_date', 'end_date'], 'tax_rates_tenant_region_start_date_end_date_unique');
|
|
});
|
|
|
|
// Add the composite foreign key constraint using raw SQL for clarity with composite keys
|
|
// This links (tenant, region_code) in tax_rates to (tenant, region_code) in tax_regions
|
|
await knex.raw(`
|
|
ALTER TABLE tax_rates
|
|
ADD CONSTRAINT tax_rates_tenant_region_code_fkey
|
|
FOREIGN KEY (tenant, region_code)
|
|
REFERENCES tax_regions (tenant, region_code)
|
|
ON DELETE RESTRICT; -- Using RESTRICT as a safe default
|
|
`);
|
|
|
|
// --- Data Migration: Populate region_code from region ---
|
|
// Update region_code based on the mapping in tax_regions using region_name.
|
|
// This assumes tax_regions is populated and contains matching region_names.
|
|
await knex.raw(`
|
|
UPDATE tax_rates tr
|
|
SET region_code = treg.region_code
|
|
FROM tax_regions treg
|
|
WHERE tr.tenant = treg.tenant
|
|
AND tr.region = treg.region_name
|
|
AND tr.region_code IS NULL;
|
|
`);
|
|
// If any region_code is still NULL here, the next step (NOT NULL constraint)
|
|
// will fail, indicating missing data in tax_regions or inconsistent names.
|
|
// ------------------------------------------------------
|
|
|
|
// Now make region_code non-nullable and drop the old column
|
|
await knex.schema.alterTable('tax_rates', (table) => {
|
|
// Alter column to be non-nullable AFTER potential data migration
|
|
table.string('region_code', 255).notNullable().alter();
|
|
|
|
// Drop the old region column
|
|
table.dropColumn('region');
|
|
|
|
// REMOVED: Unique constraint on ['tenant', 'region_code', 'start_date', 'end_date'].
|
|
// This constraint was removed to allow multiple tax rates (composite taxes)
|
|
// to exist for the same region and overlapping date ranges.
|
|
// The primary key (tax_rate_id) ensures row uniqueness.
|
|
// Business logic will handle aggregation of rates.
|
|
// table.unique(['tenant', 'region_code', 'start_date', 'end_date'], { indexName: 'tax_rates_tenant_region_code_dates_key' });
|
|
|
|
// Add an index specifically on the foreign key columns for query performance
|
|
table.index(['tenant', 'region_code'], 'idx_tax_rates_tenant_region_code');
|
|
});
|
|
};
|
|
|
|
/**
|
|
* @param { import("knex").Knex } knex
|
|
* @returns { Promise<void> }
|
|
*/
|
|
exports.down = async function(knex) {
|
|
await knex.schema.alterTable('tax_rates', (table) => {
|
|
// REMOVED: Corresponding dropUnique for the removed constraint above.
|
|
// table.dropUnique(['tenant', 'region_code', 'start_date', 'end_date'], 'tax_rates_tenant_region_code_dates_key');
|
|
|
|
// Drop the index
|
|
table.dropIndex(['tenant', 'region_code'], 'idx_tax_rates_tenant_region_code');
|
|
|
|
// Add the old 'region' column back (nullable initially)
|
|
table.string('region', 255).nullable(); // Max length from original schema
|
|
});
|
|
|
|
// Drop the foreign key constraint using raw SQL
|
|
await knex.raw(`
|
|
ALTER TABLE tax_rates
|
|
DROP CONSTRAINT IF EXISTS tax_rates_tenant_region_code_fkey;
|
|
`);
|
|
|
|
// --- Data Rollback: Populate region from region_code ---
|
|
// Update the old 'region' column based on the mapping in tax_regions.
|
|
await knex.raw(`
|
|
UPDATE tax_rates tr
|
|
SET region = treg.region_name
|
|
FROM tax_regions treg
|
|
WHERE tr.tenant = treg.tenant
|
|
AND tr.region_code = treg.region_code
|
|
AND tr.region IS NULL;
|
|
`);
|
|
// -----------------------------------------------------
|
|
|
|
await knex.schema.alterTable('tax_rates', (table) => {
|
|
// Drop the 'region_code' column
|
|
table.dropColumn('region_code');
|
|
|
|
// Re-add the old unique constraint
|
|
// Original schema showed 'region' as nullable, so we don't make it non-nullable here.
|
|
table.unique(['tenant', 'region', 'start_date', 'end_date'], { indexName: 'tax_rates_tenant_region_start_date_end_date_unique' }); // Original name
|
|
});
|
|
}; |