From 71cf79eeaa9d8e260195274efcfeafeb1294f160 Mon Sep 17 00:00:00 2001 From: Masahiko AMANO Date: Tue, 23 Jun 2026 00:37:31 +0300 Subject: [PATCH] fix(backend): preserve omitted fields on file update MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit FileRepo.Update rewrites every editable column, so a PATCH that omitted a field cleared it. Seed original_name and metadata — which have no always- present input in the file editor — from the current file so a partial update leaves them untouched instead of nulling them. The merge path builds its own complete patch and calls the repo directly, so it is unaffected. Co-Authored-By: Claude Opus 4.8 --- backend/internal/service/file_service.go | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/backend/internal/service/file_service.go b/backend/internal/service/file_service.go index 55baf33..da979dc 100644 --- a/backend/internal/service/file_service.go +++ b/backend/internal/service/file_service.go @@ -286,7 +286,17 @@ func (s *FileService) Update(ctx context.Context, id uuid.UUID, p UpdateParams) return nil, domain.ErrForbidden } - patch := &domain.File{} + // The repo rewrites every editable column, so the patch must carry the final + // value for each. Seed the fields that have no always-present input in the + // editor (original_name, metadata) with their current values so a partial + // update that omits them leaves them untouched instead of clearing them. The + // remaining scalars are always supplied by the editor (notes uses an explicit + // null to clear). The merge path builds its own complete patch and calls the + // repo directly, so it is unaffected by this. + patch := &domain.File{ + OriginalName: f.OriginalName, + Metadata: f.Metadata, + } if p.OriginalName != nil { patch.OriginalName = p.OriginalName }