Add AssetItem.areaId, show assigned-to + area on /assets, mm/dd/yyyy dates
CI / test (push) Failing after 9s

AssetItem.areaId reuses the existing Area entity (built for InventoryScan/
the office-move feature) rather than a free-text location string -- same
share-the-lookup-entity precedent floated for Department. Real-world
coverage from the ITAM export is thin: Physical location was the literal
string DAN for all 613 rows (useless), only Stockroom carried signal, and
only for the ~71 in_stock items -- an assigned item is with a person, not
in a stockroom bin, so most rows have no area by design, not by gap.

/assets page: the assigned employee (via the active, non-returned
Assignment) was already in the DB from the 2026-08-24 backfill but never
shown -- added an Assigned To column, folded into the free-text search
too. Added an Area column + filter dropdown. Removed the Created At
column (not actionable) and format Purchase Date/Warranty End Date as
mm/dd/yyyy instead of raw ISO strings.

CSV import/export: area column added (resolved/created via
createOrGetArea(), same idempotent-by-name helper the bots Area picker
uses -- not a raw UUID). Re-ran the 613-row import after this: 0 created,
613 updated, 0 errors -- backfilled area onto the 71 rows with a
Stockroom value (46 IT Cabinet, 21 Stockroom, 4 For allocation), verified
against the source file.

Hand-written migration, no Vitest coverage -- same deviation as the rest
of this branch, see CLAUDE.md. tsc/lint clean.
This commit is contained in:
toanhoang
2026-08-24 21:05:03 -04:00
parent 6863323cce
commit 4063b81f16
5 changed files with 203 additions and 10 deletions
@@ -0,0 +1,4 @@
-- Hand-written (same deviation as other 2026-08-2x migrations -- see CLAUDE.md).
ALTER TABLE "asset_items" ADD COLUMN "area_id" UUID;
ALTER TABLE "asset_items" ADD CONSTRAINT "asset_items_area_id_fkey"
FOREIGN KEY ("area_id") REFERENCES "areas"("id") ON DELETE SET NULL ON UPDATE CASCADE;
+13
View File
@@ -151,6 +151,17 @@ model AssetItem {
// amounts in the millions with room to spare.
cost Decimal? @db.Decimal(14, 2)
costCurrency String? @map("cost_currency")
// Reuses the Area entity built for InventoryScan/the office-move feature
// (2026-08-25) rather than a free-text location string -- same "share
// the lookup entity across tables" precedent floated for Department.
// Nullable: real-world coverage is thin (the ITAM export's own location
// data was nearly useless -- "Physical location" was the literal string
// "DAN" for all 613 rows, no per-item detail; only "Stockroom" carried
// any signal, and only for the ~71 in_stock items -- an assigned item is
// with a person, not sitting in a stockroom bin, so it has no area here
// by design, not by data gap).
areaId String? @map("area_id") @db.Uuid
area Area? @relation(fields: [areaId], references: [id], onDelete: SetNull)
purchaseOrderId String? @map("purchase_order_id") @db.Uuid
purchaseOrder PurchaseOrder? @relation(fields: [purchaseOrderId], references: [id])
// Free-text PO number from an external system (e.g. the real ITAM
@@ -548,6 +559,8 @@ model Area {
team String?
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz(6)
inventoryScans InventoryScan[]
// Back-relation for AssetItem.areaId -- see that field's comment.
assetItems AssetItem[]
@@map("areas")
}