This commit is contained in:
@@ -0,0 +1,159 @@
|
||||
import { strict as assert } from 'node:assert';
|
||||
import { describe, it } from 'node:test';
|
||||
import type { Contract, SlaTerm } from '@pig/db';
|
||||
import {
|
||||
renewalAlarm,
|
||||
resolveContractPrecedence,
|
||||
validateParentRelationship,
|
||||
} from '../src/services/contracts';
|
||||
|
||||
function contract(overrides: Partial<Contract>): Contract {
|
||||
return {
|
||||
id: '10000000-0000-4000-8000-000000000001',
|
||||
accountId: '20000000-0000-4000-8000-000000000002',
|
||||
type: 'msa',
|
||||
status: 'executed',
|
||||
side: 'demand',
|
||||
title: 'Master agreement',
|
||||
externalReference: null,
|
||||
demandDealId: null,
|
||||
supplyDealId: null,
|
||||
capacityCommitmentId: null,
|
||||
parentContractId: null,
|
||||
contractingPartyName: null,
|
||||
takeOrPayFloorPct: null,
|
||||
prepaidPct: null,
|
||||
terminationTier: null,
|
||||
assignableOnDefault: false,
|
||||
assignmentDeadlineBusinessDays: null,
|
||||
effectiveAt: null,
|
||||
expiresAt: null,
|
||||
executedAt: null,
|
||||
terminatedAt: null,
|
||||
isAutoRenew: false,
|
||||
noticeDays: null,
|
||||
valueCents: null,
|
||||
currency: 'USD',
|
||||
governingLaw: null,
|
||||
documentUrl: null,
|
||||
ownerUserId: null,
|
||||
notes: null,
|
||||
createdAt: new Date('2026-01-01T00:00:00.000Z'),
|
||||
updatedAt: new Date('2026-01-01T00:00:00.000Z'),
|
||||
...overrides,
|
||||
};
|
||||
}
|
||||
|
||||
function sla(overrides: Partial<SlaTerm>): SlaTerm {
|
||||
return {
|
||||
id: '30000000-0000-4000-8000-000000000003',
|
||||
contractId: '10000000-0000-4000-8000-000000000001',
|
||||
kind: 'negotiated',
|
||||
uptimeTargetPct: null,
|
||||
nodeReplacementHours: null,
|
||||
mttrHours: null,
|
||||
supportResponseHours: null,
|
||||
measurementWindow: 'monthly',
|
||||
measurementUnit: 'cluster',
|
||||
remedyType: 'service_credit',
|
||||
abatementTriggerValue: null,
|
||||
abatementTriggerUnit: null,
|
||||
claimDeadlineValue: null,
|
||||
claimDeadlineUnit: 'days',
|
||||
creditExpiryMonths: null,
|
||||
isSoleRemedy: true,
|
||||
sparePoolObligation: null,
|
||||
sparePoolScope: [],
|
||||
maintenanceClasses: [],
|
||||
reasonableEndeavoursDaysPerYear: null,
|
||||
rcaDeliveryHours: null,
|
||||
creditSchedule: [],
|
||||
creditCapPct: null,
|
||||
exclusions: null,
|
||||
createdAt: new Date('2026-01-01T00:00:00.000Z'),
|
||||
updatedAt: new Date('2026-01-01T00:00:00.000Z'),
|
||||
...overrides,
|
||||
};
|
||||
}
|
||||
|
||||
describe('contract precedence', () => {
|
||||
it('uses explicit order-form terms before the MSA without copying inherited values', () => {
|
||||
const master = contract({ takeOrPayFloorPct: '70.00', prepaidPct: '25.00' });
|
||||
const order = contract({
|
||||
id: '10000000-0000-4000-8000-000000000004',
|
||||
type: 'order_form',
|
||||
title: 'Order form',
|
||||
parentContractId: master.id,
|
||||
takeOrPayFloorPct: '90.00',
|
||||
});
|
||||
const resolved = resolveContractPrecedence(order.id, [master, order], [
|
||||
sla({ uptimeTargetPct: '99.900' }),
|
||||
]);
|
||||
|
||||
const floor = resolved.contract.takeOrPayFloorPct;
|
||||
const prepaid = resolved.contract.prepaidPct;
|
||||
const uptime = resolved.sla.uptimeTargetPct;
|
||||
assert.ok(floor);
|
||||
assert.ok(prepaid);
|
||||
assert.ok(uptime);
|
||||
|
||||
assert.equal(floor.value, '90.00');
|
||||
assert.equal(floor.inherited, false);
|
||||
assert.equal(prepaid.value, '25.00');
|
||||
assert.equal(prepaid.inherited, true);
|
||||
assert.equal(uptime.sourceContractId, master.id);
|
||||
});
|
||||
|
||||
it('treats false, zero and an empty list as deliberate child overrides', () => {
|
||||
const master = contract({ assignableOnDefault: true });
|
||||
const child = contract({
|
||||
id: '10000000-0000-4000-8000-000000000004',
|
||||
parentContractId: master.id,
|
||||
assignableOnDefault: false,
|
||||
});
|
||||
const resolved = resolveContractPrecedence(child.id, [master, child], [
|
||||
sla({ sparePoolScope: ['compute nodes', 'network switches'] }),
|
||||
sla({
|
||||
id: '30000000-0000-4000-8000-000000000004',
|
||||
contractId: child.id,
|
||||
reasonableEndeavoursDaysPerYear: 0,
|
||||
sparePoolScope: [],
|
||||
}),
|
||||
]);
|
||||
|
||||
const assignable = resolved.contract.assignableOnDefault;
|
||||
const reasonableEndeavours = resolved.sla.reasonableEndeavoursDaysPerYear;
|
||||
const sparePoolScope = resolved.sla.sparePoolScope;
|
||||
assert.ok(assignable);
|
||||
assert.ok(reasonableEndeavours);
|
||||
assert.ok(sparePoolScope);
|
||||
|
||||
assert.equal(assignable.value, false);
|
||||
assert.equal(reasonableEndeavours.value, 0);
|
||||
assert.deepEqual(sparePoolScope.value, []);
|
||||
});
|
||||
});
|
||||
|
||||
describe('contract alarms and hierarchy', () => {
|
||||
it('raises the renewal alarm at the negotiated notice deadline, not at expiry', () => {
|
||||
const result = renewalAlarm(
|
||||
{
|
||||
isAutoRenew: true,
|
||||
expiresAt: new Date('2026-04-01T00:00:00.000Z'),
|
||||
noticeDays: 60,
|
||||
},
|
||||
new Date('2026-02-15T00:00:00.000Z'),
|
||||
);
|
||||
assert.equal(result.renewalNoticeAt?.toISOString(), '2026-01-31T00:00:00.000Z');
|
||||
assert.equal(result.renewalState, 'due');
|
||||
});
|
||||
|
||||
it('rejects cross-account parentage even when both records otherwise look valid', () => {
|
||||
const child = contract({ id: '10000000-0000-4000-8000-000000000004' });
|
||||
const parent = contract({ accountId: '20000000-0000-4000-8000-000000000009' });
|
||||
assert.equal(
|
||||
validateParentRelationship(child, parent, []),
|
||||
'Parent and child contracts must belong to the same account.',
|
||||
);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user