Build the agent-native compute CRM platform
CI / verify (push) Successful in 3m6s

This commit is contained in:
2026-08-13 01:39:01 -07:00
parent bfd2f8d95a
commit 853bde2265
160 changed files with 61812 additions and 483 deletions
+567
View File
@@ -0,0 +1,567 @@
import { useEffect, useMemo, useState } from 'react';
import { zodResolver } from '@hookform/resolvers/zod';
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
import {
CONSUMING_ALLOCATION_STATUSES,
GUARANTEE_TYPES,
RESERVING_ALLOCATION_STATUSES,
} from '@pig/core';
import { AlertTriangle, Clock3, LoaderCircle, RotateCcw, ShieldCheck } from 'lucide-react';
import { useForm, type Control, type FieldPath, type FieldValues } from 'react-hook-form';
import { z } from 'zod';
import { Badge, Button, Input } from '@/components/ui';
import {
Form,
FormControl,
FormDescription,
FormField,
FormItem,
FormLabel,
FormMessage,
} from '@/components/ui/form';
import {
Select,
SelectContent,
SelectGroup,
SelectItem,
SelectTrigger,
SelectValue,
} from '@/components/ui/select';
import { Separator } from '@/components/ui/separator';
import {
Sheet,
SheetContent,
SheetDescription,
SheetHeader,
SheetTitle,
} from '@/components/ui/sheet';
import { Textarea } from '@/components/ui/textarea';
import { ApiError, compactNumber, get, money, percent, post, shortDate } from '@/lib/api';
export interface AvailabilityRow {
commitmentId: string;
name: string;
gpuType: string;
gpuCount: number;
interconnectType: string;
securityTier: string;
startsAt: string;
endsAt: string;
totalGpuHours: number;
soldGpuHours: number;
heldGpuHours: number;
availableGpuHours: number;
costPerGpuHourCents: number;
utilisation: number;
breakEvenPriceCents: number | null;
}
export type MatchRow = AvailabilityRow & { score: number; rationale: string[] };
interface CommitmentRecord {
id: string;
shape: { intervals: string[]; quantities: number[] } | null;
isContiguous: boolean;
oversubscriptionPct: string | number;
}
interface CommitmentRow {
commitment: CommitmentRecord;
accountName: string | null;
}
interface DealRecord {
id: string;
name: string;
stage: string;
}
interface DemandBoard {
deals: { deal: DealRecord; accountName: string | null }[];
}
interface AllocationRecord {
id: string;
capacityCommitmentId: string;
demandDealId: string | null;
gpuHours: string | number;
pricePerGpuHourCents: number;
startsAt: string;
endsAt: string;
status: string;
holdExpiresAt: string | null;
guaranteeType: string;
}
const activeReleaseStatuses = RESERVING_ALLOCATION_STATUSES.filter(
(status) => status !== 'completed',
);
const createStatuses = CONSUMING_ALLOCATION_STATUSES.filter((status) => status !== 'completed');
const numeric = z.string().refine(
(value) => Number.isFinite(Number(value)) && Number(value) > 0,
'Enter a number greater than zero.',
);
const moneyValue = z.string().refine(
(value) => value === '' || (Number.isFinite(Number(value)) && Number(value) >= 0),
'Enter zero or a positive amount.',
);
const formSchema = z
.object({
kind: z.enum(['allocation', 'hold']),
capacityCommitmentId: z.string().uuid('Select a commitment.'),
demandDealId: z.string().uuid('Select a demand deal.'),
gpuHours: numeric,
price: moneyValue,
startsAt: z.string().min(1, 'Start is required.'),
endsAt: z.string().min(1, 'End is required.'),
holdExpiresAt: z.string(),
status: z.enum(CONSUMING_ALLOCATION_STATUSES),
guaranteeType: z.enum(GUARANTEE_TYPES),
notes: z.string().max(10_000, 'Keep notes under 10,000 characters.'),
})
.superRefine((values, context) => {
const startsAt = new Date(values.startsAt);
const endsAt = new Date(values.endsAt);
if (endsAt <= startsAt) {
context.addIssue({ code: 'custom', path: ['endsAt'], message: 'End must be after start.' });
}
if (values.kind === 'allocation' && values.price === '') {
context.addIssue({ code: 'custom', path: ['price'], message: 'Sell price is required.' });
}
if (values.kind === 'hold') {
const expiresAt = new Date(values.holdExpiresAt);
if (!values.holdExpiresAt || expiresAt <= new Date()) {
context.addIssue({
code: 'custom',
path: ['holdExpiresAt'],
message: 'A hold must expire in the future.',
});
}
}
});
type AllocationForm = z.infer<typeof formSchema>;
function localDateTime(value: string | Date): string {
const date = new Date(value);
const offset = date.getTimezoneOffset() * 60_000;
return new Date(date.getTime() - offset).toISOString().slice(0, 16);
}
function localCommitmentBound(value: string | Date, bound: 'start' | 'end'): string {
const timestamp = new Date(value).getTime();
const minute = 60_000;
const rounded = bound === 'start'
? Math.ceil(timestamp / minute) * minute
: Math.floor(timestamp / minute) * minute;
return localDateTime(new Date(rounded));
}
function defaults(
preferredCommitmentId?: string,
defaultGpuHours?: number,
): AllocationForm {
return {
kind: 'allocation',
capacityCommitmentId: preferredCommitmentId ?? '',
demandDealId: '',
gpuHours: defaultGpuHours == null ? '' : String(defaultGpuHours),
price: '',
startsAt: '',
endsAt: '',
holdExpiresAt: localDateTime(new Date(Date.now() + 24 * 60 * 60 * 1_000)),
status: 'committed',
guaranteeType: 'committed',
notes: '',
};
}
export function AllocationSheet({
open,
onOpenChange,
preferredCommitmentId,
matches,
defaultGpuHours,
onChanged,
}: {
open: boolean;
onOpenChange(open: boolean): void;
preferredCommitmentId?: string;
matches?: MatchRow[];
defaultGpuHours?: number;
onChanged?(): void;
}) {
const queryClient = useQueryClient();
const [releaseReason, setReleaseReason] = useState('');
const [releaseError, setReleaseError] = useState<string | null>(null);
const form = useForm<AllocationForm>({
resolver: zodResolver(formSchema),
defaultValues: defaults(preferredCommitmentId, defaultGpuHours),
});
const { data: availability, isLoading: availabilityLoading } = useQuery({
queryKey: ['availability'],
queryFn: () => get<AvailabilityRow[]>('/api/capacity/availability'),
enabled: open,
});
const { data: commitments } = useQuery({
queryKey: ['commitments', 'allocation-context'],
queryFn: () => get<CommitmentRow[]>('/api/commitments'),
enabled: open,
});
const { data: demand } = useQuery({
queryKey: ['/api/deals/demand'],
queryFn: () => get<DemandBoard>('/api/deals/demand'),
enabled: open,
});
const { data: allocations } = useQuery({
queryKey: ['allocations'],
queryFn: () => get<AllocationRecord[]>('/api/allocations'),
enabled: open,
});
useEffect(() => {
if (!open) return;
form.reset(defaults(preferredCommitmentId, defaultGpuHours));
setReleaseReason('');
setReleaseError(null);
}, [defaultGpuHours, form, open, preferredCommitmentId]);
const contextIds = useMemo(
() => (matches ? new Set(matches.map((match) => match.commitmentId)) : null),
[matches],
);
const options = useMemo(
() => (availability ?? []).filter((row) => !contextIds || contextIds.has(row.commitmentId)),
[availability, contextIds],
);
const selectedId = form.watch('capacityCommitmentId');
const selected = options.find((row) => row.commitmentId === selectedId);
const detail = commitments?.find((row) => row.commitment.id === selectedId);
const match = matches?.find((row) => row.commitmentId === selectedId);
const kind = form.watch('kind');
const quotedPriceValue = form.watch('price');
const quotedPrice = quotedPriceValue === '' ? null : Number(quotedPriceValue);
const dealsById = useMemo(
() => new Map((demand?.deals ?? []).map((row) => [row.deal.id, row])),
[demand],
);
const reserving = useMemo(() => {
const now = Date.now();
return (allocations ?? []).filter(
(allocation) =>
allocation.capacityCommitmentId === selectedId &&
activeReleaseStatuses.some((status) => status === allocation.status) &&
!(
allocation.status === 'planned' &&
allocation.holdExpiresAt &&
new Date(allocation.holdExpiresAt).getTime() <= now
),
);
}, [allocations, selectedId]);
useEffect(() => {
if (!open || !selected || form.getValues('startsAt')) return;
form.setValue('startsAt', localCommitmentBound(selected.startsAt, 'start'));
form.setValue('endsAt', localCommitmentBound(selected.endsAt, 'end'));
}, [form, open, selected]);
const refresh = async () => {
await Promise.all([
queryClient.invalidateQueries({ queryKey: ['availability'] }),
queryClient.invalidateQueries({ queryKey: ['allocations'] }),
queryClient.invalidateQueries({ queryKey: ['margin'] }),
queryClient.invalidateQueries({ queryKey: ['dashboard'] }),
queryClient.invalidateQueries({ queryKey: ['/api/deals/demand'] }),
]);
onChanged?.();
};
const save = useMutation({
mutationFn: (values: AllocationForm) => {
const price = values.price === '' ? undefined : Number(values.price);
const body = {
capacityCommitmentId: values.capacityCommitmentId,
demandDealId: values.demandDealId,
gpuHours: Number(values.gpuHours),
pricePerGpuHourCents: price === undefined ? undefined : Math.round(price * 100),
startsAt: new Date(values.startsAt).toISOString(),
endsAt: new Date(values.endsAt).toISOString(),
guaranteeType: values.guaranteeType,
notes: values.notes.trim() || null,
};
return values.kind === 'hold'
? post<AllocationRecord>('/api/allocations/holds', {
...body,
holdExpiresAt: new Date(values.holdExpiresAt).toISOString(),
})
: post<AllocationRecord>('/api/allocations', { ...body, status: values.status });
},
onSuccess: async () => {
await refresh();
onOpenChange(false);
},
});
const release = useMutation({
mutationFn: (id: string) =>
post<AllocationRecord>(`/api/allocations/${id}/release`, {
reason: releaseReason.trim() || undefined,
}),
onMutate: () => setReleaseError(null),
onSuccess: refresh,
onError: (error) => setReleaseError(errorMessage(error)),
});
const chooseCommitment = (id: string) => {
form.setValue('capacityCommitmentId', id, { shouldValidate: true });
const row = options.find((option) => option.commitmentId === id);
if (row) {
form.setValue('startsAt', localCommitmentBound(row.startsAt, 'start'), { shouldValidate: true });
form.setValue('endsAt', localCommitmentBound(row.endsAt, 'end'), { shouldValidate: true });
}
};
return (
<Sheet open={open} onOpenChange={onOpenChange}>
<SheetContent className="flex h-full w-full flex-col gap-0 overflow-hidden p-0 sm:max-w-2xl">
<SheetHeader className="shrink-0 gap-1 px-5 pb-4 pt-5 text-left sm:px-6">
<SheetTitle>Reserve capacity</SheetTitle>
<SheetDescription>
Join committed supply to a demand deal. Availability is re-checked by the server when you save.
</SheetDescription>
</SheetHeader>
<Separator />
<Form {...form}>
<form
className="flex min-h-0 flex-1 flex-col"
onSubmit={form.handleSubmit((values) => save.mutate(values))}
>
<div className="flex min-h-0 flex-1 flex-col gap-6 overflow-y-auto px-5 py-5 sm:px-6">
<div className="grid grid-cols-2 rounded-lg bg-surface-2 p-1" role="group" aria-label="Reservation type">
{(['allocation', 'hold'] as const).map((value) => (
<button
key={value}
type="button"
onClick={() => form.setValue('kind', value)}
className={
kind === value
? 'tap rounded-md bg-surface px-3 text-sm font-medium text-fg shadow-sm'
: 'tap rounded-md px-3 text-sm font-medium text-muted'
}
>
{value === 'allocation' ? 'Sell allocation' : 'Timed hold'}
</button>
))}
</div>
<div className="grid grid-cols-1 gap-4 sm:grid-cols-2">
<FormField
control={form.control}
name="capacityCommitmentId"
render={({ field }) => (
<FormItem className="sm:col-span-2">
<FormLabel>Capacity commitment</FormLabel>
<Select value={field.value} onValueChange={chooseCommitment}>
<FormControl>
<SelectTrigger className="h-11">
<SelectValue placeholder={availabilityLoading ? 'Loading capacity…' : 'Select capacity'} />
</SelectTrigger>
</FormControl>
<SelectContent>
<SelectGroup>
{options.map((row) => (
<SelectItem key={row.commitmentId} value={row.commitmentId}>
{row.name} · {compactNumber(row.availableGpuHours)} GPU-hrs free
</SelectItem>
))}
</SelectGroup>
</SelectContent>
</Select>
{matches ? <FormDescription>Limited to the capacity returned by this match.</FormDescription> : null}
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="demandDealId"
render={({ field }) => (
<FormItem className="sm:col-span-2">
<FormLabel>Demand deal</FormLabel>
<Select value={field.value} onValueChange={field.onChange}>
<FormControl>
<SelectTrigger className="h-11"><SelectValue placeholder="Select the customer deal" /></SelectTrigger>
</FormControl>
<SelectContent>
<SelectGroup>
{(demand?.deals ?? [])
.filter((row) => row.deal.stage !== 'closed_lost')
.map((row) => (
<SelectItem key={row.deal.id} value={row.deal.id}>
{row.deal.name} · {row.accountName ?? 'No account'}
</SelectItem>
))}
</SelectGroup>
</SelectContent>
</Select>
<FormMessage />
</FormItem>
)}
/>
</div>
{selected ? (
<CommitmentContext row={selected} detail={detail} match={match} quotedPrice={quotedPrice} />
) : options.length === 0 && !availabilityLoading ? (
<div role="status" className="rounded-lg border border-border bg-surface-2 p-4 text-sm text-muted">
No currently available commitment remains in this context. Run the matcher again before promising capacity.
</div>
) : null}
<section className="flex flex-col gap-4">
<div>
<h3 className="text-sm font-semibold">Commercial reservation</h3>
<p className="mt-1 text-xs leading-relaxed text-muted">
GPU-hours and the window are submitted to the ledger as entered. The server checks the term, shaped capacity, holds, and concurrent writes.
</p>
</div>
<div className="grid grid-cols-1 gap-4 sm:grid-cols-2">
<TextField control={form.control} name="gpuHours" label="GPU-hours" inputMode="decimal" placeholder="2048" />
<TextField control={form.control} name="price" label={kind === 'hold' ? 'Expected $/GPU-hr' : 'Sell $/GPU-hr'} inputMode="decimal" placeholder={kind === 'hold' ? 'Optional' : '2.75'} />
<TextField control={form.control} name="startsAt" label="Starts" type="datetime-local" />
<TextField control={form.control} name="endsAt" label="Ends" type="datetime-local" />
{kind === 'hold' ? (
<TextField control={form.control} name="holdExpiresAt" label="Hold expires" type="datetime-local" className="sm:col-span-2" />
) : (
<SelectField control={form.control} name="status" label="Allocation status" options={createStatuses} />
)}
<SelectField control={form.control} name="guaranteeType" label="Service guarantee" options={GUARANTEE_TYPES} />
<FormField
control={form.control}
name="notes"
render={({ field }) => (
<FormItem className="sm:col-span-2">
<FormLabel>Reservation notes</FormLabel>
<FormControl><Textarea {...field} className="min-h-24 resize-y" placeholder="Commercial assumptions, caveats, or approval context." /></FormControl>
<FormMessage />
</FormItem>
)}
/>
</div>
</section>
{selected ? (
<section className="flex flex-col gap-3">
<div>
<h3 className="text-sm font-semibold">Reservations on this commitment</h3>
<p className="mt-1 text-xs text-muted">Live holds reserve capacity but remain separate from sold allocations.</p>
</div>
{reserving.length === 0 ? (
<p className="rounded-lg bg-surface-2 p-4 text-sm text-muted">No live reserving allocations.</p>
) : (
<div className="flex flex-col gap-2">
{reserving.map((allocation) => {
const deal = allocation.demandDealId ? dealsById.get(allocation.demandDealId) : undefined;
return (
<div key={allocation.id} className="flex flex-col gap-3 rounded-lg border border-border p-3 sm:flex-row sm:items-center sm:justify-between">
<div className="min-w-0">
<div className="flex flex-wrap items-center gap-2">
<p className="truncate text-sm font-medium">{deal?.deal.name ?? 'Internal allocation'}</p>
<Badge tone={allocation.status === 'planned' ? 'warning' : 'positive'}>{allocation.status === 'planned' ? 'Held' : allocation.status}</Badge>
</div>
<p className="mt-1 text-xs text-muted">
{compactNumber(Number(allocation.gpuHours))} GPU-hrs · {shortDate(allocation.startsAt)}{shortDate(allocation.endsAt)}
{allocation.holdExpiresAt ? ` · expires ${shortDate(allocation.holdExpiresAt)}` : ''}
</p>
</div>
<Button type="button" variant="outline" className="shrink-0" disabled={release.isPending} onClick={() => release.mutate(allocation.id)}>
{release.isPending && release.variables === allocation.id ? <LoaderCircle data-icon="inline-start" className="animate-spin" aria-hidden /> : <RotateCcw data-icon="inline-start" aria-hidden />}
Release
</Button>
</div>
);
})}
<label className="flex flex-col gap-1 text-xs font-medium text-muted">
Release reason <span className="font-normal">Optional; recorded in the audit trail</span>
<Input value={releaseReason} onChange={(event) => setReleaseReason(event.target.value)} placeholder="Deal changed, hold lapsed…" />
</label>
</div>
)}
{releaseError ? <ServerError message={releaseError} /> : null}
</section>
) : null}
{save.isError ? <ServerError message={errorMessage(save.error)} /> : null}
</div>
<Separator />
<div className="flex shrink-0 flex-col-reverse gap-2 px-5 pb-[calc(1rem+var(--safe-bottom))] pt-4 sm:flex-row sm:justify-end sm:px-6">
<Button type="button" variant="outline" onClick={() => onOpenChange(false)}>Cancel</Button>
<Button type="submit" variant="primary" disabled={save.isPending || options.length === 0}>
{save.isPending ? <LoaderCircle data-icon="inline-start" className="animate-spin" aria-hidden /> : kind === 'hold' ? <Clock3 data-icon="inline-start" aria-hidden /> : <ShieldCheck data-icon="inline-start" aria-hidden />}
{save.isPending ? 'Checking capacity…' : kind === 'hold' ? 'Place timed hold' : 'Create allocation'}
</Button>
</div>
</form>
</Form>
</SheetContent>
</Sheet>
);
}
function CommitmentContext({ row, detail, match, quotedPrice }: { row: AvailabilityRow; detail?: CommitmentRow; match?: MatchRow; quotedPrice: number | null }) {
const soldPct = row.totalGpuHours > 0 ? row.soldGpuHours / row.totalGpuHours : 0;
const heldPct = row.totalGpuHours > 0 ? row.heldGpuHours / row.totalGpuHours : 0;
const breakEvenDollars = row.breakEvenPriceCents == null ? null : row.breakEvenPriceCents / 100;
const delta = quotedPrice != null && Number.isFinite(quotedPrice) && quotedPrice >= 0 && breakEvenDollars != null
? quotedPrice - breakEvenDollars
: null;
const shape = detail?.commitment.shape;
return (
<section className="rounded-xl border border-border bg-surface-2 p-4">
<div className="flex flex-wrap items-start justify-between gap-2">
<div className="min-w-0">
<p className="truncate font-semibold">{row.name}</p>
<p className="mt-1 text-xs text-muted">{row.gpuCount}× {row.gpuType} · {row.interconnectType} · {row.securityTier.replace(/_/g, ' ')}</p>
</div>
{match ? <Badge tone={match.score > 0.7 ? 'positive' : 'neutral'}>{percent(match.score)} fit</Badge> : null}
</div>
<div className="mt-4 flex h-2 overflow-hidden rounded-full bg-surface">
<div className="bg-accent" style={{ width: `${Math.min(100, soldPct * 100)}%` }} />
<div className="bg-accent/35" style={{ width: `${Math.min(100 - soldPct * 100, heldPct * 100)}%` }} />
</div>
<div className="mt-2 grid grid-cols-3 gap-2 text-xs">
<div><p className="text-muted">Sold</p><p className="nums mt-0.5 font-medium">{compactNumber(row.soldGpuHours)} hrs</p></div>
<div><p className="text-muted">Held</p><p className="nums mt-0.5 font-medium">{compactNumber(row.heldGpuHours)} hrs</p></div>
<div><p className="text-muted">Available</p><p className="nums mt-0.5 font-medium">{compactNumber(row.availableGpuHours)} hrs</p></div>
</div>
<Separator className="my-4" />
<dl className="grid grid-cols-2 gap-x-4 gap-y-2 text-xs">
<dt className="text-muted">Contract window</dt><dd className="text-right">{shortDate(row.startsAt)}{shortDate(row.endsAt)}</dd>
<dt className="text-muted">Capacity shape</dt><dd className="text-right">{shape ? `${shape.quantities.length} tranches · ${shape.quantities.join('→')} GPUs` : 'Flat'}{detail?.commitment.isContiguous ? ' · contiguous' : ''}</dd>
<dt className="text-muted">Our cost</dt><dd className="nums text-right">{money(row.costPerGpuHourCents)}/GPU-hr</dd>
<dt className="text-muted">Remaining-block break even</dt><dd className="nums text-right">{row.breakEvenPriceCents == null ? 'Fully sold' : row.breakEvenPriceCents === 0 ? 'Cost covered' : `${money(row.breakEvenPriceCents)}/GPU-hr`}</dd>
{Number(detail?.commitment.oversubscriptionPct ?? 0) > 0 ? <><dt className="text-muted">Recorded oversubscription</dt><dd className="nums text-right">{Number(detail?.commitment.oversubscriptionPct)}%</dd></> : null}
{delta != null ? <><dt className="text-muted">Quote vs break even</dt><dd className={delta >= 0 ? 'nums text-right text-positive' : 'nums text-right text-danger'}>{delta >= 0 ? '+' : ''}{money(Math.round(delta * 100))}/GPU-hr</dd></> : null}
</dl>
{match?.rationale.length ? <ul className="mt-4 flex flex-col gap-1 text-xs text-muted">{match.rationale.map((reason) => <li key={reason}>{reason}</li>)}</ul> : null}
<p className="mt-4 text-[11px] leading-relaxed text-muted">These figures are the latest server view, not a guarantee. Save acquires a commitment lock and re-checks the exact window, shape, hours, live holds, and oversubscription policy.</p>
</section>
);
}
function TextField<T extends FieldValues>({ control, name, label, className, ...props }: { control: Control<T>; name: FieldPath<T>; label: string; className?: string } & Omit<React.ComponentProps<typeof Input>, 'name' | 'value' | 'defaultValue'>) {
return <FormField control={control} name={name} render={({ field }) => <FormItem className={className}><FormLabel>{label}</FormLabel><FormControl><Input {...field} {...props} value={String(field.value ?? '')} /></FormControl><FormMessage /></FormItem>} />;
}
function SelectField<T extends FieldValues>({ control, name, label, options }: { control: Control<T>; name: FieldPath<T>; label: string; options: readonly string[] }) {
return <FormField control={control} name={name} render={({ field }) => <FormItem><FormLabel>{label}</FormLabel><Select value={String(field.value)} onValueChange={field.onChange}><FormControl><SelectTrigger className="h-11"><SelectValue /></SelectTrigger></FormControl><SelectContent><SelectGroup>{options.map((option) => <SelectItem key={option} value={option}>{option.replace(/_/g, ' ').replace(/^./, (letter) => letter.toUpperCase())}</SelectItem>)}</SelectGroup></SelectContent></Select><FormMessage /></FormItem>} />;
}
function ServerError({ message }: { message: string }) {
return <div role="alert" className="flex gap-3 rounded-lg border border-danger/30 bg-danger/10 p-3 text-sm text-danger"><AlertTriangle className="mt-0.5 size-4 shrink-0" aria-hidden /><p>{message}</p></div>;
}
function errorMessage(error: unknown): string {
if (error instanceof ApiError) return error.message;
return error instanceof Error ? error.message : 'The reservation could not be saved.';
}