-
Notifications
You must be signed in to change notification settings - Fork 22
Hotfix admin deletion qf project middle table #2217
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: staging
Are you sure you want to change the base?
Conversation
WalkthroughAdd a surrogate auto-increment Changes
Sequence Diagram(s)sequenceDiagram
autonumber
participant Migrator
participant DB
Migrator->>DB: check table exists, check `id` column
alt id exists
Migrator->>DB: exit early
else id missing
Migrator->>DB: fetch PK constraints
Migrator->>DB: attempt drop PKs (ignore errors)
alt resetTableStructure path
Migrator->>DB: backup table -> create new table with id SERIAL PK + UNIQUE + indexes -> restore data
else fixConstraintsOnly path
Migrator->>DB: add `id` SERIAL, set as PK, ensure UNIQUE(projectId,qfRoundId), create indexes
end
end
Migrator-->>DB: commit changes
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Suggested reviewers
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🧹 Nitpick comments (1)
src/entities/projectQfRound.ts (1)
1-54: Optional: Explicitly name decorators to match migration
- Consider adding explicit names to @unique and @Index decorators in
ProjectQfRoundto mirror your migration names (e.g.@Unique('UQ_project_qf_rounds_composite', ['projectId', 'qfRoundId']) @Index('IDX_project_qf_rounds_projectId') @Index('IDX_project_qf_rounds_qfRoundId'))
This is purely optional since your codebase convention relies on auto-generated names.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
migration/1779182511001-AddIdToProjectQfRound.ts(1 hunks)src/entities/projectQfRound.ts(1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (16)
migration/1779182511001-AddIdToProjectQfRound.ts (10)
7-11: Good defensive check for table existence.The table existence validation adds safety, though in a properly sequenced migration this should always pass.
23-27: Correctly drops existing composite primary key.The approach is sound. The constraint name is sourced from information_schema, making the SQL injection risk negligible.
42-51: Good addition of indexes for foreign key columns.These indexes will improve join performance and are essential since the columns are no longer part of the primary key. The lack of IF NOT EXISTS is appropriate for a one-time migration.
55-62: Correctly drops indexes with IF EXISTS guards.The defensive IF EXISTS clauses make the rollback more resilient.
64-68: Correctly drops unique constraint with IF EXISTS guard.The defensive IF EXISTS clause makes the rollback more resilient.
70-86: Good conditional logic for dropping id primary key.The dynamic detection of the primary key constraint name before dropping it is robust and handles cases where the migration may have partially failed.
88-92: Correctly drops id column with IF EXISTS guard.The defensive IF EXISTS clause makes the rollback more resilient.
13-21: Verify fallback behavior for missing primary key constraintI couldn’t find other migrations handling missing PK names—ensure this fallback is intentional. Consider throwing an explicit error when
primaryKeyQueryis empty or document why falling back to the default name is safe.
35-40: Composite primary key already guarantees uniqueness
The initial creation migration (1684071046520-create_qfRound_table.ts) definedPRIMARY KEY("projectId","qfRoundId"), so no duplicate(projectId, qfRoundId)pairs can exist and the new UNIQUE constraint will not fail.
29-33: Verify SERIAL PK backfill behavior
Adding aSERIAL PRIMARY KEYwill assign sequentialidvalues (1…N) to all existing rows and set the sequence’s next value toMAX(id)+1. Confirm this aligns with your expectations for the existing junction data.src/entities/projectQfRound.ts (6)
1-12: Imports correctly updated for new decorator usage.The addition of
PrimaryGeneratedColumnandUniquealigns with the schema changes.
20-22: Correct usage of @PrimaryGeneratedColumn() for auto-incrementing primary key.The decorator correctly implements the SERIAL PRIMARY KEY from the migration, using the default "increment" strategy.
24-27: Correctly converted to indexed column.The change from
@PrimaryColumn()to@Column()with@Index()aligns with the migration. Note that TypeORM's auto-generated index name may differ from the migration's explicitIDX_project_qf_rounds_projectId.
29-32: Correctly converted to indexed column.The change from
@PrimaryColumn()to@Column()with@Index()aligns with the migration. Note that TypeORM's auto-generated index name may differ from the migration's explicitIDX_project_qf_rounds_qfRoundId.
34-53: Relations and additional fields correctly preserved.The ManyToOne relations and other fields remain intact, which is appropriate for this schema change focused on the primary key structure.
16-18: Verify absence ofsynchronize: truein TypeORM configTypeORM’s
@Unique(['projectId','qfRoundId'])decorator auto-generates a constraint name (e.g.UQ_<hash>), which won’t match your migration’s explicitUQ_project_qf_rounds_composite. Ensure nosynchronize: trueis enabled in your ORM configuration to prevent schema-sync or migration mismatches.
4879ef5 to
0e49e30
Compare
0e49e30 to
6595f6d
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
♻️ Duplicate comments (1)
migration/1779182511001-AddIdToProjectQfRound.ts (1)
141-146: Hard-coded constraint name may not match original.The composite primary key is restored using the hard-coded name
"PK_project_qf_rounds_qf_round", but the original constraint name (detected dynamically inup()at Line 16-21) might have been different. This creates a naming inconsistency if the migration is rolled back.This issue was already identified in a previous review comment.
🧹 Nitpick comments (1)
migration/1779182511001-AddIdToProjectQfRound.ts (1)
15-60: Simplify the primary key constraint removal logic.The current implementation has redundant fallback logic:
- Lines 27-41: The try-catch with
IF EXISTSfallback is redundant—both branches attempt the same operation- Lines 42-60: The
pg_constraintfallback duplicates the detection logicConsider this streamlined approach:
- // Get the current primary key constraint name - const primaryKeyQuery = await queryRunner.query(` - SELECT constraint_name - FROM information_schema.table_constraints - WHERE table_name = 'project_qf_rounds_qf_round' - AND constraint_type = 'PRIMARY KEY' - `); - - const primaryKeyName = primaryKeyQuery[0]?.constraint_name; - - // Drop the existing composite primary key if it exists - if (primaryKeyName) { - try { - await queryRunner.query(` - ALTER TABLE "project_qf_rounds_qf_round" - DROP CONSTRAINT "${primaryKeyName}" - `); - } catch (error) { - console.log( - `Failed to drop constraint ${primaryKeyName}, trying alternative approach...`, - ); - // Try with IF EXISTS as fallback - await queryRunner.query(` - ALTER TABLE "project_qf_rounds_qf_round" - DROP CONSTRAINT IF EXISTS "${primaryKeyName}" - `); - } - } else { - // Fallback: try to drop with constraint detection - const constraintQuery = await queryRunner.query(` - SELECT conname - FROM pg_constraint - WHERE conrelid = ( - SELECT oid - FROM pg_class - WHERE relname = 'project_qf_rounds_qf_round' - ) AND contype = 'p' - `); - - if (constraintQuery[0]?.conname) { - await queryRunner.query(` - ALTER TABLE "project_qf_rounds_qf_round" - DROP CONSTRAINT "${constraintQuery[0].conname}" - `); - } - } + // Get the current primary key constraint name from pg_constraint + const constraintQuery = await queryRunner.query(` + SELECT conname + FROM pg_constraint + WHERE conrelid = ( + SELECT oid + FROM pg_class + WHERE relname = 'project_qf_rounds_qf_round' + ) AND contype = 'p' + `); + + const primaryKeyName = constraintQuery[0]?.conname; + + // Drop the existing composite primary key if it exists + if (primaryKeyName) { + await queryRunner.query(` + ALTER TABLE "project_qf_rounds_qf_round" + DROP CONSTRAINT IF EXISTS "${primaryKeyName}" + `); + }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
migration/1779182511001-AddIdToProjectQfRound.ts(1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: test
🔇 Additional comments (4)
migration/1779182511001-AddIdToProjectQfRound.ts (4)
7-13: LGTM! Good safety check.The table existence validation prevents migration from proceeding on a missing table, which is a good defensive practice.
62-66: LGTM! Correct PostgreSQL syntax.The
SERIAL PRIMARY KEYdefinition correctly adds an auto-incrementing integer column as the new primary key.
68-84: LGTM! Proper constraint and index setup.The unique constraint on
(projectId, qfRoundId)preserves the original uniqueness guarantee, while the individual indexes optimize lookups on each foreign key column.
88-101: LGTM! Safe rollback of indexes and constraint.The
IF EXISTSclauses make the rollback resilient to partial failures, and the order (indexes before constraint) is correct.
6595f6d to
a2836e5
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (2)
migration/1779182511001-AddIdToProjectQfRound.ts (2)
40-40: Redundant condition check.The
!columnExistscheck on line 40 is redundant because the method already returns early at line 26 whencolumnExistsis true. This condition will always evaluate to true at this point.Apply this diff to simplify the condition:
- if (primaryKeyName && !columnExists) { + if (primaryKeyName) {
186-232: Add inline comment explaining fixed PK constraint nameThe name
"PK_project_qf_rounds_qf_round"is intentionally reused from your initial migration (1684071046520); add a brief comment here to document this convention.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
migration/1779182511001-AddIdToProjectQfRound.ts(1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: test
- GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (4)
migration/1779182511001-AddIdToProjectQfRound.ts (4)
7-27: LGTM! Excellent defensive programming.The table existence check and id column detection provide strong idempotency guarantees, ensuring the migration can safely run multiple times without corruption.
29-82: LGTM! Robust fallback strategy for constraint detection.The multi-tier fallback approach (information_schema → pg_constraint with IF EXISTS) ensures the migration handles various PostgreSQL configurations and edge cases gracefully.
84-138: LGTM! Proper idempotent constraint and index creation.The existence checks before creating the id column, unique constraint, and indexes ensure safe re-execution of the migration.
142-184: LGTM! Proper cleanup of indexes and constraints.The existence checks before dropping indexes and the unique constraint ensure safe rollback without errors on missing objects.
a2836e5 to
7bcadfc
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🧹 Nitpick comments (2)
migration/1779182511001-AddIdToProjectQfRound.ts (2)
38-49: Redundant try/catch when DROP CONSTRAINT IF EXISTS is sufficient.The pattern of attempting
DROP CONSTRAINTwithoutIF EXISTS(lines 39-42), catching the error, then retrying withIF EXISTS(lines 45-48) is redundant. Modern PostgreSQL supportsDROP CONSTRAINT IF EXISTSdirectly, making the initial attempt withoutIF EXISTSunnecessary.Simplify to use
IF EXISTSdirectly:// Drop the existing composite primary key if it exists and if no id column if (primaryKeyName && !columnExists) { - try { - await queryRunner.query(` - ALTER TABLE "project_qf_rounds_qf_round" - DROP CONSTRAINT "${primaryKeyName}" - `); - } catch (error) { - // Try with IF EXISTS as fallback - await queryRunner.query(` - ALTER TABLE "project_qf_rounds_qf_round" - DROP CONSTRAINT IF EXISTS "${primaryKeyName}" - `); - } + await queryRunner.query(` + ALTER TABLE "project_qf_rounds_qf_round" + DROP CONSTRAINT IF EXISTS "${primaryKeyName}" + `);Apply the same simplification to lines 63-74.
198-211: Redundant try/catch when DROP CONSTRAINT IF EXISTS is sufficient.Similar to the
up()method, this try/catch pattern (lines 198-210) is redundant. Modern PostgreSQL supportsDROP CONSTRAINT IF EXISTSdirectly.Simplify to use
IF EXISTSdirectly:if (primaryKeyName) { - try { - // Drop the id primary key constraint - await queryRunner.query(` - ALTER TABLE "project_qf_rounds_qf_round" - DROP CONSTRAINT "${primaryKeyName}" - `); - } catch (error) { - // Fallback with IF EXISTS - await queryRunner.query(` - ALTER TABLE "project_qf_rounds_qf_round" - DROP CONSTRAINT IF EXISTS "${primaryKeyName}" - `); - } + // Drop the id primary key constraint + await queryRunner.query(` + ALTER TABLE "project_qf_rounds_qf_round" + DROP CONSTRAINT IF EXISTS "${primaryKeyName}" + `); }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
migration/1779182511001-AddIdToProjectQfRound.ts(1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: test
🔇 Additional comments (5)
migration/1779182511001-AddIdToProjectQfRound.ts (5)
78-84: LGTM! Properly guarded id column addition.The conditional check ensures the
SERIAL PRIMARY KEYcolumn is only added when absent, and theSERIALtype correctly implements auto-incrementing behavior for the surrogate key.
86-102: LGTM! Unique constraint properly preserves original composite key semantics.The existence check ensures idempotency, and the constraint correctly enforces uniqueness on
(projectId, qfRoundId), maintaining the original composite primary key's uniqueness guarantees after the migration to a surrogate key.
104-132: LGTM! Indexes properly support foreign key lookups.The existence checks ensure idempotency, and creating separate indexes on
projectIdandqfRoundIdwill optimize common query patterns for FK joins and lookups. The naming convention is clear and consistent.
136-178: LGTM! Defensive rollback of indexes and unique constraint.The existence checks prevent errors during rollback, and the operations correctly reverse the schema changes from
up()in the proper order (indexes first, then unique constraint).
220-226: Verify hard-coded constraint name is acceptable.Line 223 restores the composite primary key with the hard-coded name
"PK_project_qf_rounds_qf_round". A previous review comment flagged this as an inconsistency (marked as addressed in commit 6595f6d), sinceup()dynamically detects the original constraint name (lines 27-34) butdown()uses a fixed name.If the original constraint had a different name, this creates a schema inconsistency between the original state and the rolled-back state.
Consider whether the hard-coded name is acceptable for your TypeORM context, or if you should store and restore the original constraint name:
// Only restore composite primary key if id column was actually dropped if (columnExists) { + // Note: This uses TypeORM's default naming convention. + // If the original PK had a different name, this will create a new constraint name. await queryRunner.query(` ALTER TABLE "project_qf_rounds_qf_round" ADD CONSTRAINT "PK_project_qf_rounds_qf_round" PRIMARY KEY ("projectId", "qfRoundId") `); }Alternatively, if exact restoration is required, you could:
- Store the original PK name in a variable at the start of
down()- Query for the original name before dropping the composite PK in
up()- Persist it (e.g., in a metadata table) and retrieve it in
down()
f9a4d6b to
18e7bd0
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
migration/1779182511001-AddIdToProjectQfRound.ts(1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: test
18e7bd0 to
bcde46f
Compare
…://github.com/Giveth/impact-graph into hotfix_admin_deletion_qf_project_middle_table
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
♻️ Duplicate comments (2)
migration/1779182511001-AddIdToProjectQfRound.ts (2)
279-285: Fallback still uses wrong constraint name.The fallback on line 283 attempts to drop
"UQ_project_qf_rounds_qf_round", which is a unique constraint name pattern, not a primary key constraint name. PostgreSQL's auto-generated PK constraints typically use the_pkeysuffix (e.g.,"project_qf_rounds_qf_round_pkey").This issue was previously flagged and marked as addressed in commit a2836e5, but the incorrect constraint name is still present.
Apply this fix to use the correct default PK constraint name:
} else { - // Fallback: drop all possible primary key constraints + // Fallback: try PostgreSQL default PK constraint name await queryRunner.query(` ALTER TABLE "project_qf_rounds_qf_round" - DROP CONSTRAINT IF EXISTS "UQ_project_qf_rounds_qf_round" + DROP CONSTRAINT IF EXISTS "project_qf_rounds_qf_round_pkey" `); }Alternatively, query for all PK constraints and drop them (similar to the approach in
up()):} else { - // Fallback: drop all possible primary key constraints - await queryRunner.query(` - ALTER TABLE "project_qf_rounds_qf_round" - DROP CONSTRAINT IF EXISTS "UQ_project_qf_rounds_qf_round" - `); + // Fallback: drop all PK constraints + const allPKs = await queryRunner.query(` + SELECT conname + FROM pg_constraint + WHERE conrelid = 'project_qf_rounds_qf_round'::regclass + AND contype = 'p' + `); + for (const pk of allPKs) { + await queryRunner.query(` + ALTER TABLE "project_qf_rounds_qf_round" + DROP CONSTRAINT IF EXISTS "${pk.conname}" + `); + } }
22-24: Early return still skips table restructuring.The early return when
idcolumn exists was previously flagged as problematic and marked as addressed, but it's still present. If theidcolumn exists (e.g., from a partial migration or entity sync), this returns immediately and skips:
- The
resetTableStructure()call (line 82)- Unique constraint creation
- Index creation
This creates schema drift between databases.
Consider one of these approaches:
Option 1: Remove the early return and let
resetTableStructure()handle idempotency (it drops and recreates the table, so it's naturally idempotent):- if (idColumnExists) { - return; - } - // Get all primary key constraints for this tableOption 2: If you want to preserve data when
idexists, check for and create missing constraints/indexes:if (idColumnExists) { + // Ensure constraints and indexes exist + await this.fixConstraintsOnly(queryRunner); return; }
🧹 Nitpick comments (2)
migration/1779182511001-AddIdToProjectQfRound.ts (2)
60-66: Use parameterized queries for constraint name checks.Line 62 uses string interpolation for the constraint name, which is a SQL injection anti-pattern. While not exploitable here (the array is hard-coded), this pattern could be copied to contexts where user input is involved.
Use a parameterized query or ensure the constraint name is properly escaped:
const constraintExists = await queryRunner.query(` SELECT 1 FROM pg_constraint - WHERE conname = '${constraintName}' + WHERE conname = $1 AND conrelid = ( SELECT oid FROM pg_class WHERE relname = 'project_qf_rounds_qf_round' ) - `); + `, [constraintName]);
134-237: Unused method: remove or integrate.The
fixConstraintsOnly()method is never called. It appears to be an alternative, safer approach toresetTableStructure()(avoidsDROP TABLE CASCADE), but it's dead code.Either:
Option 1: Remove the unused method to reduce maintenance burden.
Option 2: Use
fixConstraintsOnly()instead ofresetTableStructure()if the id column already exists (as suggested in the earlier comment), since it's safer:if (idColumnExists) { + await this.fixConstraintsOnly(queryRunner); return; }Or replace the
resetTableStructure()call entirely:- // PostgreSQL doesn't support column positioning, so we need to recreate the table - // to have id as the first column - await this.resetTableStructure(queryRunner); + // Fix constraints in place (safer than DROP/CREATE) + await this.fixConstraintsOnly(queryRunner);
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
migration/1779182511001-AddIdToProjectQfRound.ts(1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
migration/1779182511001-AddIdToProjectQfRound.ts (1)
src/utils/logger.ts (1)
logger(44-44)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: test
- GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (1)
migration/1779182511001-AddIdToProjectQfRound.ts (1)
1-2: LGTM!The logger import is correctly added and used appropriately throughout the migration for error handling.
| await queryRunner.query(` | ||
| DROP TABLE IF EXISTS "project_qf_rounds_qf_round" CASCADE | ||
| `); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
CASCADE will drop dependent objects without recreating them.
DROP TABLE ... CASCADE on line 96 will silently drop all dependent database objects:
- Foreign key constraints from other tables
- Views that reference this table
- Triggers
- Stored procedures that reference the table
These dependencies are not recreated after the table is rebuilt, which will break referential integrity and potentially cause application failures.
Either:
Option 1: Remove CASCADE and handle dependencies explicitly:
// Step 2: Drop the problematic table
await queryRunner.query(`
- DROP TABLE IF EXISTS "project_qf_rounds_qf_round" CASCADE
+ DROP TABLE IF EXISTS "project_qf_rounds_qf_round"
`);Then query pg_constraint for foreign keys and recreate them manually after table creation.
Option 2: Document that this migration requires manual restoration of dependent objects, and provide a script to identify what will be dropped:
// Before dropping, log what CASCADE will affect:
const dependencies = await queryRunner.query(`
SELECT
conname AS constraint_name,
confrelid::regclass AS referencing_table
FROM pg_constraint
WHERE confrelid = 'project_qf_rounds_qf_round'::regclass
`);
logger.warn('CASCADE will drop these dependencies:', dependencies);| // Restore the composite primary key | ||
| await queryRunner.query(` | ||
| ALTER TABLE IF EXISTS "project_qf_rounds_qf_round" | ||
| ADD CONSTRAINT "PK_project_qf_rounds_qf_round" | ||
| PRIMARY KEY ("projectId", "qfRoundId") | ||
| `); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hard-coded constraint name may differ from original.
The composite primary key is restored with the hard-coded name "PK_project_qf_rounds_qf_round" (line 296), but the original constraint may have had a different name (e.g., "PK_046d515dee2988817725ec75ebf" as seen in line 52).
This was previously flagged and marked as addressed in commit 6595f6d, but the hard-coded name remains.
While functionally equivalent, this creates a naming inconsistency. Consider dynamically determining the original name if perfect reversibility is required. However, since constraint names don't affect behavior, this may be acceptable if you're standardizing on the new name going forward.
If standardization is not the goal, you could store the original PK name before dropping it in up() and reference it in down():
// In up(), before dropping PKs:
const originalPK = await queryRunner.query(`
SELECT conname
FROM pg_constraint
WHERE conrelid = 'project_qf_rounds_qf_round'::regclass
AND contype = 'p'
LIMIT 1
`);
// Store originalPK[0]?.conname somewhere (e.g., migration metadata table)
// In down():
// Retrieve stored name and use it instead of hard-coded value🤖 Prompt for AI Agents
In migration/1779182511001-AddIdToProjectQfRound.ts around lines 293-298 the
composite PK is recreated with a hard-coded name
"PK_project_qf_rounds_qf_round", which may differ from the original and breaks
perfect reversibility; before dropping the original PK in up(), query
pg_constraint for the existing primary key name on project_qf_rounds_qf_round
and persist that name (e.g., in a simple migration metadata table or a temporary
table/comment), then in down() retrieve and use that persisted name when
re-adding the constraint instead of the hard-coded string so the original
constraint name is restored; alternatively, if you intend to standardize on the
new name, document that decision and leave the new name.
Summary by CodeRabbit
Bug Fixes
Performance
Refactor
Chores