feat(operator): inline edit mode on /partners/[slug]

Toggle the partner detail cards from read-only to editable in place. Edit
button in the PageHeader flips to Cancel + Save changes; cards expose
text inputs for name/domain/contact/billing, a 4-option segmented
control for status, and a 0–100 range slider for marginPct. Save sends
a PATCH diff (only fields that actually changed), refreshes the page
data, and exits edit mode. Cancel with unsaved changes confirms first.

Also tightens audit metadata: previously `Object.keys(dto)` on the
ValidationPipe-instantiated DTO listed every @IsOptional() field, even
when the request body didn't touch them. The partner.updated audit
event now records only the keys the operator actually sent.
This commit is contained in:
Ronni Baslund
2026-05-24 22:05:31 +02:00
parent 0299328175
commit 4a1a4ddad5
2 changed files with 304 additions and 7 deletions
@@ -92,7 +92,16 @@ export class PartnersService {
resourceId: String(partner._id),
resourceName: partner.name,
partnerSlug: partner.slug,
metadata: { changes: Object.keys(dto as Record<string, unknown>) },
metadata: {
// class-validator's ValidationPipe(transform: true) instantiates the
// DTO with every @IsOptional() property defined (set to undefined
// when absent from the body). Filtering keeps the audit log honest —
// `changes` reflects what the operator actually sent, not the DTO
// shape.
changes: Object.keys(dto as Record<string, unknown>).filter(
(k) => (dto as Record<string, unknown>)[k] !== undefined,
),
},
},
actor,
)