@@ -198,6 +198,35 @@ func (s *ProjectVersionIntegrationTestSuite) TestMarkAsLatestInvalidUUID() {
198198 require .Error (t , err )
199199}
200200
201+ // Regression test for PFM-6470: a version that was deleted and recreated with the
202+ // same name leaves a soft-deleted row alongside the active one. Looking the version
203+ // up by name must return the active row instead of crashing because the query matched
204+ // more than one row.
205+ func (s * ProjectVersionIntegrationTestSuite ) TestFindByProjectAndVersionIgnoresSoftDeleted () {
206+ t := s .T ()
207+ ctx := context .Background ()
208+
209+ // Create a version and soft-delete it, simulating a delete from the UI/API.
210+ deleted , err := s .ProjectVersion .Create (ctx , s .project .ID .String (), "v17" , true )
211+ require .NoError (t , err )
212+
213+ _ , err = s .Data .DB .ProjectVersion .UpdateOneID (deleted .ID ).SetDeletedAt (time .Now ()).Save (ctx )
214+ require .NoError (t , err )
215+
216+ // Recreate a version with the same name; now two rows share version "v17"
217+ // (one soft-deleted, one active).
218+ recreated , err := s .ProjectVersion .Create (ctx , s .project .ID .String (), "v17" , true )
219+ require .NoError (t , err )
220+ require .NotEqual (t , deleted .ID , recreated .ID )
221+
222+ // Looking up "v17" must return the active row, not error out because the query
223+ // matched both the soft-deleted and the active row.
224+ found , err := s .ProjectVersion .FindByProjectAndVersion (ctx , s .project .ID .String (), "v17" )
225+ require .NoError (t , err )
226+ require .NotNil (t , found )
227+ require .Equal (t , recreated .ID , found .ID )
228+ }
229+
201230func TestProjectVersionUseCase (t * testing.T ) {
202231 suite .Run (t , new (ProjectVersionIntegrationTestSuite ))
203232}
0 commit comments