feat: skip local hashing for iCloud assets, use server-computed checksum

Instead of downloading iCloud assets twice (once to hash, once to upload),
skip local hashing for iCloud-only assets and let the server return its
computed SHA1 checksum in the upload response. The mobile app stores this
checksum locally to prevent re-uploads.

Changes:
- Server returns checksum in upload response (created + duplicate)
- iOS native layer tags iCloud-only assets with ICLOUD_ONLY error
- Hash service skips iCloud assets (allowNetworkAccess: false)
- Upload result carries server checksum back to mobile
- Foreground/background upload services store server checksum
- Backup candidates include unhashed assets (onlyHashed: false)

https://claude.ai/code/session_01LEs74WpkJ1gWcJrFBsp1i2
This commit is contained in:
Claude
2026-03-17 18:52:32 +00:00
parent 34caed3b2b
commit 1811d42d79
7 changed files with 51 additions and 8 deletions

View File

@@ -11,6 +11,8 @@ export class AssetMediaResponseDto {
status!: AssetMediaStatus;
@ApiProperty({ description: 'Asset media ID' })
id!: string;
@ApiPropertyOptional({ description: 'Asset checksum (SHA1 base64)' })
checksum?: string;
}
export enum AssetUploadAction {

View File

@@ -157,7 +157,7 @@ export class AssetMediaService extends BaseService {
await this.userRepository.updateUsage(auth.user.id, file.size);
return { id: asset.id, status: AssetMediaStatus.CREATED };
return { id: asset.id, status: AssetMediaStatus.CREATED, checksum: file.checksum.toString('base64') };
} catch (error: any) {
return this.handleUploadError(error, auth, file, sidecarFile);
}
@@ -350,7 +350,7 @@ export class AssetMediaService extends BaseService {
await this.sharedLinkRepository.addAssets(auth.sharedLink.id, [duplicateId]);
}
return { status: AssetMediaStatus.DUPLICATE, id: duplicateId };
return { status: AssetMediaStatus.DUPLICATE, id: duplicateId, checksum: file.checksum.toString('base64') };
}
this.logger.error(`Error uploading file ${error}`, error?.stack);