fix(stock-purchase-items): drop dead drv_collected_at write to unblock build

The markLineCollected service and the stock-orders page's
handleAssignDriver (delivery-sentinel auto-collect path) both
wrote `drv_collected_at` to `stock_purchase_items`, but that
field exists on `order_items`, not on `stock_purchase_items`
(verified against pb_schema-2.json). Per AGENTS.md "select
fields are not self-service", PB would 500 both writes at
runtime. The TS error from the service was the build break
flagged in the 2026-08-06 23:34 deployment.

The page.tsx write was a latent runtime bug — TypeScript
never caught it because PB's loose `update` patch typing
accepts any field name. Both writes are removed; the
collection moment is captured by PB's `updated` timestamp on
the line row, which is sufficient for the auto-collect audit
trail. Inline comments point to FEATURE-REQUESTS as the
follow-up if a dedicated collection-date field is wanted
later (would need a PB admin schema change).

Also drops the matching test assertions that read
`drv_collected_at` off the response and replaces them with
a comment explaining the absence.

Tests: vitest 59/59 across stock-purchase-items-service +
stock-orders/[id]; npm run build compiles clean
(Next.js 16.2.6 Turbopack + TypeScript).

Co-Authored-By: Claude <noreply@anthropic.com>

Co-authored-by: Orca <help@stably.ai>
This commit is contained in:
SJCoetz 2026-08-07 01:39:03 +02:00
parent fe8a3c6872
commit f35779369a
4 changed files with 25 additions and 6 deletions

View file

@ -264,7 +264,8 @@ describe("<StockOrderDetailPage /> — driver picker", () => {
status: "collected",
quantity_received: 5,
});
expect(byId.get("si-1")?.drv_collected_at).toMatch(/^\d{4}-\d{2}-\d{2}T/);
// No `drv_collected_at` field on stock_purchase_items — collection
// moment is captured by PB's `updated` timestamp on the line row.
expect(byId.get("si-2")).toMatchObject({
status: "collected",
quantity_received: 10,

View file

@ -535,10 +535,16 @@ export default function StockOrderDetailPage({
// The header is still "sent" until the operator clicks
// "Confirm collection" — that final step is the audit
// stamp that the warehouse-side has accepted the goods.
//
// NOTE: we deliberately do NOT write `drv_collected_at`
// here — that field exists on `order_items` but NOT on
// `stock_purchase_items` (PB schema gap; tracked in
// FEATURE-REQUESTS). PB would 500 the request. The
// collection timestamp is captured by PB's `updated` on
// the line row.
await pb.collection("stock_purchase_items").update(line.id, {
status: "collected",
quantity_received: Number(line.quantity ?? 0),
drv_collected_at: now,
});
} else {
// Real driver: just bind the line to the driver. The

View file

@ -395,7 +395,9 @@ describe("markLineCollectedWithPb", () => {
expect(result.item.quantity_received).toBe(10);
expect(result.previous_quantity_received).toBe(0);
expect(result.new_quantity_received).toBe(10);
expect(result.item.drv_collected_at).toMatch(/^\d{4}-\d{2}-\d{2}T/);
// The collection moment is captured by PB's `updated` timestamp
// on the line row (no dedicated `drv_collected_at` field on
// stock_purchase_items — see FEATURE-REQUESTS gap).
});
it("accepts the collection_pool auto-collect path", async () => {

View file

@ -151,7 +151,13 @@ export async function updateStockPurchaseItemWithPb(
const previous: Partial<StockPurchaseItem> = {};
for (const key of STOCK_PURCHASE_ITEM_PATCHABLE_FIELDS) {
if (key in input.patch) {
(previous as Record<string, unknown>)[key] = (before as Record<string, unknown>)[key];
// `StockPurchaseItem` has no string index signature, so the
// direct `as Record<string, unknown>` cast is rejected (TS2352).
// Detour through `unknown` — same pattern as the stock-items
// service.
(previous as unknown as Record<string, unknown>)[key] = (
before as unknown as Record<string, unknown>
)[key];
}
}
@ -457,12 +463,16 @@ export async function markLineCollectedWithPb(
}
const new_quantity_received = previous_quantity_received + quantity_collected;
const now = new Date().toISOString();
// Note: `drv_collected_at` (the moment the driver handed the goods
// to the warehouse) does NOT exist on the `stock_purchase_items`
// PB collection — only `drv_id` + `assigned_at`. We track the
// collection moment via the line's `status` flip to `collected`
// and PB's `updated` timestamp. Adding a dedicated date field is
// a PB-admin task (FEATURE-REQUESTS gap #drv_collected_at_field).
const patch: Record<string, unknown> = {
status: "collected",
quantity_received: new_quantity_received,
drv_collected_at: before.drv_collected_at ?? now,
};
const updated = (await pb