feat(assets): add asset metadata views and enforce assignment transitions

This commit is contained in:
2026-06-19 17:14:22 +02:00
parent c1763ed007
commit f32d55a7b0
17 changed files with 1573 additions and 70 deletions
+119
View File
@@ -12,6 +12,7 @@ const schemaCopy = {
statusRequired: "El estado es obligatorio",
invalidCreateStatus: "El estado inicial no es válido",
invalidUpdateStatus: "El estado no es válido",
personRequired: "La persona es obligatoria",
}
describe("asset schema localization", () => {
@@ -75,6 +76,65 @@ describe("asset schema localization", () => {
}
})
it("requires person when create or update status is assigned", () => {
const createResult = buildCreateAssetSchema(schemaCopy).safeParse({
itemId: "item-1",
serialNumber: "SERIAL-1",
status: "ASSIGNED",
})
expect(createResult.success).toBe(false)
if (!createResult.success) {
expect(createResult.error.flatten().fieldErrors.personId).toContain(
schemaCopy.personRequired,
)
}
const updateResult = buildUpdateAssetSchema(schemaCopy).safeParse({
id: "asset-1",
itemId: "item-1",
serialNumber: "SERIAL-1",
status: "ASSIGNED",
})
expect(updateResult.success).toBe(false)
if (!updateResult.success) {
expect(updateResult.error.flatten().fieldErrors.personId).toContain(
schemaCopy.personRequired,
)
}
})
it("aligns create and update status options with the asset status contract", () => {
expect(
buildCreateAssetSchema(schemaCopy).safeParse({
itemId: "item-1",
serialNumber: "SERIAL-1",
status: "IN_REPAIR",
}).success,
).toBe(false)
for (const status of ["LOST", "RETIRED"] as const) {
expect(
buildUpdateAssetSchema(schemaCopy).safeParse({
id: "asset-1",
itemId: "item-1",
serialNumber: "SERIAL-1",
status,
}).success,
).toBe(true)
}
expect(
buildUpdateAssetSchema(schemaCopy).safeParse({
id: "asset-1",
itemId: "item-1",
serialNumber: "SERIAL-1",
status: "RESERVED",
}).success,
).toBe(false)
})
it("keeps optional asset fields optional", () => {
const result = buildCreateAssetSchema(schemaCopy).safeParse({
itemId: "item-1",
@@ -84,4 +144,63 @@ describe("asset schema localization", () => {
expect(result.success).toBe(true)
})
it("accepts operational asset fields on create and update payloads", () => {
const createResult = buildCreateAssetSchema(schemaCopy).safeParse({
itemId: "item-1",
serialNumber: "SERIAL-2",
status: "AVAILABLE",
assetTag: "IT-000123",
manufacturer: "Lenovo",
model: "ThinkPad T14",
purchaseDate: "2026-01-15",
purchasePrice: "1249.99",
warrantyEndsAt: "2028-01-15",
})
expect(createResult.success).toBe(true)
if (createResult.success) {
expect(createResult.data).toMatchObject({
assetTag: "IT-000123",
manufacturer: "Lenovo",
model: "ThinkPad T14",
purchasePrice: 1249.99,
})
expect(createResult.data.purchaseDate?.toISOString()).toBe(
"2026-01-15T00:00:00.000Z",
)
expect(createResult.data.warrantyEndsAt?.toISOString()).toBe(
"2028-01-15T00:00:00.000Z",
)
}
const updateResult = buildUpdateAssetSchema(schemaCopy).safeParse({
id: "asset-1",
itemId: "item-1",
serialNumber: "SERIAL-2",
status: "BROKEN",
assetTag: "IT-000124",
manufacturer: "Dell",
model: "Latitude 7420",
purchaseDate: "2026-02-01",
purchasePrice: "1499.5",
warrantyEndsAt: "2027-02-01",
})
expect(updateResult.success).toBe(true)
if (updateResult.success) {
expect(updateResult.data).toMatchObject({
assetTag: "IT-000124",
manufacturer: "Dell",
model: "Latitude 7420",
purchasePrice: 1499.5,
})
expect(updateResult.data.purchaseDate?.toISOString()).toBe(
"2026-02-01T00:00:00.000Z",
)
expect(updateResult.data.warrantyEndsAt?.toISOString()).toBe(
"2027-02-01T00:00:00.000Z",
)
}
})
})