feat(manufacturers): detail page with MPN-level insights
CI / Lint · Typecheck · Test · Build (push) Successful in 47s
CI / Playwright (smoke) (push) Has been skipped
CI / Build & push images (push) Successful in 1m2s

Adds /manufacturers/:id with vendor-wide KPIs, top MPNs by units,
failures by MPN, category mix, past-EOL exposure, and a filtered
PartModels table. Wires upstream links from PartDetail and
PartModelDetail so the manufacturer name is a navigable anchor.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-04-17 15:10:37 -04:00
parent c6fb839005
commit 1d53e81d5e
14 changed files with 1027 additions and 30 deletions
+11
View File
@@ -1,5 +1,6 @@
import type {
CreateManufacturerRequest,
ManufacturerInsights,
UpdateManufacturerRequest,
} from '@vector/shared';
import { api } from './client.js';
@@ -15,6 +16,16 @@ export function listManufacturers(filters: ManufacturerListFilters = {}) {
return getList<Manufacturer>('/manufacturers', filters);
}
export async function getManufacturer(id: string): Promise<Manufacturer> {
const res = await api.get<Manufacturer>(`/manufacturers/${id}`);
return res.data;
}
export async function getManufacturerInsights(id: string): Promise<ManufacturerInsights> {
const res = await api.get<ManufacturerInsights>(`/manufacturers/${id}/insights`);
return res.data;
}
export async function createManufacturer(input: CreateManufacturerRequest): Promise<Manufacturer> {
const res = await api.post<Manufacturer>('/manufacturers', input);
return res.data;
+1
View File
@@ -15,6 +15,7 @@ export interface Manufacturer {
name: string;
createdAt: string;
updatedAt: string;
_count?: { parts: number; partModels: number };
}
export interface PartModel {
+1
View File
@@ -20,6 +20,7 @@ export const queryKeys = {
list: (filters?: Record<string, unknown>) =>
[...queryKeys.manufacturers.all, 'list', filters ?? {}] as const,
detail: (id: string) => [...queryKeys.manufacturers.all, 'detail', id] as const,
insights: (id: string) => [...queryKeys.manufacturers.all, 'insights', id] as const,
},
sites: {
all: ['sites'] as const,