diff --git a/backend/src/entities/table-settings/personal-table-settings/personal-table-settings.controller.ts b/backend/src/entities/table-settings/personal-table-settings/personal-table-settings.controller.ts index 6cce7e763..c5c384e3d 100644 --- a/backend/src/entities/table-settings/personal-table-settings/personal-table-settings.controller.ts +++ b/backend/src/entities/table-settings/personal-table-settings/personal-table-settings.controller.ts @@ -116,8 +116,8 @@ export class PersonalTableSettingsController { columns_view: personalSettingsData.columns_view || null, list_fields: personalSettingsData.list_fields || null, list_per_page: personalSettingsData.list_per_page || null, - ordering: personalSettingsData.ordering || null, - ordering_field: personalSettingsData.ordering_field || null, + ordering: personalSettingsData.ordering, + ordering_field: personalSettingsData.ordering_field, original_names: personalSettingsData.original_names || null, }, }; diff --git a/backend/src/entities/table-settings/personal-table-settings/personal-table-settings.entity.ts b/backend/src/entities/table-settings/personal-table-settings/personal-table-settings.entity.ts index 18a724ac6..6794cd72f 100644 --- a/backend/src/entities/table-settings/personal-table-settings/personal-table-settings.entity.ts +++ b/backend/src/entities/table-settings/personal-table-settings/personal-table-settings.entity.ts @@ -5,49 +5,57 @@ import { UserEntity } from '../../user/user.entity.js'; @Entity('personal_table_settings') export class PersonalTableSettingsEntity { - @PrimaryGeneratedColumn('uuid') - id: string; - - @Column({ default: null }) - table_name: string; - - @Column('enum', { - nullable: false, - enum: QueryOrderingEnum, - default: QueryOrderingEnum.ASC, - }) - ordering!: QueryOrderingEnum; - - @Column('varchar', { default: null }) - ordering_field: string; - - @Column('int', { default: null }) - list_per_page: number; - - @Column('varchar', { array: true, default: {} }) - list_fields: string[]; - - @Column({ type: 'varchar', array: true, default: {} }) - columns_view: Array; - - @Column('boolean', { default: false }) - original_names: boolean; - - @ManyToOne((_) => ConnectionEntity, (connection) => connection.personal_table_settings, { - onDelete: 'CASCADE', - }) - @JoinColumn({ name: 'connection_id' }) - connection: Relation; - - @Column() - connection_id: string; - - @ManyToOne((_) => UserEntity, (user) => user.personal_table_settings, { - onDelete: 'CASCADE', - }) - @JoinColumn({ name: 'user_id' }) - user: Relation; - - @Column() - user_id: string; + @PrimaryGeneratedColumn('uuid') + id: string; + + @Column({ default: null }) + table_name: string; + + @Column('enum', { + nullable: true, + enum: QueryOrderingEnum, + default: null, + }) + ordering!: QueryOrderingEnum; + + @Column('varchar', { default: null }) + ordering_field: string; + + @Column('int', { default: null }) + list_per_page: number; + + @Column('varchar', { array: true, default: {} }) + list_fields: string[]; + + @Column({ type: 'varchar', array: true, default: {} }) + columns_view: Array; + + @Column('boolean', { default: false }) + original_names: boolean; + + @ManyToOne( + (_) => ConnectionEntity, + (connection) => connection.personal_table_settings, + { + onDelete: 'CASCADE', + }, + ) + @JoinColumn({ name: 'connection_id' }) + connection: Relation; + + @Column() + connection_id: string; + + @ManyToOne( + (_) => UserEntity, + (user) => user.personal_table_settings, + { + onDelete: 'CASCADE', + }, + ) + @JoinColumn({ name: 'user_id' }) + user: Relation; + + @Column() + user_id: string; } diff --git a/backend/src/entities/table-settings/personal-table-settings/utils/build-new-personal-table-settings-entity.util.ts b/backend/src/entities/table-settings/personal-table-settings/utils/build-new-personal-table-settings-entity.util.ts index 26ec0ba7b..1d24bf963 100644 --- a/backend/src/entities/table-settings/personal-table-settings/utils/build-new-personal-table-settings-entity.util.ts +++ b/backend/src/entities/table-settings/personal-table-settings/utils/build-new-personal-table-settings-entity.util.ts @@ -1,13 +1,15 @@ import { PersonalTableSettingsData } from '../data-structures/create-personal-table-settings.ds.js'; import { PersonalTableSettingsEntity } from '../personal-table-settings.entity.js'; +const NULLABLE_FIELDS = ['ordering', 'ordering_field']; + export function buildNewPersonalTableSettingsEntity( personalSettingsData: PersonalTableSettingsData, ): PersonalTableSettingsEntity { const newEntity = new PersonalTableSettingsEntity(); Object.assign(newEntity, personalSettingsData); Object.keys(personalSettingsData).forEach((key) => { - if (personalSettingsData[key as keyof PersonalTableSettingsData] === undefined) { + if (personalSettingsData[key as keyof PersonalTableSettingsData] === null && !NULLABLE_FIELDS.includes(key)) { // eslint-disable-next-line security/detect-object-injection delete (newEntity as any)[key]; } diff --git a/backend/src/migrations/1768915268048-MakeOrderingFieldInPersonalTableSettingsEntityNullable.ts b/backend/src/migrations/1768915268048-MakeOrderingFieldInPersonalTableSettingsEntityNullable.ts new file mode 100644 index 000000000..479450853 --- /dev/null +++ b/backend/src/migrations/1768915268048-MakeOrderingFieldInPersonalTableSettingsEntityNullable.ts @@ -0,0 +1,67 @@ +import { MigrationInterface, QueryRunner } from 'typeorm'; + +export class MakeOrderingFieldInPersonalTableSettingsEntityNullable1768915268048 implements MigrationInterface { + name = 'MakeOrderingFieldInPersonalTableSettingsEntityNullable1768915268048'; + + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "secret_access_logs" DROP CONSTRAINT "FK_secret_access_logs_secretId"`); + await queryRunner.query(`ALTER TABLE "secret_access_logs" DROP CONSTRAINT "FK_secret_access_logs_userId"`); + await queryRunner.query(`ALTER TABLE "user_secrets" DROP CONSTRAINT "FK_user_secrets_companyId"`); + await queryRunner.query(`DROP INDEX "public"."IDX_secret_access_logs_secretId"`); + await queryRunner.query(`DROP INDEX "public"."IDX_secret_access_logs_userId"`); + await queryRunner.query(`DROP INDEX "public"."IDX_secret_access_logs_accessedAt"`); + await queryRunner.query(`DROP INDEX "public"."IDX_user_secrets_companyId"`); + await queryRunner.query(`DROP INDEX "public"."IDX_user_secrets_createdAt"`); + await queryRunner.query(`DROP INDEX "public"."IDX_user_secrets_expiresAt"`); + await queryRunner.query(`DROP INDEX "public"."IDX_user_secrets_company_slug"`); + await queryRunner.query(`ALTER TABLE "personal_table_settings" ALTER COLUMN "ordering" DROP NOT NULL`); + await queryRunner.query(`ALTER TABLE "personal_table_settings" ALTER COLUMN "ordering" DROP DEFAULT`); + await queryRunner.query(`CREATE INDEX "IDX_69aeac5d0c61c697346fa2a0f8" ON "secret_access_logs" ("secretId") `); + await queryRunner.query(`CREATE INDEX "IDX_1d02f2dca9278e9a3925f9e797" ON "secret_access_logs" ("userId") `); + await queryRunner.query(`CREATE INDEX "IDX_ab33b550d45b31f76ac35a8c67" ON "secret_access_logs" ("accessedAt") `); + await queryRunner.query(`CREATE INDEX "IDX_8798678e66032251ff48185e96" ON "user_secrets" ("companyId") `); + await queryRunner.query( + `CREATE UNIQUE INDEX "IDX_f39a47aac503fe096b0c77f2b3" ON "user_secrets" ("companyId", "slug") `, + ); + await queryRunner.query( + `ALTER TABLE "secret_access_logs" ADD CONSTRAINT "FK_69aeac5d0c61c697346fa2a0f83" FOREIGN KEY ("secretId") REFERENCES "user_secrets"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, + ); + await queryRunner.query( + `ALTER TABLE "secret_access_logs" ADD CONSTRAINT "FK_1d02f2dca9278e9a3925f9e797f" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, + ); + await queryRunner.query( + `ALTER TABLE "user_secrets" ADD CONSTRAINT "FK_8798678e66032251ff48185e962" FOREIGN KEY ("companyId") REFERENCES "company_info"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, + ); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "user_secrets" DROP CONSTRAINT "FK_8798678e66032251ff48185e962"`); + await queryRunner.query(`ALTER TABLE "secret_access_logs" DROP CONSTRAINT "FK_1d02f2dca9278e9a3925f9e797f"`); + await queryRunner.query(`ALTER TABLE "secret_access_logs" DROP CONSTRAINT "FK_69aeac5d0c61c697346fa2a0f83"`); + await queryRunner.query(`DROP INDEX "public"."IDX_f39a47aac503fe096b0c77f2b3"`); + await queryRunner.query(`DROP INDEX "public"."IDX_8798678e66032251ff48185e96"`); + await queryRunner.query(`DROP INDEX "public"."IDX_ab33b550d45b31f76ac35a8c67"`); + await queryRunner.query(`DROP INDEX "public"."IDX_1d02f2dca9278e9a3925f9e797"`); + await queryRunner.query(`DROP INDEX "public"."IDX_69aeac5d0c61c697346fa2a0f8"`); + await queryRunner.query(`ALTER TABLE "personal_table_settings" ALTER COLUMN "ordering" SET DEFAULT 'ASC'`); + await queryRunner.query(`ALTER TABLE "personal_table_settings" ALTER COLUMN "ordering" SET NOT NULL`); + await queryRunner.query( + `CREATE UNIQUE INDEX "IDX_user_secrets_company_slug" ON "user_secrets" ("companyId", "slug") `, + ); + await queryRunner.query(`CREATE INDEX "IDX_user_secrets_expiresAt" ON "user_secrets" ("expiresAt") `); + await queryRunner.query(`CREATE INDEX "IDX_user_secrets_createdAt" ON "user_secrets" ("createdAt") `); + await queryRunner.query(`CREATE INDEX "IDX_user_secrets_companyId" ON "user_secrets" ("companyId") `); + await queryRunner.query(`CREATE INDEX "IDX_secret_access_logs_accessedAt" ON "secret_access_logs" ("accessedAt") `); + await queryRunner.query(`CREATE INDEX "IDX_secret_access_logs_userId" ON "secret_access_logs" ("userId") `); + await queryRunner.query(`CREATE INDEX "IDX_secret_access_logs_secretId" ON "secret_access_logs" ("secretId") `); + await queryRunner.query( + `ALTER TABLE "user_secrets" ADD CONSTRAINT "FK_user_secrets_companyId" FOREIGN KEY ("companyId") REFERENCES "company_info"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, + ); + await queryRunner.query( + `ALTER TABLE "secret_access_logs" ADD CONSTRAINT "FK_secret_access_logs_userId" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, + ); + await queryRunner.query( + `ALTER TABLE "secret_access_logs" ADD CONSTRAINT "FK_secret_access_logs_secretId" FOREIGN KEY ("secretId") REFERENCES "user_secrets"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, + ); + } +}