This commit is contained in:
@@ -0,0 +1,355 @@
|
||||
import assert from 'node:assert/strict';
|
||||
import { createHash, randomUUID } from 'node:crypto';
|
||||
import test, { after } from 'node:test';
|
||||
import { and, eq, inArray } from 'drizzle-orm';
|
||||
import {
|
||||
accounts,
|
||||
activities,
|
||||
allocations,
|
||||
capacityCommitments,
|
||||
createDatabase,
|
||||
demandDeals,
|
||||
invites,
|
||||
teamMemberships,
|
||||
users,
|
||||
} from '@pig/db';
|
||||
import { createApp } from '../src/app';
|
||||
import { loadConfig } from '../src/lib/config';
|
||||
|
||||
const databaseUrl = process.env.DATABASE_URL;
|
||||
if (!databaseUrl) throw new Error('DATABASE_URL is required for the critical-path E2E test.');
|
||||
|
||||
const db = createDatabase({ url: databaseUrl, max: 4 });
|
||||
|
||||
after(async () => {
|
||||
await db.$client.end();
|
||||
});
|
||||
|
||||
test('invite-bound member creates, sells and observes capacity through authenticated HTTP', async () => {
|
||||
const suffix = randomUUID();
|
||||
const email = `e2e-${suffix}@example.test`;
|
||||
const subject = randomUUID();
|
||||
const accessToken = `e2e-token-${suffix}`;
|
||||
const inviteCode = `invite-${suffix}`;
|
||||
const startsAt = new Date('2027-01-01T00:00:00.000Z');
|
||||
const endsAt = new Date('2027-01-01T10:00:00.000Z');
|
||||
let inviteId: string | undefined;
|
||||
let userId: string | undefined;
|
||||
let supplyAccountId: string | undefined;
|
||||
let demandAccountId: string | undefined;
|
||||
let demandDealId: string | undefined;
|
||||
let commitmentId: string | undefined;
|
||||
let allocationId: string | undefined;
|
||||
|
||||
const config = loadConfig({
|
||||
...process.env,
|
||||
NODE_ENV: 'production',
|
||||
DATABASE_URL: databaseUrl,
|
||||
PIG_PUBLIC_URL: 'https://pig-e2e.invalid',
|
||||
SUPABASE_URL: 'https://identity-e2e.invalid',
|
||||
SUPABASE_ANON_KEY: 'e2e-anon-key',
|
||||
SUPABASE_SERVICE_KEY: '',
|
||||
PIG_ADMIN_EMAILS: '',
|
||||
PIGGY_ENABLED: 'false',
|
||||
});
|
||||
const authProvider = {
|
||||
async verifyAccessToken(token: string) {
|
||||
if (token !== accessToken) throw new Error('Invalid E2E token.');
|
||||
return { subject, email };
|
||||
},
|
||||
};
|
||||
const app = createApp(config, db, authProvider);
|
||||
|
||||
try {
|
||||
const [invite] = await db
|
||||
.insert(invites)
|
||||
.values({
|
||||
codeHash: createHash('sha256').update(inviteCode).digest('hex'),
|
||||
email,
|
||||
usesRemaining: 1,
|
||||
})
|
||||
.returning();
|
||||
assert.ok(invite);
|
||||
inviteId = invite.id;
|
||||
|
||||
// A valid external identity is authentication, not workspace membership.
|
||||
const ungatedSignup = await request(app, '/api/signup', {
|
||||
token: accessToken,
|
||||
body: { name: 'E2E Capacity Seller', team: 'supply' },
|
||||
});
|
||||
assert.equal(ungatedSignup.status, 403);
|
||||
assert.equal(ungatedSignup.body.code, 'invite_required');
|
||||
const uninvitedUsers = await db.select().from(users).where(eq(users.email, email));
|
||||
assert.equal(uninvitedUsers.length, 0);
|
||||
|
||||
// The password registration route also stays closed without its provider
|
||||
// administration credential; the injected verifier is not a bypass.
|
||||
const openRegistration = await request(app, '/api/register', {
|
||||
body: {
|
||||
email,
|
||||
password: 'not-a-production-password',
|
||||
name: 'E2E Capacity Seller',
|
||||
team: 'supply',
|
||||
inviteCode,
|
||||
},
|
||||
});
|
||||
assert.equal(openRegistration.status, 503);
|
||||
assert.equal(openRegistration.body.code, 'registration_unavailable');
|
||||
|
||||
const signup = await request(app, '/api/signup', {
|
||||
token: accessToken,
|
||||
body: {
|
||||
name: 'E2E Capacity Seller',
|
||||
team: 'supply',
|
||||
title: 'Capacity lead',
|
||||
inviteCode,
|
||||
},
|
||||
});
|
||||
assert.equal(signup.status, 201);
|
||||
const signupUser = record(signup.body.user, 'signup user');
|
||||
userId = text(signupUser.id, 'signup user id');
|
||||
assert.equal(signupUser.email, email);
|
||||
assert.equal(signupUser.isPlatformAdmin, false);
|
||||
|
||||
const [consumedInvite] = await db
|
||||
.select()
|
||||
.from(invites)
|
||||
.where(eq(invites.id, inviteId));
|
||||
assert.ok(consumedInvite);
|
||||
assert.equal(consumedInvite.usesRemaining, 0);
|
||||
assert.equal(consumedInvite.redeemedByUserId, userId);
|
||||
|
||||
// Fixture setup grants only the two capabilities this path needs. Product
|
||||
// writes below still pass through the real authorization middleware.
|
||||
await db
|
||||
.update(teamMemberships)
|
||||
.set({ role: 'lead' })
|
||||
.where(
|
||||
and(
|
||||
eq(teamMemberships.userId, userId),
|
||||
eq(teamMemberships.team, 'supply'),
|
||||
),
|
||||
);
|
||||
await db.insert(teamMemberships).values({
|
||||
userId,
|
||||
team: 'demand',
|
||||
role: 'member',
|
||||
isPrimary: false,
|
||||
});
|
||||
|
||||
const me = await request(app, '/api/me', { token: accessToken, method: 'GET' });
|
||||
assert.equal(me.status, 200);
|
||||
assert.equal(me.body.id, userId);
|
||||
assert.equal(me.body.via, 'jwt');
|
||||
const grants = array(me.body.permissions, 'permissions');
|
||||
assert.ok(
|
||||
grants.some(
|
||||
(grant) =>
|
||||
record(grant, 'permission').capability === 'commitment:write' &&
|
||||
record(grant, 'permission').team === 'supply',
|
||||
),
|
||||
);
|
||||
assert.ok(
|
||||
grants.some(
|
||||
(grant) =>
|
||||
record(grant, 'permission').capability === 'deal:write' &&
|
||||
record(grant, 'permission').team === 'demand',
|
||||
),
|
||||
);
|
||||
|
||||
const [supplyAccount, demandAccount] = await Promise.all([
|
||||
db
|
||||
.insert(accounts)
|
||||
.values({ name: `E2E Supply ${suffix}`, side: 'supply' })
|
||||
.returning()
|
||||
.then(([row]) => row),
|
||||
db
|
||||
.insert(accounts)
|
||||
.values({ name: `E2E Demand ${suffix}`, side: 'demand' })
|
||||
.returning()
|
||||
.then(([row]) => row),
|
||||
]);
|
||||
assert.ok(supplyAccount);
|
||||
assert.ok(demandAccount);
|
||||
supplyAccountId = supplyAccount.id;
|
||||
demandAccountId = demandAccount.id;
|
||||
|
||||
const [deal] = await db
|
||||
.insert(demandDeals)
|
||||
.values({
|
||||
accountId: demandAccount.id,
|
||||
name: `E2E Reserved Cluster ${suffix}`,
|
||||
stage: 'deployment',
|
||||
productLine: 'compute_reserved',
|
||||
ownerUserId: userId,
|
||||
})
|
||||
.returning();
|
||||
assert.ok(deal);
|
||||
demandDealId = deal.id;
|
||||
|
||||
const baselineMarginResponse = await request(app, '/api/capacity/margin', {
|
||||
token: accessToken,
|
||||
method: 'GET',
|
||||
});
|
||||
assert.equal(baselineMarginResponse.status, 200);
|
||||
const baselineMargin = marginTotals(baselineMarginResponse.body);
|
||||
|
||||
const commitmentResponse = await request(app, '/api/commitments', {
|
||||
token: accessToken,
|
||||
body: {
|
||||
accountId: supplyAccount.id,
|
||||
name: `E2E Eight-GPU Block ${suffix}`,
|
||||
gpuType: 'H100_80GB',
|
||||
gpuCount: 8,
|
||||
interconnectType: 'Unknown',
|
||||
securityTier: 'secure_cloud',
|
||||
startsAt: startsAt.toISOString(),
|
||||
endsAt: endsAt.toISOString(),
|
||||
totalGpuHours: 80,
|
||||
costPerGpuHourCents: 100,
|
||||
},
|
||||
});
|
||||
assert.equal(commitmentResponse.status, 200);
|
||||
commitmentId = text(commitmentResponse.body.id, 'commitment id');
|
||||
|
||||
const availabilityBefore = await request(app, '/api/capacity/availability', {
|
||||
token: accessToken,
|
||||
method: 'GET',
|
||||
});
|
||||
assert.equal(availabilityBefore.status, 200);
|
||||
const capacityBefore = findById(
|
||||
array(availabilityBefore.body, 'availability'),
|
||||
'commitmentId',
|
||||
commitmentId,
|
||||
);
|
||||
assert.equal(capacityBefore.totalGpuHours, 80);
|
||||
assert.equal(capacityBefore.soldGpuHours, 0);
|
||||
assert.equal(capacityBefore.availableGpuHours, 80);
|
||||
|
||||
const marginBeforeResponse = await request(app, '/api/capacity/margin', {
|
||||
token: accessToken,
|
||||
method: 'GET',
|
||||
});
|
||||
assert.equal(marginBeforeResponse.status, 200);
|
||||
const marginBefore = marginTotals(marginBeforeResponse.body);
|
||||
assert.equal(marginBefore.revenueCents - baselineMargin.revenueCents, 0);
|
||||
assert.equal(marginBefore.costCents - baselineMargin.costCents, 8_000);
|
||||
assert.equal(marginBefore.grossMarginCents - baselineMargin.grossMarginCents, -8_000);
|
||||
|
||||
const allocationResponse = await request(app, '/api/allocations', {
|
||||
token: accessToken,
|
||||
body: {
|
||||
capacityCommitmentId: commitmentId,
|
||||
demandDealId: deal.id,
|
||||
gpuHours: 40,
|
||||
pricePerGpuHourCents: 300,
|
||||
startsAt: startsAt.toISOString(),
|
||||
endsAt: endsAt.toISOString(),
|
||||
status: 'committed',
|
||||
},
|
||||
});
|
||||
assert.equal(allocationResponse.status, 200);
|
||||
allocationId = text(allocationResponse.body.id, 'allocation id');
|
||||
|
||||
const availabilityAfter = await request(app, '/api/capacity/availability', {
|
||||
token: accessToken,
|
||||
method: 'GET',
|
||||
});
|
||||
const capacityAfter = findById(
|
||||
array(availabilityAfter.body, 'availability'),
|
||||
'commitmentId',
|
||||
commitmentId,
|
||||
);
|
||||
assert.equal(capacityAfter.soldGpuHours, 40);
|
||||
assert.equal(capacityAfter.heldGpuHours, 0);
|
||||
assert.equal(capacityAfter.availableGpuHours, 40);
|
||||
assert.equal(capacityAfter.utilisation, 0.5);
|
||||
|
||||
const marginAfterResponse = await request(app, '/api/capacity/margin', {
|
||||
token: accessToken,
|
||||
method: 'GET',
|
||||
});
|
||||
assert.equal(marginAfterResponse.status, 200);
|
||||
const marginAfter = marginTotals(marginAfterResponse.body);
|
||||
assert.equal(marginAfter.revenueCents - marginBefore.revenueCents, 12_000);
|
||||
// The full block remains the cost basis even though only half was sold.
|
||||
assert.equal(marginAfter.costCents - marginBefore.costCents, 0);
|
||||
assert.equal(marginAfter.grossMarginCents - marginBefore.grossMarginCents, 12_000);
|
||||
assert.equal(marginAfter.grossMarginCents - baselineMargin.grossMarginCents, 4_000);
|
||||
} finally {
|
||||
if (allocationId) await db.delete(allocations).where(eq(allocations.id, allocationId));
|
||||
if (commitmentId) {
|
||||
await db.delete(capacityCommitments).where(eq(capacityCommitments.id, commitmentId));
|
||||
}
|
||||
if (demandDealId) await db.delete(demandDeals).where(eq(demandDeals.id, demandDealId));
|
||||
if (userId) await db.delete(activities).where(eq(activities.actorUserId, userId));
|
||||
const accountIds = [supplyAccountId, demandAccountId].filter(
|
||||
(id): id is string => id !== undefined,
|
||||
);
|
||||
if (accountIds.length) await db.delete(accounts).where(inArray(accounts.id, accountIds));
|
||||
if (inviteId) await db.delete(invites).where(eq(invites.id, inviteId));
|
||||
if (userId) await db.delete(users).where(eq(users.id, userId));
|
||||
}
|
||||
});
|
||||
|
||||
async function request(
|
||||
app: ReturnType<typeof createApp>,
|
||||
path: string,
|
||||
options: { token?: string; body?: unknown; method?: 'GET' | 'POST' } = {},
|
||||
): Promise<{ status: number; body: Record<string, unknown> }> {
|
||||
const response = await app.request(path, {
|
||||
method: options.method ?? 'POST',
|
||||
headers: {
|
||||
...(options.token ? { authorization: `Bearer ${options.token}` } : {}),
|
||||
...(options.body === undefined ? {} : { 'content-type': 'application/json' }),
|
||||
},
|
||||
...(options.body === undefined ? {} : { body: JSON.stringify(options.body) }),
|
||||
});
|
||||
return {
|
||||
status: response.status,
|
||||
body: (await response.json()) as Record<string, unknown>,
|
||||
};
|
||||
}
|
||||
|
||||
function record(value: unknown, label: string): Record<string, unknown> {
|
||||
assert.ok(value && typeof value === 'object' && !Array.isArray(value), `${label} must be an object`);
|
||||
return value as Record<string, unknown>;
|
||||
}
|
||||
|
||||
function array(value: unknown, label: string): unknown[] {
|
||||
assert.ok(Array.isArray(value), `${label} must be an array`);
|
||||
return value;
|
||||
}
|
||||
|
||||
function text(value: unknown, label: string): string {
|
||||
if (typeof value !== 'string') {
|
||||
assert.fail(`${label} must be a string`);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
function findById(rows: unknown[], field: string, id: string): Record<string, unknown> {
|
||||
const found = rows.map((row) => record(row, 'row')).find((row) => row[field] === id);
|
||||
assert.ok(found, `Expected ${field}=${id}`);
|
||||
return found;
|
||||
}
|
||||
|
||||
function marginTotals(body: Record<string, unknown>): {
|
||||
revenueCents: number;
|
||||
costCents: number;
|
||||
grossMarginCents: number;
|
||||
} {
|
||||
const totals = record(body.totals, 'margin totals');
|
||||
return {
|
||||
revenueCents: number(totals.revenueCents, 'margin revenue'),
|
||||
costCents: number(totals.costCents, 'margin cost'),
|
||||
grossMarginCents: number(totals.grossMarginCents, 'gross margin'),
|
||||
};
|
||||
}
|
||||
|
||||
function number(value: unknown, label: string): number {
|
||||
if (typeof value !== 'number') {
|
||||
assert.fail(`${label} must be a number`);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
Reference in New Issue
Block a user