immich/mobile/lib/infrastructure
Santo Shakil a490cea1c4
fix(mobile): dedupe stale remote_asset rows on sync (#28445)
* fix(mobile): dedupe stale remote_asset rows on sync

queue a pre-delete on the matching partial-index tuple before each
upsert in updateAssetsV1/V2 so the second insert does not crash on
SqliteException(2067) when the server re-issues a new id for the
same (ownerId, checksum). closes #22522 #27186.

* run the dedupe deletes before the inserts and keep only the last duplicate per payload

* switch the asset upsert to insert or replace

* trim the dedupe tests to the essentials
2026-08-21 11:13:48 +00:00
..
entities chore(mobile): Apply stricter linting rules for correctness (#30372) 2026-07-30 19:39:24 +00:00
loaders fix(mobile): decode remote thumbnails at displayed size (#29965) 2026-08-10 21:14:23 +06:00
repositories fix(mobile): dedupe stale remote_asset rows on sync (#28445) 2026-08-21 11:13:48 +00:00
utils chore(mobile): Apply stricter linting rules for formatting (#30370) 2026-07-30 08:56:46 +00:00
mapper.dart refactor: partner-page (#28783) 2026-06-04 09:05:45 -04:00
README.md

Infrastructure Layer

This directory contains the infrastructure layer of Immich. The infrastructure layer is responsible for the implementation details of the app. It includes data sources, APIs, and other external dependencies.

Structure

  • Entities: These are the classes that define the database schema for the domain models.
  • Repositories: These are the actual implementation of the domain interfaces. A single interface might have multiple implementations.
  • Utils: These are utility classes and functions specific to infrastructure implementations.
infrastructure/
├── entities/
│   └── user.entity.dart
├── repositories/
│   └── user.repository.dart
└── utils/
    └── database_utils.dart

Usage

The infrastructure layer provides concrete implementations of repository interfaces defined in the domain layer. These implementations are exposed through Riverpod providers in the root providers directory.

// In domain/services/user.service.dart
final userRepository = ref.watch(userRepositoryProvider);
final user = await userRepository.getUser(userId);

The domain layer should never directly instantiate repository implementations, but instead receive them through dependency injection.