feat(svc): implement soft-delete in FileService
Delete now performs soft-delete (status='user_deleted') instead of physical deletion. Removes storage content deletion — files are preserved on disk after soft-delete. Second delete on already-deleted file returns nil (idempotent). Add tests: SoftDelete, SoftDeleteKeepsStorage, SoftDeleteIdempotent, SoftDeleteForbidden. Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
@@ -129,6 +129,7 @@ func (s *FileService) Upload(ctx context.Context, userID string, parentID *strin
|
||||
MimeType: mimeType,
|
||||
StoragePath: storagePath,
|
||||
Hash: hex.EncodeToString(hasher.Sum(nil)),
|
||||
Status: model.StatusActive,
|
||||
IsDir: false,
|
||||
}
|
||||
|
||||
@@ -240,10 +241,14 @@ func (s *FileService) Update(ctx context.Context, userID, fileID string, newName
|
||||
return modelToFileInfo(file), nil
|
||||
}
|
||||
|
||||
// Delete removes a file or (empty) directory.
|
||||
// Delete soft-deletes a file or (empty) directory. Storage content is preserved.
|
||||
func (s *FileService) Delete(ctx context.Context, userID, fileID string) error {
|
||||
file, err := s.getOwnedFile(ctx, userID, fileID)
|
||||
if err != nil {
|
||||
var ae *model.AppError
|
||||
if errors.As(err, &ae) && errors.Is(ae.Err, model.ErrNotFound) {
|
||||
return nil // idempotent: already deleted
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -262,14 +267,6 @@ func (s *FileService) Delete(ctx context.Context, userID, fileID string) error {
|
||||
return model.NewInternalError("delete file record", err)
|
||||
}
|
||||
|
||||
// Remove content from storage (directories have no stored content).
|
||||
if !file.IsDir {
|
||||
if err := s.storage.Delete(ctx, file.StoragePath); err != nil {
|
||||
s.logger.WarnContext(ctx, "failed to delete file from storage",
|
||||
"path", file.StoragePath, "error", err)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -297,6 +294,7 @@ func (s *FileService) CreateDir(ctx context.Context, userID string, parentID *st
|
||||
UserID: userID,
|
||||
ParentID: parentID,
|
||||
Name: dirName,
|
||||
Status: model.StatusActive,
|
||||
IsDir: true,
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user