@@ -2,7 +2,7 @@ import { expect } from 'chai';
22import supertest from 'supertest' ;
33import app from '../../../src/server.js' ;
44import { prepareV2Db } from '../../../src/database/v2/index.js' ;
5- import { StagingV2 , ProjectV2 , ProgramV2 , LocationV2 , EstimationV2 , RatingV2 , CoBenefitV2 , ValidationV2 , VerificationV2 , MethodologyV2 , ProjectMethodologyV2 , StakeholderV2 , StakeholderProjectV2 , IssuanceV2 , UnitV2 , LabelV2 , UnitLabelV2 } from '../../../src/models/v2/index.js' ;
5+ import { StagingV2 , ProjectV2 , ProgramV2 , LocationV2 , EstimationV2 , RatingV2 , CoBenefitV2 , ValidationV2 , VerificationV2 , MethodologyV2 , ProjectMethodologyV2 , StakeholderV2 , StakeholderProjectV2 , IssuanceV2 , UnitV2 , LabelV2 , UnitLabelV2 , AefT1SubmissionV2 , AefT5AuthorizedEntitiesV2 } from '../../../src/models/v2/index.js' ;
66import { v4 as uuidv4 } from 'uuid' ;
77
88import {
@@ -1244,6 +1244,103 @@ describe('V2 Project API - Basic CRUD Tests', function () {
12441244 }
12451245 } ) ;
12461246
1247+ it ( 'should return 409 when AEF records reference this project' , async function ( ) {
1248+ const chain = await createV2TestProgramChain ( { testId : `PROJ-AEF-PROJ-${ uuidv4 ( ) . slice ( 0 , 8 ) } ` } ) ;
1249+ const t1 = await AefT1SubmissionV2 . create ( {
1250+ cadTrustAefT1SubmissionId : uuidv4 ( ) ,
1251+ aefT1SubmissionParty : 'Project reference guard party' ,
1252+ aefT1SubmissionVersion : '1.0' ,
1253+ aefT1SubmissionReportYear : 2024 ,
1254+ aefT1SubmissionSubmissionDate : '2024-01-15' ,
1255+ } ) ;
1256+ await AefT5AuthorizedEntitiesV2 . create ( {
1257+ cadTrustAefT5AuthorizedEntitiesId : uuidv4 ( ) ,
1258+ aefT5AuthorizedEntitiesAuthorizationDate : '2024-01-15' ,
1259+ aefT5AuthorizedEntitiesName : 'Project reference guard entity' ,
1260+ aefT5AuthorizedEntitiesId : `PROJ-REF-AE-${ uuidv4 ( ) . slice ( 0 , 6 ) } ` ,
1261+ aefT5AuthorizedEntitiesCooperativeApproachId : `PROJ-REF-CA-${ uuidv4 ( ) . slice ( 0 , 6 ) } ` ,
1262+ cadTrustAefT1SubmissionId : t1 . cadTrustAefT1SubmissionId ,
1263+ cadTrustProjectId : chain . project . cadTrustProjectId ,
1264+ } ) ;
1265+
1266+ const response = await supertest ( app )
1267+ . delete ( `/v2/project/${ chain . project . cadTrustProjectId } ` )
1268+ . expect ( 409 ) ;
1269+
1270+ expect ( response . body . success ) . to . be . false ;
1271+ expect ( response . body . error ) . to . equal ( 'Referenced records must be removed before deletion' ) ;
1272+ expect ( response . body . references ) . to . deep . include ( { table : 'aef_t5_authorized_entities' , count : 1 } ) ;
1273+
1274+ const stagingDeletes = await StagingV2 . findAll ( {
1275+ where : { table : 'project' , action : 'DELETE' } ,
1276+ raw : true ,
1277+ } ) ;
1278+ const projectDelete = stagingDeletes . find ( ( row ) => {
1279+ const data = JSON . parse ( row . data ) ;
1280+ return data [ 0 ] ?. cad_trust_project_id === chain . project . cadTrustProjectId ;
1281+ } ) ;
1282+ expect ( projectDelete ) . to . be . undefined ;
1283+ } ) ;
1284+
1285+ it ( 'should return 409 when cascade unit has AEF references' , async function ( ) {
1286+ const homeOrgId = await getV2HomeOrgId ( ) ;
1287+ const chain = await createV2TestProgramChain ( { testId : `PROJ-AEF-GUARD-${ uuidv4 ( ) . slice ( 0 , 8 ) } ` } ) ;
1288+ const unit = await UnitV2 . create ( addUuidIfNeeded ( 'UnitV2' , {
1289+ unitSerialId : `PROJ-AEF-UNIT-${ uuidv4 ( ) . slice ( 0 , 8 ) } ` ,
1290+ unitStartBlock : '1' ,
1291+ unitEndBlock : '100' ,
1292+ unitCount : 50 ,
1293+ unitType : 'Avoidance - nature' ,
1294+ unitVintageYear : 2024 ,
1295+ unitStatus : 'Issued' ,
1296+ unitMetric : 'tCO2e' ,
1297+ cadTrustIssuanceId : chain . issuance . cadTrustIssuanceId ,
1298+ orgUid : homeOrgId ,
1299+ } ) ) ;
1300+ const t1 = await AefT1SubmissionV2 . create ( {
1301+ cadTrustAefT1SubmissionId : uuidv4 ( ) ,
1302+ aefT1SubmissionParty : 'Project cascade guard party' ,
1303+ aefT1SubmissionVersion : '1.0' ,
1304+ aefT1SubmissionReportYear : 2024 ,
1305+ aefT1SubmissionSubmissionDate : '2024-01-15' ,
1306+ } ) ;
1307+ await AefT5AuthorizedEntitiesV2 . create ( {
1308+ cadTrustAefT5AuthorizedEntitiesId : uuidv4 ( ) ,
1309+ aefT5AuthorizedEntitiesAuthorizationDate : '2024-01-15' ,
1310+ aefT5AuthorizedEntitiesName : 'Project cascade guard entity' ,
1311+ aefT5AuthorizedEntitiesId : `PROJ-AE-${ uuidv4 ( ) . slice ( 0 , 6 ) } ` ,
1312+ aefT5AuthorizedEntitiesCooperativeApproachId : `PROJ-CA-${ uuidv4 ( ) . slice ( 0 , 6 ) } ` ,
1313+ cadTrustAefT1SubmissionId : t1 . cadTrustAefT1SubmissionId ,
1314+ cadTrustUnitId : unit . cadTrustUnitId ,
1315+ cadTrustProjectId : null ,
1316+ } ) ;
1317+
1318+ const response = await supertest ( app )
1319+ . delete ( `/v2/project/${ chain . project . cadTrustProjectId } ` )
1320+ . expect ( 409 ) ;
1321+
1322+ expect ( response . body . success ) . to . be . false ;
1323+ expect ( response . body . error ) . to . equal ( 'Referenced records must be removed before deletion' ) ;
1324+ expect ( response . body . references ) . to . deep . include ( { table : 'aef_t5_authorized_entities' , count : 1 } ) ;
1325+
1326+ const stagingDeletes = await StagingV2 . findAll ( {
1327+ where : { action : 'DELETE' } ,
1328+ raw : true ,
1329+ } ) ;
1330+ const projectDelete = stagingDeletes . find ( ( row ) => {
1331+ if ( row . table !== 'project' ) return false ;
1332+ const data = JSON . parse ( row . data ) ;
1333+ return data [ 0 ] ?. cad_trust_project_id === chain . project . cadTrustProjectId ;
1334+ } ) ;
1335+ const unitDelete = stagingDeletes . find ( ( row ) => {
1336+ if ( row . table !== 'unit' ) return false ;
1337+ const data = JSON . parse ( row . data ) ;
1338+ return data [ 0 ] ?. cad_trust_unit_id === unit . cadTrustUnitId ;
1339+ } ) ;
1340+ expect ( projectDelete ) . to . be . undefined ;
1341+ expect ( unitDelete ) . to . be . undefined ;
1342+ } ) ;
1343+
12471344 it ( 'should return 409 when another project references this project' , async function ( ) {
12481345 const homeOrgId = await getV2HomeOrgId ( ) ;
12491346 const program = await ProgramV2 . create ( {
0 commit comments