Executive summary
jpablodrexler/jp-photo-manager scores 54 out of 100, but it is rated At risk while a critical security finding is open; the score itself is unchanged.
The weakest lens counts most in the score, and here that is Maturity, which scores 49 and is rated Weak. Its Documentation accuracy dimension scores 0 out of 10, and until that reaches 4, Maturity can't be rated higher than Adequate. The first actions are to resolve the 1 No ADRs found finding(s) in ADR Quality and to reconcile the README with reality: JPPhotoManagerWeb/README.md runs `bash scripts/complexity-report.sh`, but `scripts/complexity-report.sh` does not exist; JPPhotoManagerWeb/README.md runs `bash scripts/dead-code-report.sh`, but `scripts/dead-code-report.sh` does not exist; JPPhotoManagerWeb/README.md runs `bash scripts/auth-coverage-report.sh`, but `scripts/auth-coverage-report.sh` does not exist; JPPhotoManagerWeb/README.md runs `bash scripts/coverage-report.sh`, but `scripts/coverage-report.sh` does not exist; JPPhotoManagerWeb/README.md runs `bash scripts/mutation-report.sh`, but `scripts/mutation-report.sh` does not exist, and if Maturity rose to 70, the score would rise from 54 to about 59.
84 findings are critical: 26 in Static Analysis (SAST), 25 in Dependency Vulnerabilities, 11 in IaC & Container Security, nine in Domain ↔ infrastructure boundary, five in Captive dependencies, five in Explicit Debt, two in Project dependency cycles and one in Secrets (history).
Watchdog couldn't measure 7 dimensions in this code, among them Code Coverage, Test Reliability and Dependency Hygiene, so they are left out of the score. The product code is 24,588 lines, which would take an estimated 0.6 person-years, around €91,000, to rebuild.
If Maturity rose from 49 to 70, the lowest score rated Strong, the score would rise from 54 to about 59.
New since the last survey: 58 findings
- Explicit Debt · Dead code: HasSameContent JPPhotoManager/JPPhotoManager.Domain/Interfaces/Services/IStorageService.cs
- Explicit Debt · Dead code: ReadFolders JPPhotoManager/JPPhotoManager.Infrastructure/Repositories/AssetRepository.cs
- Explicit Debt · Dead code: ReadAssets JPPhotoManager/JPPhotoManager.Infrastructure/Repositories/AssetRepository.cs
- Secrets (history) · REDACTED
- Static Analysis (SAST) · REDACTED
- Dependency Vulnerabilities · REDACTED
- Dependency Vulnerabilities · REDACTED
- Dependency Vulnerabilities · REDACTED
- Dependency Vulnerabilities · REDACTED
- Dependency Vulnerabilities · REDACTED
- Dependency Vulnerabilities · REDACTED
- Dependency Vulnerabilities · REDACTED
- Dependency Vulnerabilities · REDACTED
- Dependency Vulnerabilities · REDACTED
- Dependency Vulnerabilities · REDACTED
- Dependency Vulnerabilities · REDACTED
- Dependency Vulnerabilities · REDACTED
- Dependency Vulnerabilities · REDACTED
- IaC & Container Security · REDACTED
- Supply-chain Provenance & Signing · REDACTED
- Supply-chain Provenance & Signing · REDACTED
- Supply-chain Provenance & Signing · REDACTED
- Supply-chain Provenance & Signing · REDACTED
- Large Files · JPPhotoManagerWeb/frontend/src/app/features/gallery/gallery.component.ts: 907 lines of code JPPhotoManagerWeb/frontend/src/app/features/gallery/gallery.component.ts
- Cancellation propagation · Async method without CancellationToken: CatalogAssetsAsync JPPhotoManager/JPPhotoManager.Domain/Services/CatalogAssetsService.cs
- Cancellation propagation · Async method without CancellationToken: ExecuteAsync JPPhotoManager/JPPhotoManager.Domain/Services/ConvertAssetsService.cs
- Cancellation propagation · Async method without CancellationToken: CheckNewReleaseAsync JPPhotoManager/JPPhotoManager.Domain/Services/NewReleaseNotificationService.cs
- Cancellation propagation · Async method without CancellationToken: ExecuteAsync JPPhotoManager/JPPhotoManager.Domain/Services/SyncAssetsService.cs
- Cancellation propagation · Async method without CancellationToken: SyncAssetsAsync JPPhotoManager/JPPhotoManager.Application/Application.cs
- Cancellation propagation · Async method without CancellationToken: ConvertAssetsAsync JPPhotoManager/JPPhotoManager.Application/Application.cs
- Cancellation propagation · Async method without CancellationToken: CatalogAssetsAsync JPPhotoManager/JPPhotoManager.Application/Application.cs
- Cancellation propagation · Async method without CancellationToken: CheckNewReleaseAsyc JPPhotoManager/JPPhotoManager.Application/Application.cs
- Cancellation propagation · Async method without CancellationToken: GetAssets JPPhotoManager/JPPhotoManager.UI/Controls/ThumbnailsUserControl.xaml.cs
- Cancellation propagation · Async method without CancellationToken: RunProcessAsync JPPhotoManager/JPPhotoManager.UI/ViewModels/ConvertAssetsViewModel.cs
- Cancellation propagation · Async method without CancellationToken: RunProcessAsync JPPhotoManager/JPPhotoManager.UI/ViewModels/SyncAssetsViewModel.cs
- Captive dependencies · Captive dependency: singleton FolderRepository captures scoped AppDbContext JPPhotoManager/JPPhotoManager.Infrastructure/Repositories/FolderRepository.cs
- Captive dependencies · Captive dependency: singleton AssetRepository captures scoped AppDbContext JPPhotoManager/JPPhotoManager.Infrastructure/Repositories/AssetRepository.cs
- Captive dependencies · Captive dependency: singleton RecentTargetPathRepository captures scoped AppDbContext JPPhotoManager/JPPhotoManager.Infrastructure/Repositories/RecentTargetPathRepository.cs
- Captive dependencies · Captive dependency: singleton SyncAssetsConfigurationRepository captures scoped AppDbContext JPPhotoManager/JPPhotoManager.Infrastructure/Repositories/SyncAssetsConfigurationRepository.cs
- Captive dependencies · Captive dependency: singleton ConvertAssetsConfigurationRepository captures scoped AppDbContext JPPhotoManager/JPPhotoManager.Infrastructure/Repositories/ConvertAssetsConfigurationRepository.cs
- Domain ↔ infrastructure boundary · Domain depends on infrastructure: Asset JPPhotoManager/JPPhotoManager.Domain/Entities/Asset.cs
- Domain ↔ infrastructure boundary · Domain depends on infrastructure: Asset JPPhotoManager/JPPhotoManager.Domain/Entities/Asset.cs
- Domain ↔ infrastructure boundary · Domain depends on infrastructure: Asset JPPhotoManager/JPPhotoManager.Domain/Entities/Asset.cs
- Domain ↔ infrastructure boundary · Domain depends on infrastructure: ConvertAssetsDirectoriesDefinition JPPhotoManager/JPPhotoManager.Domain/Entities/ConvertAssetsDirectoriesDefinition.cs
- Domain ↔ infrastructure boundary · Domain depends on infrastructure: Folder JPPhotoManager/JPPhotoManager.Domain/Entities/Folder.cs
- Domain ↔ infrastructure boundary · Domain depends on infrastructure: Folder JPPhotoManager/JPPhotoManager.Domain/Entities/Folder.cs
- Domain ↔ infrastructure boundary · Domain depends on infrastructure: Folder JPPhotoManager/JPPhotoManager.Domain/Entities/Folder.cs
- Domain ↔ infrastructure boundary · Domain depends on infrastructure: RecentTargetPath JPPhotoManager/JPPhotoManager.Domain/Entities/RecentTargetPath.cs
- Domain ↔ infrastructure boundary · Domain depends on infrastructure: SyncAssetsDirectoriesDefinition JPPhotoManager/JPPhotoManager.Domain/Entities/SyncAssetsDirectoriesDefinition.cs
- One transaction, one aggregate · One operation mutates 2 aggregates: MoveAssetsUseCaseImpl.execute JPPhotoManagerWeb/backend/src/main/java/com/jpablodrexler/photomanager/application/usecase/asset/MoveAssetsUseCaseImpl.java
- One transaction, one aggregate · One operation mutates 3 aggregates: CatalogAssetItemWriter.write JPPhotoManagerWeb/backend/src/main/java/com/jpablodrexler/photomanager/infrastructure/batch/CatalogAssetItemWriter.java
- Async & latency hygiene · Sync-over-async blocking JPPhotoManagerWeb/frontend/scripts/lighthouse-report.mjs
- Async & latency hygiene · Sync-over-async blocking JPPhotoManagerWeb/frontend/scripts/lighthouse-report.mjs
- Async & latency hygiene · Sync-over-async blocking JPPhotoManagerWeb/frontend/scripts/lighthouse-report.mjs
- Async & latency hygiene · Sync-over-async blocking JPPhotoManagerWeb/frontend/scripts/lighthouse-report.mjs
- Async & latency hygiene · Sync-over-async blocking JPPhotoManagerWeb/frontend/scripts/lighthouse-report.mjs
- Async & latency hygiene · Sync-over-async blocking JPPhotoManagerWeb/frontend/scripts/lighthouse-report.mjs
- Async & latency hygiene · Sync-over-async blocking JPPhotoManagerWeb/frontend/scripts/lighthouse-report.mjs
Fixed since the last survey: 43 findings
- Dependency Vulnerabilities · Critical CVE: [GHSA redacted] JPPhotoManagerWeb/backend/pom.xml
- Dependency Vulnerabilities · Critical CVE: [GHSA redacted] JPPhotoManagerWeb/backend/pom.xml
- Dependency Vulnerabilities · Critical CVE: [GHSA redacted] JPPhotoManagerWeb/backend/pom.xml
- Dependency Vulnerabilities · Critical CVE: [GHSA redacted] JPPhotoManagerWeb/backend/pom.xml
- Dependency Vulnerabilities · High CVE: [GHSA redacted] JPPhotoManagerWeb/backend/pom.xml
- Dependency Vulnerabilities · High CVE: [GHSA redacted] JPPhotoManagerWeb/backend/pom.xml
- Dependency Vulnerabilities · High CVE: [GHSA redacted] JPPhotoManagerWeb/backend/pom.xml
- Dependency Vulnerabilities · High CVE: [GHSA redacted] JPPhotoManagerWeb/backend/pom.xml
- Dependency Vulnerabilities · High CVE: [GHSA redacted] JPPhotoManagerWeb/backend/pom.xml
- Dependency Vulnerabilities · High CVE: [GHSA redacted] JPPhotoManagerWeb/backend/pom.xml
- Dependency Vulnerabilities · High CVE: [GHSA redacted] JPPhotoManagerWeb/backend/pom.xml
- Dependency Vulnerabilities · High CVE: [GHSA redacted] JPPhotoManagerWeb/backend/pom.xml
- Dependency Vulnerabilities · High CVE: [GHSA redacted] JPPhotoManagerWeb/backend/pom.xml
- Dependency Vulnerabilities · High CVE: [GHSA redacted] JPPhotoManagerWeb/backend/pom.xml
- Dependency Vulnerabilities · High CVE: [GHSA redacted] JPPhotoManagerWeb/backend/pom.xml
- Dependency Vulnerabilities · High CVE: [GHSA redacted] JPPhotoManagerWeb/backend/pom.xml
- Dependency Vulnerabilities · High CVE: [GHSA redacted] JPPhotoManagerWeb/backend/pom.xml
- Dependency Vulnerabilities · High CVE: [GHSA redacted] JPPhotoManagerWeb/backend/pom.xml
- Dependency Vulnerabilities · High CVE: [GHSA redacted] JPPhotoManagerWeb/backend/pom.xml
- Dependency Vulnerabilities · High CVE: [GHSA redacted] JPPhotoManagerWeb/backend/pom.xml
- Dependency Vulnerabilities · High CVE: [GHSA redacted] JPPhotoManagerWeb/backend/pom.xml
- Dependency Vulnerabilities · High CVE: [GHSA redacted] JPPhotoManagerWeb/backend/pom.xml
- Dependency Vulnerabilities · High CVE: [GHSA redacted] JPPhotoManagerWeb/backend/pom.xml
- Dependency Vulnerabilities · High CVE: REDACTED REDACTED
- Dependency Vulnerabilities · High CVE: REDACTED REDACTED
- Dependency Vulnerabilities · High CVE: REDACTED REDACTED
- Dependency Vulnerabilities · High CVE: REDACTED REDACTED
- Dependency Vulnerabilities · High CVE: REDACTED REDACTED
- Dependency Vulnerabilities · High CVE: [GHSA redacted] REDACTED
- Dependency Vulnerabilities · High CVE: [GHSA redacted] REDACTED
- Dependency Vulnerabilities · High CVE: REDACTED REDACTED
- Dependency Vulnerabilities · Medium CVE: [GHSA redacted] JPPhotoManagerWeb/backend/pom.xml
- Dependency Vulnerabilities · Medium CVE: [GHSA redacted] JPPhotoManagerWeb/backend/pom.xml
- Dependency Vulnerabilities · Medium CVE: [GHSA redacted] JPPhotoManagerWeb/backend/pom.xml
- Dependency Vulnerabilities · Medium CVE: [GHSA redacted] JPPhotoManagerWeb/backend/pom.xml
- Dependency Vulnerabilities · Medium CVE: [GHSA redacted] JPPhotoManagerWeb/backend/pom.xml
- Dependency Vulnerabilities · Medium CVE: [GHSA redacted] JPPhotoManagerWeb/backend/pom.xml
- Dependency Vulnerabilities · Medium CVE: [GHSA redacted] JPPhotoManagerWeb/backend/pom.xml
- Dependency Vulnerabilities · Medium CVE: [GHSA redacted] JPPhotoManagerWeb/backend/pom.xml
- Dependency Vulnerabilities · Medium CVE: [GHSA redacted] JPPhotoManagerWeb/backend/pom.xml
- Dependency Vulnerabilities · Medium CVE: REDACTED REDACTED
- Dependency Vulnerabilities · Medium CVE: [GHSA redacted] REDACTED
- Supply-chain Provenance & Signing REDACTED
Rebuild cost: about €91,000 · Estimate
| Cost to rebuild | €30,000 to €150,000, for 503 to 1,601 hours of work, about 0.6 person-years for 1 to 2 engineers |
|---|---|
| Difficulty of the problem | High, judged from the kind of software and how it is built. Code that solves a harder problem, such as payments or medical bookings, costs more per line to write. |
| Quality factor | ×0.8 at a score of 54. Better code takes more work to write, so the factor is ×1.0 at a score of 70, lower below it and higher above it. |
| Size | Medium: 24,588 lines of product code |
| Comment lines | The estimate prices 24,486 lines. Comment lines count towards the size of 24,588 lines but aren't priced as work. |
Top priorities
Diagnosis: what the measurements show together
Architecture — module dependency graph
Architecture: which parts of the code depend on which
| uses → | 1 JPPhotoManagerWeb.frontend.src.app.core.models.asset_model | 2 JPPhotoManagerWeb.frontend.src.app.core.models.dialog_model | 3 JPPhotoManagerWeb.frontend.src.app.core.models.paginated-data_model | 4 JPPhotoManagerWeb.frontend.src.app.core.services.auth_service | 5 com.jpablodrexler.photomanager.domain.enums | 6 JPPhotoManager.Domain.Interfaces.Services | 7 JPPhotoManagerWeb.frontend.src.app.app_component | 8 JPPhotoManagerWeb.frontend.src.app.core.models.album_model | 9 JPPhotoManagerWeb.frontend.src.app.core.services.asset_service | 10 com.jpablodrexler.photomanager.domain.model | 11 com.jpablodrexler.photomanager.infrastructure.persistence.entity | 12 JPPhotoManager.Domain.Entities | 13 JPPhotoManagerWeb.frontend.src.app.core.services.album_service | 14 com.jpablodrexler.photomanager.application.dto | 15 com.jpablodrexler.photomanager.domain.port.in.catalog | 16 com.jpablodrexler.photomanager.domain.port.in.folder | 17 com.jpablodrexler.photomanager.domain.port.out | 18 com.jpablodrexler.photomanager.infrastructure.persistence.mapper | 19 JPPhotoManager.Domain | 20 JPPhotoManagerWeb.frontend.src.app.features.gallery.gallery_component | 21 com.jpablodrexler.photomanager.application.usecase.asset | 22 com.jpablodrexler.photomanager.application.usecase.convert | 23 com.jpablodrexler.photomanager.application.usecase.sync | 24 com.jpablodrexler.photomanager.application.usecase.user | 25 com.jpablodrexler.photomanager.infrastructure.persistence.adapter | 26 com.jpablodrexler.photomanager.infrastructure.service | 27 com.jpablodrexler.photomanager.infrastructure.web.dto.response | 28 JPPhotoManager.Domain.Interfaces.Repositories | 29 JPPhotoManager.Infrastructure.Services | 30 com.jpablodrexler.photomanager.config | 31 com.jpablodrexler.photomanager.infrastructure.batch | 32 com.jpablodrexler.photomanager.infrastructure.kafka | 33 com.jpablodrexler.photomanager.infrastructure.web.mapper | 34 JPPhotoManager.Application | 35 JPPhotoManager.Domain.Services | 36 JPPhotoManager.Infrastructure.Repositories | 37 com.jpablodrexler.photomanager.infrastructure.web.controller | 38 JPPhotoManager.UI.ViewModels | 39 JPPhotoManager.UI.Windows | 40 JPPhotoManager.UI.Controls |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 1 JPPhotoManagerWeb.frontend.src.app.core.models.asset_model | ||||||||||||||||||||||||||||||||||||||||
| 2 JPPhotoManagerWeb.frontend.src.app.core.models.dialog_model | ||||||||||||||||||||||||||||||||||||||||
| 3 JPPhotoManagerWeb.frontend.src.app.core.models.paginated-data_model | ||||||||||||||||||||||||||||||||||||||||
| 4 JPPhotoManagerWeb.frontend.src.app.core.services.auth_service | ||||||||||||||||||||||||||||||||||||||||
| 5 com.jpablodrexler.photomanager.domain.enums | ||||||||||||||||||||||||||||||||||||||||
| 6 JPPhotoManager.Domain.Interfaces.Services | 9 | 10 | ||||||||||||||||||||||||||||||||||||||
| 7 JPPhotoManagerWeb.frontend.src.app.app_component | 1 | |||||||||||||||||||||||||||||||||||||||
| 8 JPPhotoManagerWeb.frontend.src.app.core.models.album_model | 1 | 1 | ||||||||||||||||||||||||||||||||||||||
| 9 JPPhotoManagerWeb.frontend.src.app.core.services.asset_service | 6 | 1 | ||||||||||||||||||||||||||||||||||||||
| 10 com.jpablodrexler.photomanager.domain.model | 7 | |||||||||||||||||||||||||||||||||||||||
| 11 com.jpablodrexler.photomanager.infrastructure.persistence.entity | 3 | |||||||||||||||||||||||||||||||||||||||
| 12 JPPhotoManager.Domain.Entities | 1 | |||||||||||||||||||||||||||||||||||||||
| 13 JPPhotoManagerWeb.frontend.src.app.core.services.album_service | 4 | |||||||||||||||||||||||||||||||||||||||
| 14 com.jpablodrexler.photomanager.application.dto | 1 | 1 | ||||||||||||||||||||||||||||||||||||||
| 15 com.jpablodrexler.photomanager.domain.port.in.catalog | 1 | |||||||||||||||||||||||||||||||||||||||
| 16 com.jpablodrexler.photomanager.domain.port.in.folder | 2 | |||||||||||||||||||||||||||||||||||||||
| 17 com.jpablodrexler.photomanager.domain.port.out | 2 | 29 | ||||||||||||||||||||||||||||||||||||||
| 18 com.jpablodrexler.photomanager.infrastructure.persistence.mapper | 14 | 16 | ||||||||||||||||||||||||||||||||||||||
| 19 JPPhotoManager.Domain | 3 | |||||||||||||||||||||||||||||||||||||||
| 20 JPPhotoManagerWeb.frontend.src.app.features.gallery.gallery_component | 2 | 1 | 1 | |||||||||||||||||||||||||||||||||||||
| 21 com.jpablodrexler.photomanager.application.usecase.asset | 16 | 32 | ||||||||||||||||||||||||||||||||||||||
| 22 com.jpablodrexler.photomanager.application.usecase.convert | 3 | 1 | 4 | |||||||||||||||||||||||||||||||||||||
| 23 com.jpablodrexler.photomanager.application.usecase.sync | 3 | 1 | 4 | |||||||||||||||||||||||||||||||||||||
| 24 com.jpablodrexler.photomanager.application.usecase.user | 3 | 5 | ||||||||||||||||||||||||||||||||||||||
| 25 com.jpablodrexler.photomanager.infrastructure.persistence.adapter | 2 | 27 | 1 | 15 | 16 | |||||||||||||||||||||||||||||||||||
| 26 com.jpablodrexler.photomanager.infrastructure.service | 1 | 7 | 1 | 25 | ||||||||||||||||||||||||||||||||||||
| 27 com.jpablodrexler.photomanager.infrastructure.web.dto.response | 2 | 3 | ||||||||||||||||||||||||||||||||||||||
| 28 JPPhotoManager.Domain.Interfaces.Repositories | 5 | 1 | ||||||||||||||||||||||||||||||||||||||
| 29 JPPhotoManager.Infrastructure.Services | 7 | 3 | 3 | |||||||||||||||||||||||||||||||||||||
| 30 com.jpablodrexler.photomanager.config | 1 | 4 | 1 | |||||||||||||||||||||||||||||||||||||
| 31 com.jpablodrexler.photomanager.infrastructure.batch | 5 | 1 | 17 | 2 | ||||||||||||||||||||||||||||||||||||
| 32 com.jpablodrexler.photomanager.infrastructure.kafka | 1 | 16 | 1 | 10 | 1 | |||||||||||||||||||||||||||||||||||
| 33 com.jpablodrexler.photomanager.infrastructure.web.mapper | 23 | 2 | 20 | |||||||||||||||||||||||||||||||||||||
| 34 JPPhotoManager.Application | 10 | 8 | 17 | 5 | ||||||||||||||||||||||||||||||||||||
| 35 JPPhotoManager.Domain.Services | 25 | 7 | 7 | 10 | ||||||||||||||||||||||||||||||||||||
| 36 JPPhotoManager.Infrastructure.Repositories | 2 | 5 | 1 | 5 | ||||||||||||||||||||||||||||||||||||
| 37 com.jpablodrexler.photomanager.infrastructure.web.controller | 1 | 1 | 3 | 2 | 5 | 3 | 18 | 15 | ||||||||||||||||||||||||||||||||
| 38 JPPhotoManager.UI.ViewModels | 12 | 10 | 9 | |||||||||||||||||||||||||||||||||||||
| 39 JPPhotoManager.UI.Windows | 3 | 1 | 1 | 5 | 4 | |||||||||||||||||||||||||||||||||||
| 40 JPPhotoManager.UI.Controls | 2 | 1 | 1 | 5 | 2 |
6→12 JPPhotoManager.Domain.Interfaces.Services uses JPPhotoManager.Domain.Entities part of a loop✕
- Connections
- 9 pairs of types, where a type in JPPhotoManager.Domain.Interfaces.Services uses a type in JPPhotoManager.Domain.Entities.
- The types involved
JPPhotoManager.Domain.Interfaces.Services.IBatchRenameService→JPPhotoManager.Domain.Entities.AssetJPPhotoManager.Domain.Interfaces.Services.ICatalogAssetsService→JPPhotoManager.Domain.Entities.AssetJPPhotoManager.Domain.Interfaces.Services.IDirectoryComparer→JPPhotoManager.Domain.Entities.AssetJPPhotoManager.Domain.Interfaces.Services.IFindDuplicatedAssetsService→JPPhotoManager.Domain.Entities.AssetJPPhotoManager.Domain.Interfaces.Services.IMoveAssetsService→JPPhotoManager.Domain.Entities.AssetJPPhotoManager.Domain.Interfaces.Services.IMoveAssetsService→JPPhotoManager.Domain.Entities.FolderJPPhotoManager.Domain.Interfaces.Services.IStorageService→JPPhotoManager.Domain.Entities.AssetJPPhotoManager.Domain.Interfaces.Services.IStorageService→JPPhotoManager.Domain.Entities.FolderJPPhotoManager.Domain.Interfaces.Services.IUserConfigurationService→JPPhotoManager.Domain.Entities.Asset
- Direction
- JPPhotoManager.Domain.Interfaces.Services uses JPPhotoManager.Domain.Entities, so a change to JPPhotoManager.Domain.Entities can break JPPhotoManager.Domain.Interfaces.Services, while a change to JPPhotoManager.Domain.Interfaces.Services can't break JPPhotoManager.Domain.Entities.
- Position
- Above the diagonal, so it is part of a loop. Neither module can be changed, tested or released on its own until one of these dependencies is removed.
6→19 JPPhotoManager.Domain.Interfaces.Services uses JPPhotoManager.Domain part of a loop✕
- Connections
- 10 pairs of types, where a type in JPPhotoManager.Domain.Interfaces.Services uses a type in JPPhotoManager.Domain.
- The types involved
JPPhotoManager.Domain.Interfaces.Services.IBatchRenameService→JPPhotoManager.Domain.BatchRenameResultJPPhotoManager.Domain.Interfaces.Services.ICatalogAssetsService→JPPhotoManager.Domain.CatalogChangeCallbackJPPhotoManager.Domain.Interfaces.Services.IConvertAssetsService→JPPhotoManager.Domain.ConvertAssetsResultJPPhotoManager.Domain.Interfaces.Services.IConvertAssetsService→JPPhotoManager.Domain.ProcessStatusChangedCallbackJPPhotoManager.Domain.Interfaces.Services.INewReleaseNotificationService→JPPhotoManager.Domain.ReleaseJPPhotoManager.Domain.Interfaces.Services.IReleaseAvailabilityService→JPPhotoManager.Domain.ReleaseJPPhotoManager.Domain.Interfaces.Services.ISyncAssetsService→JPPhotoManager.Domain.ProcessStatusChangedCallbackJPPhotoManager.Domain.Interfaces.Services.ISyncAssetsService→JPPhotoManager.Domain.SyncAssetsResultJPPhotoManager.Domain.Interfaces.Services.IUserConfigurationService→JPPhotoManager.Domain.AboutInformationJPPhotoManager.Domain.Interfaces.Services.IUserConfigurationService→JPPhotoManager.Domain.WallpaperStyle
- Direction
- JPPhotoManager.Domain.Interfaces.Services uses JPPhotoManager.Domain, so a change to JPPhotoManager.Domain can break JPPhotoManager.Domain.Interfaces.Services, while a change to JPPhotoManager.Domain.Interfaces.Services can't break JPPhotoManager.Domain.
- Position
- Above the diagonal, so it is part of a loop. Neither module can be changed, tested or released on its own until one of these dependencies is removed.
7→4 JPPhotoManagerWeb.frontend.src.app.app_component uses JPPhotoManagerWeb.frontend.src.app.core.services.auth_service✕
- Connections
- 1 pair of types, where a type in JPPhotoManagerWeb.frontend.src.app.app_component uses a type in JPPhotoManagerWeb.frontend.src.app.core.services.auth_service.
- The types involved
JPPhotoManagerWeb.frontend.src.app.app_component.AppComponent→JPPhotoManagerWeb.frontend.src.app.core.services.auth_service.AuthService
- Direction
- JPPhotoManagerWeb.frontend.src.app.app_component uses JPPhotoManagerWeb.frontend.src.app.core.services.auth_service, so a change to JPPhotoManagerWeb.frontend.src.app.core.services.auth_service can break JPPhotoManagerWeb.frontend.src.app.app_component, while a change to JPPhotoManagerWeb.frontend.src.app.app_component can't break JPPhotoManagerWeb.frontend.src.app.core.services.auth_service.
- Position
- Below the diagonal: JPPhotoManagerWeb.frontend.src.app.app_component uses a module listed above it, which is the healthy direction.
8→1 JPPhotoManagerWeb.frontend.src.app.core.models.album_model uses JPPhotoManagerWeb.frontend.src.app.core.models.asset_model✕
- Connections
- 1 pair of types, where a type in JPPhotoManagerWeb.frontend.src.app.core.models.album_model uses a type in JPPhotoManagerWeb.frontend.src.app.core.models.asset_model.
- The types involved
JPPhotoManagerWeb.frontend.src.app.core.models.album_model.Album→JPPhotoManagerWeb.frontend.src.app.core.models.asset_model.Asset
- Direction
- JPPhotoManagerWeb.frontend.src.app.core.models.album_model uses JPPhotoManagerWeb.frontend.src.app.core.models.asset_model, so a change to JPPhotoManagerWeb.frontend.src.app.core.models.asset_model can break JPPhotoManagerWeb.frontend.src.app.core.models.album_model, while a change to JPPhotoManagerWeb.frontend.src.app.core.models.album_model can't break JPPhotoManagerWeb.frontend.src.app.core.models.asset_model.
- Position
- Below the diagonal: JPPhotoManagerWeb.frontend.src.app.core.models.album_model uses a module listed above it, which is the healthy direction.
8→3 JPPhotoManagerWeb.frontend.src.app.core.models.album_model uses JPPhotoManagerWeb.frontend.src.app.core.models.paginated-data_model✕
- Connections
- 1 pair of types, where a type in JPPhotoManagerWeb.frontend.src.app.core.models.album_model uses a type in JPPhotoManagerWeb.frontend.src.app.core.models.paginated-data_model.
- The types involved
JPPhotoManagerWeb.frontend.src.app.core.models.album_model.Album→JPPhotoManagerWeb.frontend.src.app.core.models.paginated-data_model.PaginatedData
- Direction
- JPPhotoManagerWeb.frontend.src.app.core.models.album_model uses JPPhotoManagerWeb.frontend.src.app.core.models.paginated-data_model, so a change to JPPhotoManagerWeb.frontend.src.app.core.models.paginated-data_model can break JPPhotoManagerWeb.frontend.src.app.core.models.album_model, while a change to JPPhotoManagerWeb.frontend.src.app.core.models.album_model can't break JPPhotoManagerWeb.frontend.src.app.core.models.paginated-data_model.
- Position
- Below the diagonal: JPPhotoManagerWeb.frontend.src.app.core.models.album_model uses a module listed above it, which is the healthy direction.
9→1 JPPhotoManagerWeb.frontend.src.app.core.services.asset_service uses JPPhotoManagerWeb.frontend.src.app.core.models.asset_model✕
- Connections
- 6 pairs of types, where a type in JPPhotoManagerWeb.frontend.src.app.core.services.asset_service uses a type in JPPhotoManagerWeb.frontend.src.app.core.models.asset_model.
- The types involved
JPPhotoManagerWeb.frontend.src.app.core.services.asset_service.AssetService→JPPhotoManagerWeb.frontend.src.app.core.models.asset_model.AssetJPPhotoManagerWeb.frontend.src.app.core.services.asset_service.AssetService→JPPhotoManagerWeb.frontend.src.app.core.models.asset_model.AssetTimelineFiltersJPPhotoManagerWeb.frontend.src.app.core.services.asset_service.AssetService→JPPhotoManagerWeb.frontend.src.app.core.models.asset_model.CropAssetRequestJPPhotoManagerWeb.frontend.src.app.core.services.asset_service.AssetService→JPPhotoManagerWeb.frontend.src.app.core.models.asset_model.RenameAssetsResponseJPPhotoManagerWeb.frontend.src.app.core.services.asset_service.AssetService→JPPhotoManagerWeb.frontend.src.app.core.models.asset_model.SortCriteriaJPPhotoManagerWeb.frontend.src.app.core.services.asset_service.AssetService→JPPhotoManagerWeb.frontend.src.app.core.models.asset_model.UploadAssetResponse
- Direction
- JPPhotoManagerWeb.frontend.src.app.core.services.asset_service uses JPPhotoManagerWeb.frontend.src.app.core.models.asset_model, so a change to JPPhotoManagerWeb.frontend.src.app.core.models.asset_model can break JPPhotoManagerWeb.frontend.src.app.core.services.asset_service, while a change to JPPhotoManagerWeb.frontend.src.app.core.services.asset_service can't break JPPhotoManagerWeb.frontend.src.app.core.models.asset_model.
- Position
- Below the diagonal: JPPhotoManagerWeb.frontend.src.app.core.services.asset_service uses a module listed above it, which is the healthy direction.
9→3 JPPhotoManagerWeb.frontend.src.app.core.services.asset_service uses JPPhotoManagerWeb.frontend.src.app.core.models.paginated-data_model✕
- Connections
- 1 pair of types, where a type in JPPhotoManagerWeb.frontend.src.app.core.services.asset_service uses a type in JPPhotoManagerWeb.frontend.src.app.core.models.paginated-data_model.
- The types involved
JPPhotoManagerWeb.frontend.src.app.core.services.asset_service.AssetService→JPPhotoManagerWeb.frontend.src.app.core.models.paginated-data_model.PaginatedData
- Direction
- JPPhotoManagerWeb.frontend.src.app.core.services.asset_service uses JPPhotoManagerWeb.frontend.src.app.core.models.paginated-data_model, so a change to JPPhotoManagerWeb.frontend.src.app.core.models.paginated-data_model can break JPPhotoManagerWeb.frontend.src.app.core.services.asset_service, while a change to JPPhotoManagerWeb.frontend.src.app.core.services.asset_service can't break JPPhotoManagerWeb.frontend.src.app.core.models.paginated-data_model.
- Position
- Below the diagonal: JPPhotoManagerWeb.frontend.src.app.core.services.asset_service uses a module listed above it, which is the healthy direction.
10→5 com.jpablodrexler.photomanager.domain.model uses com.jpablodrexler.photomanager.domain.enums✕
- Connections
- 7 pairs of types, where a type in com.jpablodrexler.photomanager.domain.model uses a type in com.jpablodrexler.photomanager.domain.enums.
- The types involved
com.jpablodrexler.photomanager.domain.model.Asset→com.jpablodrexler.photomanager.domain.enums.FileTypecom.jpablodrexler.photomanager.domain.model.Asset→com.jpablodrexler.photomanager.domain.enums.ImageRotationcom.jpablodrexler.photomanager.domain.model.Asset→com.jpablodrexler.photomanager.domain.enums.ProcessingStatuscom.jpablodrexler.photomanager.domain.model.AssetFilter→com.jpablodrexler.photomanager.domain.enums.SortCriteriacom.jpablodrexler.photomanager.domain.model.AuditEvent→com.jpablodrexler.photomanager.domain.enums.AuditActioncom.jpablodrexler.photomanager.domain.model.AuditEvent→com.jpablodrexler.photomanager.domain.enums.AuditEntityTypecom.jpablodrexler.photomanager.domain.model.CatalogChangeNotification→com.jpablodrexler.photomanager.domain.enums.Reason
- Direction
- com.jpablodrexler.photomanager.domain.model uses com.jpablodrexler.photomanager.domain.enums, so a change to com.jpablodrexler.photomanager.domain.enums can break com.jpablodrexler.photomanager.domain.model, while a change to com.jpablodrexler.photomanager.domain.model can't break com.jpablodrexler.photomanager.domain.enums.
- Position
- Below the diagonal: com.jpablodrexler.photomanager.domain.model uses a module listed above it, which is the healthy direction.
11→5 com.jpablodrexler.photomanager.infrastructure.persistence.entity uses com.jpablodrexler.photomanager.domain.enums✕
- Connections
- 3 pairs of types, where a type in com.jpablodrexler.photomanager.infrastructure.persistence.entity uses a type in com.jpablodrexler.photomanager.domain.enums.
- The types involved
com.jpablodrexler.photomanager.infrastructure.persistence.entity.AssetEntity→com.jpablodrexler.photomanager.domain.enums.FileTypecom.jpablodrexler.photomanager.infrastructure.persistence.entity.AssetEntity→com.jpablodrexler.photomanager.domain.enums.ImageRotationcom.jpablodrexler.photomanager.infrastructure.persistence.entity.AssetEntity→com.jpablodrexler.photomanager.domain.enums.ProcessingStatus
- Direction
- com.jpablodrexler.photomanager.infrastructure.persistence.entity uses com.jpablodrexler.photomanager.domain.enums, so a change to com.jpablodrexler.photomanager.domain.enums can break com.jpablodrexler.photomanager.infrastructure.persistence.entity, while a change to com.jpablodrexler.photomanager.infrastructure.persistence.entity can't break com.jpablodrexler.photomanager.domain.enums.
- Position
- Below the diagonal: com.jpablodrexler.photomanager.infrastructure.persistence.entity uses a module listed above it, which is the healthy direction.
12→6 JPPhotoManager.Domain.Entities uses JPPhotoManager.Domain.Interfaces.Services✕
- Connections
- 1 pair of types, where a type in JPPhotoManager.Domain.Entities uses a type in JPPhotoManager.Domain.Interfaces.Services.
- The types involved
JPPhotoManager.Domain.Entities.Asset→JPPhotoManager.Domain.Interfaces.Services.IStorageService
- Direction
- JPPhotoManager.Domain.Entities uses JPPhotoManager.Domain.Interfaces.Services, so a change to JPPhotoManager.Domain.Interfaces.Services can break JPPhotoManager.Domain.Entities, while a change to JPPhotoManager.Domain.Entities can't break JPPhotoManager.Domain.Interfaces.Services.
- Position
- Below the diagonal: JPPhotoManager.Domain.Entities uses a module listed above it, which is the healthy direction.
13→8 JPPhotoManagerWeb.frontend.src.app.core.services.album_service uses JPPhotoManagerWeb.frontend.src.app.core.models.album_model✕
- Connections
- 4 pairs of types, where a type in JPPhotoManagerWeb.frontend.src.app.core.services.album_service uses a type in JPPhotoManagerWeb.frontend.src.app.core.models.album_model.
- The types involved
JPPhotoManagerWeb.frontend.src.app.core.services.album_service.AlbumService→JPPhotoManagerWeb.frontend.src.app.core.models.album_model.AlbumJPPhotoManagerWeb.frontend.src.app.core.services.album_service.AlbumService→JPPhotoManagerWeb.frontend.src.app.core.models.album_model.AlbumSummaryJPPhotoManagerWeb.frontend.src.app.core.services.album_service.AlbumService→JPPhotoManagerWeb.frontend.src.app.core.models.album_model.CreateAlbumRequestJPPhotoManagerWeb.frontend.src.app.core.services.album_service.AlbumService→JPPhotoManagerWeb.frontend.src.app.core.models.album_model.UpdateAlbumRequest
- Direction
- JPPhotoManagerWeb.frontend.src.app.core.services.album_service uses JPPhotoManagerWeb.frontend.src.app.core.models.album_model, so a change to JPPhotoManagerWeb.frontend.src.app.core.models.album_model can break JPPhotoManagerWeb.frontend.src.app.core.services.album_service, while a change to JPPhotoManagerWeb.frontend.src.app.core.services.album_service can't break JPPhotoManagerWeb.frontend.src.app.core.models.album_model.
- Position
- Below the diagonal: JPPhotoManagerWeb.frontend.src.app.core.services.album_service uses a module listed above it, which is the healthy direction.
14→5 com.jpablodrexler.photomanager.application.dto uses com.jpablodrexler.photomanager.domain.enums✕
- Connections
- 1 pair of types, where a type in com.jpablodrexler.photomanager.application.dto uses a type in com.jpablodrexler.photomanager.domain.enums.
- The types involved
com.jpablodrexler.photomanager.application.dto.UploadProgressMessage→com.jpablodrexler.photomanager.domain.enums.UploadStage
- Direction
- com.jpablodrexler.photomanager.application.dto uses com.jpablodrexler.photomanager.domain.enums, so a change to com.jpablodrexler.photomanager.domain.enums can break com.jpablodrexler.photomanager.application.dto, while a change to com.jpablodrexler.photomanager.application.dto can't break com.jpablodrexler.photomanager.domain.enums.
- Position
- Below the diagonal: com.jpablodrexler.photomanager.application.dto uses a module listed above it, which is the healthy direction.
14→10 com.jpablodrexler.photomanager.application.dto uses com.jpablodrexler.photomanager.domain.model✕
- Connections
- 1 pair of types, where a type in com.jpablodrexler.photomanager.application.dto uses a type in com.jpablodrexler.photomanager.domain.model.
- The types involved
com.jpablodrexler.photomanager.application.dto.CatalogProgressMessage→com.jpablodrexler.photomanager.domain.model.CatalogChangeNotification
- Direction
- com.jpablodrexler.photomanager.application.dto uses com.jpablodrexler.photomanager.domain.model, so a change to com.jpablodrexler.photomanager.domain.model can break com.jpablodrexler.photomanager.application.dto, while a change to com.jpablodrexler.photomanager.application.dto can't break com.jpablodrexler.photomanager.domain.model.
- Position
- Below the diagonal: com.jpablodrexler.photomanager.application.dto uses a module listed above it, which is the healthy direction.
15→10 com.jpablodrexler.photomanager.domain.port.in.catalog uses com.jpablodrexler.photomanager.domain.model✕
- Connections
- 1 pair of types, where a type in com.jpablodrexler.photomanager.domain.port.in.catalog uses a type in com.jpablodrexler.photomanager.domain.model.
- The types involved
com.jpablodrexler.photomanager.domain.port.in.catalog.GetDuplicatedAssetsUseCase→com.jpablodrexler.photomanager.domain.model.Asset
- Direction
- com.jpablodrexler.photomanager.domain.port.in.catalog uses com.jpablodrexler.photomanager.domain.model, so a change to com.jpablodrexler.photomanager.domain.model can break com.jpablodrexler.photomanager.domain.port.in.catalog, while a change to com.jpablodrexler.photomanager.domain.port.in.catalog can't break com.jpablodrexler.photomanager.domain.model.
- Position
- Below the diagonal: com.jpablodrexler.photomanager.domain.port.in.catalog uses a module listed above it, which is the healthy direction.
16→10 com.jpablodrexler.photomanager.domain.port.in.folder uses com.jpablodrexler.photomanager.domain.model✕
- Connections
- 2 pairs of types, where a type in com.jpablodrexler.photomanager.domain.port.in.folder uses a type in com.jpablodrexler.photomanager.domain.model.
- The types involved
com.jpablodrexler.photomanager.domain.port.in.folder.GetSubFoldersUseCase→com.jpablodrexler.photomanager.domain.model.Foldercom.jpablodrexler.photomanager.domain.port.in.folder.PruneDeletedFoldersUseCase→com.jpablodrexler.photomanager.domain.model.CatalogChangeNotification
- Direction
- com.jpablodrexler.photomanager.domain.port.in.folder uses com.jpablodrexler.photomanager.domain.model, so a change to com.jpablodrexler.photomanager.domain.model can break com.jpablodrexler.photomanager.domain.port.in.folder, while a change to com.jpablodrexler.photomanager.domain.port.in.folder can't break com.jpablodrexler.photomanager.domain.model.
- Position
- Below the diagonal: com.jpablodrexler.photomanager.domain.port.in.folder uses a module listed above it, which is the healthy direction.
17→5 com.jpablodrexler.photomanager.domain.port.out uses com.jpablodrexler.photomanager.domain.enums✕
- Connections
- 2 pairs of types, where a type in com.jpablodrexler.photomanager.domain.port.out uses a type in com.jpablodrexler.photomanager.domain.enums.
- The types involved
com.jpablodrexler.photomanager.domain.port.out.AssetRepository→com.jpablodrexler.photomanager.domain.enums.ProcessingStatuscom.jpablodrexler.photomanager.domain.port.out.StoragePort→com.jpablodrexler.photomanager.domain.enums.ImageRotation
- Direction
- com.jpablodrexler.photomanager.domain.port.out uses com.jpablodrexler.photomanager.domain.enums, so a change to com.jpablodrexler.photomanager.domain.enums can break com.jpablodrexler.photomanager.domain.port.out, while a change to com.jpablodrexler.photomanager.domain.port.out can't break com.jpablodrexler.photomanager.domain.enums.
- Position
- Below the diagonal: com.jpablodrexler.photomanager.domain.port.out uses a module listed above it, which is the healthy direction.
17→10 com.jpablodrexler.photomanager.domain.port.out uses com.jpablodrexler.photomanager.domain.model✕
- Connections
- 29 pairs of types, where a type in com.jpablodrexler.photomanager.domain.port.out uses a type in com.jpablodrexler.photomanager.domain.model. Showing 25 of them; the rest are in namespace-graph.json in this report's bundle.
- The types involved
com.jpablodrexler.photomanager.domain.port.out.AlbumRepository→com.jpablodrexler.photomanager.domain.model.Albumcom.jpablodrexler.photomanager.domain.port.out.AlbumRepository→com.jpablodrexler.photomanager.domain.model.Assetcom.jpablodrexler.photomanager.domain.port.out.AlbumRepository→com.jpablodrexler.photomanager.domain.model.AssetFiltercom.jpablodrexler.photomanager.domain.port.out.AlbumRepository→com.jpablodrexler.photomanager.domain.model.PaginatedResultcom.jpablodrexler.photomanager.domain.port.out.AssetAudioRepository→com.jpablodrexler.photomanager.domain.model.AssetAudiocom.jpablodrexler.photomanager.domain.port.out.AssetExifRepository→com.jpablodrexler.photomanager.domain.model.AssetExifcom.jpablodrexler.photomanager.domain.port.out.AssetRepository→com.jpablodrexler.photomanager.domain.model.Assetcom.jpablodrexler.photomanager.domain.port.out.AssetRepository→com.jpablodrexler.photomanager.domain.model.AssetFiltercom.jpablodrexler.photomanager.domain.port.out.AssetRepository→com.jpablodrexler.photomanager.domain.model.Foldercom.jpablodrexler.photomanager.domain.port.out.AssetRepository→com.jpablodrexler.photomanager.domain.model.FolderStatcom.jpablodrexler.photomanager.domain.port.out.AssetRepository→com.jpablodrexler.photomanager.domain.model.FolderStorageEntrycom.jpablodrexler.photomanager.domain.port.out.AssetRepository→com.jpablodrexler.photomanager.domain.model.FormatEntrycom.jpablodrexler.photomanager.domain.port.out.AssetRepository→com.jpablodrexler.photomanager.domain.model.MonthlyCountEntrycom.jpablodrexler.photomanager.domain.port.out.AssetRepository→com.jpablodrexler.photomanager.domain.model.PaginatedResultcom.jpablodrexler.photomanager.domain.port.out.AssetRepository→com.jpablodrexler.photomanager.domain.model.RatingEntrycom.jpablodrexler.photomanager.domain.port.out.AuditLogRepository→com.jpablodrexler.photomanager.domain.model.AuditEventcom.jpablodrexler.photomanager.domain.port.out.AuditLogRepository→com.jpablodrexler.photomanager.domain.model.AuditLogFiltercom.jpablodrexler.photomanager.domain.port.out.AuditLogRepository→com.jpablodrexler.photomanager.domain.model.PaginatedResultcom.jpablodrexler.photomanager.domain.port.out.CatalogFolderPort→com.jpablodrexler.photomanager.domain.model.Assetcom.jpablodrexler.photomanager.domain.port.out.ConvertConfigRepository→com.jpablodrexler.photomanager.domain.model.ConvertDirectoriesDefinitioncom.jpablodrexler.photomanager.domain.port.out.FolderRepository→com.jpablodrexler.photomanager.domain.model.Foldercom.jpablodrexler.photomanager.domain.port.out.RecentTargetPathRepository→com.jpablodrexler.photomanager.domain.model.RecentTargetPathcom.jpablodrexler.photomanager.domain.port.out.RefreshTokenRepository→com.jpablodrexler.photomanager.domain.model.RefreshTokencom.jpablodrexler.photomanager.domain.port.out.SearchPresetRepository→com.jpablodrexler.photomanager.domain.model.SearchPresetcom.jpablodrexler.photomanager.domain.port.out.StoragePort→com.jpablodrexler.photomanager.domain.model.ExifMetadata
- Direction
- com.jpablodrexler.photomanager.domain.port.out uses com.jpablodrexler.photomanager.domain.model, so a change to com.jpablodrexler.photomanager.domain.model can break com.jpablodrexler.photomanager.domain.port.out, while a change to com.jpablodrexler.photomanager.domain.port.out can't break com.jpablodrexler.photomanager.domain.model.
- Position
- Below the diagonal: com.jpablodrexler.photomanager.domain.port.out uses a module listed above it, which is the healthy direction.
18→10 com.jpablodrexler.photomanager.infrastructure.persistence.mapper uses com.jpablodrexler.photomanager.domain.model✕
- Connections
- 14 pairs of types, where a type in com.jpablodrexler.photomanager.infrastructure.persistence.mapper uses a type in com.jpablodrexler.photomanager.domain.model.
- The types involved
com.jpablodrexler.photomanager.infrastructure.persistence.mapper.AlbumEntityMapper→com.jpablodrexler.photomanager.domain.model.Albumcom.jpablodrexler.photomanager.infrastructure.persistence.mapper.AssetAudioEntityMapper→com.jpablodrexler.photomanager.domain.model.AssetAudiocom.jpablodrexler.photomanager.infrastructure.persistence.mapper.AssetEntityMapper→com.jpablodrexler.photomanager.domain.model.Assetcom.jpablodrexler.photomanager.infrastructure.persistence.mapper.AssetExifEntityMapper→com.jpablodrexler.photomanager.domain.model.AssetExifcom.jpablodrexler.photomanager.infrastructure.persistence.mapper.AuditLogDocumentMapper→com.jpablodrexler.photomanager.domain.model.AuditEventcom.jpablodrexler.photomanager.infrastructure.persistence.mapper.ConvertConfigEntityMapper→com.jpablodrexler.photomanager.domain.model.ConvertDirectoriesDefinitioncom.jpablodrexler.photomanager.infrastructure.persistence.mapper.FolderEntityMapper→com.jpablodrexler.photomanager.domain.model.Foldercom.jpablodrexler.photomanager.infrastructure.persistence.mapper.RecentTargetPathEntityMapper→com.jpablodrexler.photomanager.domain.model.RecentTargetPathcom.jpablodrexler.photomanager.infrastructure.persistence.mapper.RefreshTokenEntityMapper→com.jpablodrexler.photomanager.domain.model.RefreshTokencom.jpablodrexler.photomanager.infrastructure.persistence.mapper.SearchPresetEntityMapper→com.jpablodrexler.photomanager.domain.model.SearchPresetcom.jpablodrexler.photomanager.infrastructure.persistence.mapper.SyncConfigEntityMapper→com.jpablodrexler.photomanager.domain.model.SyncDirectoriesDefinitioncom.jpablodrexler.photomanager.infrastructure.persistence.mapper.TagEntityMapper→com.jpablodrexler.photomanager.domain.model.Tagcom.jpablodrexler.photomanager.infrastructure.persistence.mapper.UserEntityMapper→com.jpablodrexler.photomanager.domain.model.Usercom.jpablodrexler.photomanager.infrastructure.persistence.mapper.UserPreferenceMapper→com.jpablodrexler.photomanager.domain.model.UserPreference
- Direction
- com.jpablodrexler.photomanager.infrastructure.persistence.mapper uses com.jpablodrexler.photomanager.domain.model, so a change to com.jpablodrexler.photomanager.domain.model can break com.jpablodrexler.photomanager.infrastructure.persistence.mapper, while a change to com.jpablodrexler.photomanager.infrastructure.persistence.mapper can't break com.jpablodrexler.photomanager.domain.model.
- Position
- Below the diagonal: com.jpablodrexler.photomanager.infrastructure.persistence.mapper uses a module listed above it, which is the healthy direction.
18→11 com.jpablodrexler.photomanager.infrastructure.persistence.mapper uses com.jpablodrexler.photomanager.infrastructure.persistence.entity✕
- Connections
- 16 pairs of types, where a type in com.jpablodrexler.photomanager.infrastructure.persistence.mapper uses a type in com.jpablodrexler.photomanager.infrastructure.persistence.entity.
- The types involved
com.jpablodrexler.photomanager.infrastructure.persistence.mapper.AlbumEntityMapper→com.jpablodrexler.photomanager.infrastructure.persistence.entity.AlbumEntitycom.jpablodrexler.photomanager.infrastructure.persistence.mapper.AlbumEntityMapper→com.jpablodrexler.photomanager.infrastructure.persistence.entity.UserEntitycom.jpablodrexler.photomanager.infrastructure.persistence.mapper.AssetAudioEntityMapper→com.jpablodrexler.photomanager.infrastructure.persistence.entity.AssetAudioEntitycom.jpablodrexler.photomanager.infrastructure.persistence.mapper.AssetEntityMapper→com.jpablodrexler.photomanager.infrastructure.persistence.entity.AssetEntitycom.jpablodrexler.photomanager.infrastructure.persistence.mapper.AssetEntityMapper→com.jpablodrexler.photomanager.infrastructure.persistence.entity.TagEntitycom.jpablodrexler.photomanager.infrastructure.persistence.mapper.AssetExifEntityMapper→com.jpablodrexler.photomanager.infrastructure.persistence.entity.AssetExifEntitycom.jpablodrexler.photomanager.infrastructure.persistence.mapper.ConvertConfigEntityMapper→com.jpablodrexler.photomanager.infrastructure.persistence.entity.ConvertAssetsDirectoriesDefinitionEntitycom.jpablodrexler.photomanager.infrastructure.persistence.mapper.FolderEntityMapper→com.jpablodrexler.photomanager.infrastructure.persistence.entity.FolderEntitycom.jpablodrexler.photomanager.infrastructure.persistence.mapper.RecentTargetPathEntityMapper→com.jpablodrexler.photomanager.infrastructure.persistence.entity.RecentTargetPathEntitycom.jpablodrexler.photomanager.infrastructure.persistence.mapper.RefreshTokenEntityMapper→com.jpablodrexler.photomanager.infrastructure.persistence.entity.RefreshTokenEntitycom.jpablodrexler.photomanager.infrastructure.persistence.mapper.SearchPresetEntityMapper→com.jpablodrexler.photomanager.infrastructure.persistence.entity.SearchPresetEntitycom.jpablodrexler.photomanager.infrastructure.persistence.mapper.SearchPresetEntityMapper→com.jpablodrexler.photomanager.infrastructure.persistence.entity.UserEntitycom.jpablodrexler.photomanager.infrastructure.persistence.mapper.SyncConfigEntityMapper→com.jpablodrexler.photomanager.infrastructure.persistence.entity.SyncAssetsDirectoriesDefinitionEntitycom.jpablodrexler.photomanager.infrastructure.persistence.mapper.TagEntityMapper→com.jpablodrexler.photomanager.infrastructure.persistence.entity.TagEntitycom.jpablodrexler.photomanager.infrastructure.persistence.mapper.UserEntityMapper→com.jpablodrexler.photomanager.infrastructure.persistence.entity.UserEntitycom.jpablodrexler.photomanager.infrastructure.persistence.mapper.UserPreferenceMapper→com.jpablodrexler.photomanager.infrastructure.persistence.entity.UserPreferenceEntity
- Direction
- com.jpablodrexler.photomanager.infrastructure.persistence.mapper uses com.jpablodrexler.photomanager.infrastructure.persistence.entity, so a change to com.jpablodrexler.photomanager.infrastructure.persistence.entity can break com.jpablodrexler.photomanager.infrastructure.persistence.mapper, while a change to com.jpablodrexler.photomanager.infrastructure.persistence.mapper can't break com.jpablodrexler.photomanager.infrastructure.persistence.entity.
- Position
- Below the diagonal: com.jpablodrexler.photomanager.infrastructure.persistence.mapper uses a module listed above it, which is the healthy direction.
19→12 JPPhotoManager.Domain uses JPPhotoManager.Domain.Entities✕
- Connections
- 3 pairs of types, where a type in JPPhotoManager.Domain uses a type in JPPhotoManager.Domain.Entities.
- The types involved
JPPhotoManager.Domain.BatchRenameResult→JPPhotoManager.Domain.Entities.AssetJPPhotoManager.Domain.CatalogChangeCallbackEventArgs→JPPhotoManager.Domain.Entities.AssetJPPhotoManager.Domain.CatalogChangeCallbackEventArgs→JPPhotoManager.Domain.Entities.Folder
- Direction
- JPPhotoManager.Domain uses JPPhotoManager.Domain.Entities, so a change to JPPhotoManager.Domain.Entities can break JPPhotoManager.Domain, while a change to JPPhotoManager.Domain can't break JPPhotoManager.Domain.Entities.
- Position
- Below the diagonal: JPPhotoManager.Domain uses a module listed above it, which is the healthy direction.
20→1 JPPhotoManagerWeb.frontend.src.app.features.gallery.gallery_component uses JPPhotoManagerWeb.frontend.src.app.core.models.asset_model✕
- Connections
- 2 pairs of types, where a type in JPPhotoManagerWeb.frontend.src.app.features.gallery.gallery_component uses a type in JPPhotoManagerWeb.frontend.src.app.core.models.asset_model.
- The types involved
JPPhotoManagerWeb.frontend.src.app.features.gallery.gallery_component.GalleryComponent→JPPhotoManagerWeb.frontend.src.app.core.models.asset_model.AssetJPPhotoManagerWeb.frontend.src.app.features.gallery.gallery_component.GalleryComponent→JPPhotoManagerWeb.frontend.src.app.core.models.asset_model.SortCriteria
- Direction
- JPPhotoManagerWeb.frontend.src.app.features.gallery.gallery_component uses JPPhotoManagerWeb.frontend.src.app.core.models.asset_model, so a change to JPPhotoManagerWeb.frontend.src.app.core.models.asset_model can break JPPhotoManagerWeb.frontend.src.app.features.gallery.gallery_component, while a change to JPPhotoManagerWeb.frontend.src.app.features.gallery.gallery_component can't break JPPhotoManagerWeb.frontend.src.app.core.models.asset_model.
- Position
- Below the diagonal: JPPhotoManagerWeb.frontend.src.app.features.gallery.gallery_component uses a module listed above it, which is the healthy direction.
20→9 JPPhotoManagerWeb.frontend.src.app.features.gallery.gallery_component uses JPPhotoManagerWeb.frontend.src.app.core.services.asset_service✕
- Connections
- 1 pair of types, where a type in JPPhotoManagerWeb.frontend.src.app.features.gallery.gallery_component uses a type in JPPhotoManagerWeb.frontend.src.app.core.services.asset_service.
- The types involved
JPPhotoManagerWeb.frontend.src.app.features.gallery.gallery_component.GalleryComponent→JPPhotoManagerWeb.frontend.src.app.core.services.asset_service.AssetService
- Direction
- JPPhotoManagerWeb.frontend.src.app.features.gallery.gallery_component uses JPPhotoManagerWeb.frontend.src.app.core.services.asset_service, so a change to JPPhotoManagerWeb.frontend.src.app.core.services.asset_service can break JPPhotoManagerWeb.frontend.src.app.features.gallery.gallery_component, while a change to JPPhotoManagerWeb.frontend.src.app.features.gallery.gallery_component can't break JPPhotoManagerWeb.frontend.src.app.core.services.asset_service.
- Position
- Below the diagonal: JPPhotoManagerWeb.frontend.src.app.features.gallery.gallery_component uses a module listed above it, which is the healthy direction.
20→13 JPPhotoManagerWeb.frontend.src.app.features.gallery.gallery_component uses JPPhotoManagerWeb.frontend.src.app.core.services.album_service✕
- Connections
- 1 pair of types, where a type in JPPhotoManagerWeb.frontend.src.app.features.gallery.gallery_component uses a type in JPPhotoManagerWeb.frontend.src.app.core.services.album_service.
- The types involved
JPPhotoManagerWeb.frontend.src.app.features.gallery.gallery_component.GalleryComponent→JPPhotoManagerWeb.frontend.src.app.core.services.album_service.AlbumService
- Direction
- JPPhotoManagerWeb.frontend.src.app.features.gallery.gallery_component uses JPPhotoManagerWeb.frontend.src.app.core.services.album_service, so a change to JPPhotoManagerWeb.frontend.src.app.core.services.album_service can break JPPhotoManagerWeb.frontend.src.app.features.gallery.gallery_component, while a change to JPPhotoManagerWeb.frontend.src.app.features.gallery.gallery_component can't break JPPhotoManagerWeb.frontend.src.app.core.services.album_service.
- Position
- Below the diagonal: JPPhotoManagerWeb.frontend.src.app.features.gallery.gallery_component uses a module listed above it, which is the healthy direction.
21→10 com.jpablodrexler.photomanager.application.usecase.asset uses com.jpablodrexler.photomanager.domain.model✕
- Connections
- 16 pairs of types, where a type in com.jpablodrexler.photomanager.application.usecase.asset uses a type in com.jpablodrexler.photomanager.domain.model.
- The types involved
com.jpablodrexler.photomanager.application.usecase.asset.CropAssetUseCaseImpl→com.jpablodrexler.photomanager.domain.model.Assetcom.jpablodrexler.photomanager.application.usecase.asset.CropAssetUseCaseImpl→com.jpablodrexler.photomanager.domain.model.CropRegioncom.jpablodrexler.photomanager.application.usecase.asset.GetAssetExifUseCaseImpl→com.jpablodrexler.photomanager.domain.model.AssetExifcom.jpablodrexler.photomanager.application.usecase.asset.GetAssetImageUseCaseImpl→com.jpablodrexler.photomanager.domain.model.AssetImagecom.jpablodrexler.photomanager.application.usecase.asset.GetAssetsTimelineUseCaseImpl→com.jpablodrexler.photomanager.domain.model.AssetFiltercom.jpablodrexler.photomanager.application.usecase.asset.GetAssetsTimelineUseCaseImpl→com.jpablodrexler.photomanager.domain.model.PaginatedResultcom.jpablodrexler.photomanager.application.usecase.asset.GetAssetsTimelineUseCaseImpl→com.jpablodrexler.photomanager.domain.model.TimelineGroupcom.jpablodrexler.photomanager.application.usecase.asset.GetAssetsUseCaseImpl→com.jpablodrexler.photomanager.domain.model.Assetcom.jpablodrexler.photomanager.application.usecase.asset.GetAssetsUseCaseImpl→com.jpablodrexler.photomanager.domain.model.AssetFiltercom.jpablodrexler.photomanager.application.usecase.asset.GetAssetsUseCaseImpl→com.jpablodrexler.photomanager.domain.model.PaginatedResultcom.jpablodrexler.photomanager.application.usecase.asset.GetPlaylistUseCaseImpl→com.jpablodrexler.photomanager.domain.model.Assetcom.jpablodrexler.photomanager.application.usecase.asset.RenameAssetsUseCaseImpl→com.jpablodrexler.photomanager.domain.model.Assetcom.jpablodrexler.photomanager.application.usecase.asset.RenameAssetsUseCaseImpl→com.jpablodrexler.photomanager.domain.model.RenameAssetsResultcom.jpablodrexler.photomanager.application.usecase.asset.RenameAssetsUseCaseImpl→com.jpablodrexler.photomanager.domain.model.RenamePreviewcom.jpablodrexler.photomanager.application.usecase.asset.StreamAssetUseCaseImpl→com.jpablodrexler.photomanager.domain.model.AssetStreamInfocom.jpablodrexler.photomanager.application.usecase.asset.UploadAssetUseCaseImpl→com.jpablodrexler.photomanager.domain.model.Asset
- Direction
- com.jpablodrexler.photomanager.application.usecase.asset uses com.jpablodrexler.photomanager.domain.model, so a change to com.jpablodrexler.photomanager.domain.model can break com.jpablodrexler.photomanager.application.usecase.asset, while a change to com.jpablodrexler.photomanager.application.usecase.asset can't break com.jpablodrexler.photomanager.domain.model.
- Position
- Below the diagonal: com.jpablodrexler.photomanager.application.usecase.asset uses a module listed above it, which is the healthy direction.
21→17 com.jpablodrexler.photomanager.application.usecase.asset uses com.jpablodrexler.photomanager.domain.port.out✕
- Connections
- 32 pairs of types, where a type in com.jpablodrexler.photomanager.application.usecase.asset uses a type in com.jpablodrexler.photomanager.domain.port.out. Showing 25 of them; the rest are in namespace-graph.json in this report's bundle.
- The types involved
com.jpablodrexler.photomanager.application.usecase.asset.CropAssetUseCaseImpl→com.jpablodrexler.photomanager.domain.port.out.AssetRepositorycom.jpablodrexler.photomanager.application.usecase.asset.CropAssetUseCaseImpl→com.jpablodrexler.photomanager.domain.port.out.CatalogFolderPortcom.jpablodrexler.photomanager.application.usecase.asset.CropAssetUseCaseImpl→com.jpablodrexler.photomanager.domain.port.out.StoragePortcom.jpablodrexler.photomanager.application.usecase.asset.DeleteAssetsUseCaseImpl→com.jpablodrexler.photomanager.domain.port.out.AssetRepositorycom.jpablodrexler.photomanager.application.usecase.asset.DeleteAssetsUseCaseImpl→com.jpablodrexler.photomanager.domain.port.out.StoragePortcom.jpablodrexler.photomanager.application.usecase.asset.DeleteAssetsUseCaseImpl→com.jpablodrexler.photomanager.domain.port.out.ThumbnailPortcom.jpablodrexler.photomanager.application.usecase.asset.DownloadAssetsUseCaseImpl→com.jpablodrexler.photomanager.domain.port.out.AssetRepositorycom.jpablodrexler.photomanager.application.usecase.asset.DownloadAssetsUseCaseImpl→com.jpablodrexler.photomanager.domain.port.out.AuditLogRepositorycom.jpablodrexler.photomanager.application.usecase.asset.DownloadAssetsUseCaseImpl→com.jpablodrexler.photomanager.domain.port.out.StoragePortcom.jpablodrexler.photomanager.application.usecase.asset.GetAssetExifUseCaseImpl→com.jpablodrexler.photomanager.domain.port.out.AssetExifRepositorycom.jpablodrexler.photomanager.application.usecase.asset.GetAssetExifUseCaseImpl→com.jpablodrexler.photomanager.domain.port.out.AssetRepositorycom.jpablodrexler.photomanager.application.usecase.asset.GetAssetImageUseCaseImpl→com.jpablodrexler.photomanager.domain.port.out.AssetRepositorycom.jpablodrexler.photomanager.application.usecase.asset.GetAssetImageUseCaseImpl→com.jpablodrexler.photomanager.domain.port.out.AuditLogRepositorycom.jpablodrexler.photomanager.application.usecase.asset.GetAssetImageUseCaseImpl→com.jpablodrexler.photomanager.domain.port.out.StoragePortcom.jpablodrexler.photomanager.application.usecase.asset.GetAssetThumbnailUseCaseImpl→com.jpablodrexler.photomanager.domain.port.out.ThumbnailPortcom.jpablodrexler.photomanager.application.usecase.asset.GetAssetsTimelineUseCaseImpl→com.jpablodrexler.photomanager.domain.port.out.AssetRepositorycom.jpablodrexler.photomanager.application.usecase.asset.GetAssetsUseCaseImpl→com.jpablodrexler.photomanager.domain.port.out.AssetRepositorycom.jpablodrexler.photomanager.application.usecase.asset.GetPlaylistUseCaseImpl→com.jpablodrexler.photomanager.domain.port.out.AssetRepositorycom.jpablodrexler.photomanager.application.usecase.asset.MoveAssetsUseCaseImpl→com.jpablodrexler.photomanager.domain.port.out.AssetRepositorycom.jpablodrexler.photomanager.application.usecase.asset.MoveAssetsUseCaseImpl→com.jpablodrexler.photomanager.domain.port.out.FolderRepositorycom.jpablodrexler.photomanager.application.usecase.asset.MoveAssetsUseCaseImpl→com.jpablodrexler.photomanager.domain.port.out.RecentTargetPathRepositorycom.jpablodrexler.photomanager.application.usecase.asset.MoveAssetsUseCaseImpl→com.jpablodrexler.photomanager.domain.port.out.StoragePortcom.jpablodrexler.photomanager.application.usecase.asset.RateAssetUseCaseImpl→com.jpablodrexler.photomanager.domain.port.out.AssetRepositorycom.jpablodrexler.photomanager.application.usecase.asset.RateAssetUseCaseImpl→com.jpablodrexler.photomanager.domain.port.out.AuditLogRepositorycom.jpablodrexler.photomanager.application.usecase.asset.RenameAssetsUseCaseImpl→com.jpablodrexler.photomanager.domain.port.out.AssetRepository
- Direction
- com.jpablodrexler.photomanager.application.usecase.asset uses com.jpablodrexler.photomanager.domain.port.out, so a change to com.jpablodrexler.photomanager.domain.port.out can break com.jpablodrexler.photomanager.application.usecase.asset, while a change to com.jpablodrexler.photomanager.application.usecase.asset can't break com.jpablodrexler.photomanager.domain.port.out.
- Position
- Below the diagonal: com.jpablodrexler.photomanager.application.usecase.asset uses a module listed above it, which is the healthy direction.
22→10 com.jpablodrexler.photomanager.application.usecase.convert uses com.jpablodrexler.photomanager.domain.model✕
- Connections
- 3 pairs of types, where a type in com.jpablodrexler.photomanager.application.usecase.convert uses a type in com.jpablodrexler.photomanager.domain.model.
- The types involved
com.jpablodrexler.photomanager.application.usecase.convert.ConvertAssetsUseCaseImpl→com.jpablodrexler.photomanager.domain.model.ConvertDirectoriesDefinitioncom.jpablodrexler.photomanager.application.usecase.convert.GetConvertConfigUseCaseImpl→com.jpablodrexler.photomanager.domain.model.ConvertDirectoriesDefinitioncom.jpablodrexler.photomanager.application.usecase.convert.SaveConvertConfigUseCaseImpl→com.jpablodrexler.photomanager.domain.model.ConvertDirectoriesDefinition
- Direction
- com.jpablodrexler.photomanager.application.usecase.convert uses com.jpablodrexler.photomanager.domain.model, so a change to com.jpablodrexler.photomanager.domain.model can break com.jpablodrexler.photomanager.application.usecase.convert, while a change to com.jpablodrexler.photomanager.application.usecase.convert can't break com.jpablodrexler.photomanager.domain.model.
- Position
- Below the diagonal: com.jpablodrexler.photomanager.application.usecase.convert uses a module listed above it, which is the healthy direction.
22→14 com.jpablodrexler.photomanager.application.usecase.convert uses com.jpablodrexler.photomanager.application.dto✕
- Connections
- 1 pair of types, where a type in com.jpablodrexler.photomanager.application.usecase.convert uses a type in com.jpablodrexler.photomanager.application.dto.
- The types involved
com.jpablodrexler.photomanager.application.usecase.convert.ConvertAssetsUseCaseImpl→com.jpablodrexler.photomanager.application.dto.ConvertAssetsResult
- Direction
- com.jpablodrexler.photomanager.application.usecase.convert uses com.jpablodrexler.photomanager.application.dto, so a change to com.jpablodrexler.photomanager.application.dto can break com.jpablodrexler.photomanager.application.usecase.convert, while a change to com.jpablodrexler.photomanager.application.usecase.convert can't break com.jpablodrexler.photomanager.application.dto.
- Position
- Below the diagonal: com.jpablodrexler.photomanager.application.usecase.convert uses a module listed above it, which is the healthy direction.
22→17 com.jpablodrexler.photomanager.application.usecase.convert uses com.jpablodrexler.photomanager.domain.port.out✕
- Connections
- 4 pairs of types, where a type in com.jpablodrexler.photomanager.application.usecase.convert uses a type in com.jpablodrexler.photomanager.domain.port.out.
- The types involved
com.jpablodrexler.photomanager.application.usecase.convert.ConvertAssetsUseCaseImpl→com.jpablodrexler.photomanager.domain.port.out.ConvertConfigRepositorycom.jpablodrexler.photomanager.application.usecase.convert.ConvertAssetsUseCaseImpl→com.jpablodrexler.photomanager.domain.port.out.StoragePortcom.jpablodrexler.photomanager.application.usecase.convert.GetConvertConfigUseCaseImpl→com.jpablodrexler.photomanager.domain.port.out.ConvertConfigRepositorycom.jpablodrexler.photomanager.application.usecase.convert.SaveConvertConfigUseCaseImpl→com.jpablodrexler.photomanager.domain.port.out.ConvertConfigRepository
- Direction
- com.jpablodrexler.photomanager.application.usecase.convert uses com.jpablodrexler.photomanager.domain.port.out, so a change to com.jpablodrexler.photomanager.domain.port.out can break com.jpablodrexler.photomanager.application.usecase.convert, while a change to com.jpablodrexler.photomanager.application.usecase.convert can't break com.jpablodrexler.photomanager.domain.port.out.
- Position
- Below the diagonal: com.jpablodrexler.photomanager.application.usecase.convert uses a module listed above it, which is the healthy direction.
23→10 com.jpablodrexler.photomanager.application.usecase.sync uses com.jpablodrexler.photomanager.domain.model✕
- Connections
- 3 pairs of types, where a type in com.jpablodrexler.photomanager.application.usecase.sync uses a type in com.jpablodrexler.photomanager.domain.model.
- The types involved
com.jpablodrexler.photomanager.application.usecase.sync.GetSyncConfigUseCaseImpl→com.jpablodrexler.photomanager.domain.model.SyncDirectoriesDefinitioncom.jpablodrexler.photomanager.application.usecase.sync.SaveSyncConfigUseCaseImpl→com.jpablodrexler.photomanager.domain.model.SyncDirectoriesDefinitioncom.jpablodrexler.photomanager.application.usecase.sync.SyncAssetsUseCaseImpl→com.jpablodrexler.photomanager.domain.model.SyncDirectoriesDefinition
- Direction
- com.jpablodrexler.photomanager.application.usecase.sync uses com.jpablodrexler.photomanager.domain.model, so a change to com.jpablodrexler.photomanager.domain.model can break com.jpablodrexler.photomanager.application.usecase.sync, while a change to com.jpablodrexler.photomanager.application.usecase.sync can't break com.jpablodrexler.photomanager.domain.model.
- Position
- Below the diagonal: com.jpablodrexler.photomanager.application.usecase.sync uses a module listed above it, which is the healthy direction.
23→14 com.jpablodrexler.photomanager.application.usecase.sync uses com.jpablodrexler.photomanager.application.dto✕
- Connections
- 1 pair of types, where a type in com.jpablodrexler.photomanager.application.usecase.sync uses a type in com.jpablodrexler.photomanager.application.dto.
- The types involved
com.jpablodrexler.photomanager.application.usecase.sync.SyncAssetsUseCaseImpl→com.jpablodrexler.photomanager.application.dto.SyncAssetsResult
- Direction
- com.jpablodrexler.photomanager.application.usecase.sync uses com.jpablodrexler.photomanager.application.dto, so a change to com.jpablodrexler.photomanager.application.dto can break com.jpablodrexler.photomanager.application.usecase.sync, while a change to com.jpablodrexler.photomanager.application.usecase.sync can't break com.jpablodrexler.photomanager.application.dto.
- Position
- Below the diagonal: com.jpablodrexler.photomanager.application.usecase.sync uses a module listed above it, which is the healthy direction.
23→17 com.jpablodrexler.photomanager.application.usecase.sync uses com.jpablodrexler.photomanager.domain.port.out✕
- Connections
- 4 pairs of types, where a type in com.jpablodrexler.photomanager.application.usecase.sync uses a type in com.jpablodrexler.photomanager.domain.port.out.
- The types involved
com.jpablodrexler.photomanager.application.usecase.sync.GetSyncConfigUseCaseImpl→com.jpablodrexler.photomanager.domain.port.out.SyncConfigRepositorycom.jpablodrexler.photomanager.application.usecase.sync.SaveSyncConfigUseCaseImpl→com.jpablodrexler.photomanager.domain.port.out.SyncConfigRepositorycom.jpablodrexler.photomanager.application.usecase.sync.SyncAssetsUseCaseImpl→com.jpablodrexler.photomanager.domain.port.out.StoragePortcom.jpablodrexler.photomanager.application.usecase.sync.SyncAssetsUseCaseImpl→com.jpablodrexler.photomanager.domain.port.out.SyncConfigRepository
- Direction
- com.jpablodrexler.photomanager.application.usecase.sync uses com.jpablodrexler.photomanager.domain.port.out, so a change to com.jpablodrexler.photomanager.domain.port.out can break com.jpablodrexler.photomanager.application.usecase.sync, while a change to com.jpablodrexler.photomanager.application.usecase.sync can't break com.jpablodrexler.photomanager.domain.port.out.
- Position
- Below the diagonal: com.jpablodrexler.photomanager.application.usecase.sync uses a module listed above it, which is the healthy direction.
24→10 com.jpablodrexler.photomanager.application.usecase.user uses com.jpablodrexler.photomanager.domain.model✕
- Connections
- 3 pairs of types, where a type in com.jpablodrexler.photomanager.application.usecase.user uses a type in com.jpablodrexler.photomanager.domain.model.
- The types involved
com.jpablodrexler.photomanager.application.usecase.user.CreateUserUseCaseImpl→com.jpablodrexler.photomanager.domain.model.UserSummarycom.jpablodrexler.photomanager.application.usecase.user.GetCurrentUserUseCaseImpl→com.jpablodrexler.photomanager.domain.model.Usercom.jpablodrexler.photomanager.application.usecase.user.ListUsersUseCaseImpl→com.jpablodrexler.photomanager.domain.model.UserSummary
- Direction
- com.jpablodrexler.photomanager.application.usecase.user uses com.jpablodrexler.photomanager.domain.model, so a change to com.jpablodrexler.photomanager.domain.model can break com.jpablodrexler.photomanager.application.usecase.user, while a change to com.jpablodrexler.photomanager.application.usecase.user can't break com.jpablodrexler.photomanager.domain.model.
- Position
- Below the diagonal: com.jpablodrexler.photomanager.application.usecase.user uses a module listed above it, which is the healthy direction.
24→17 com.jpablodrexler.photomanager.application.usecase.user uses com.jpablodrexler.photomanager.domain.port.out✕
- Connections
- 5 pairs of types, where a type in com.jpablodrexler.photomanager.application.usecase.user uses a type in com.jpablodrexler.photomanager.domain.port.out.
- The types involved
com.jpablodrexler.photomanager.application.usecase.user.CreateUserUseCaseImpl→com.jpablodrexler.photomanager.domain.port.out.UserRepositorycom.jpablodrexler.photomanager.application.usecase.user.DeleteUserUseCaseImpl→com.jpablodrexler.photomanager.domain.port.out.UserRepositorycom.jpablodrexler.photomanager.application.usecase.user.GetCurrentUserUseCaseImpl→com.jpablodrexler.photomanager.domain.port.out.UserRepositorycom.jpablodrexler.photomanager.application.usecase.user.ListUsersUseCaseImpl→com.jpablodrexler.photomanager.domain.port.out.UserRepositorycom.jpablodrexler.photomanager.application.usecase.user.UpdatePasswordUseCaseImpl→com.jpablodrexler.photomanager.domain.port.out.UserRepository
- Direction
- com.jpablodrexler.photomanager.application.usecase.user uses com.jpablodrexler.photomanager.domain.port.out, so a change to com.jpablodrexler.photomanager.domain.port.out can break com.jpablodrexler.photomanager.application.usecase.user, while a change to com.jpablodrexler.photomanager.application.usecase.user can't break com.jpablodrexler.photomanager.domain.port.out.
- Position
- Below the diagonal: com.jpablodrexler.photomanager.application.usecase.user uses a module listed above it, which is the healthy direction.
25→5 com.jpablodrexler.photomanager.infrastructure.persistence.adapter uses com.jpablodrexler.photomanager.domain.enums✕
- Connections
- 2 pairs of types, where a type in com.jpablodrexler.photomanager.infrastructure.persistence.adapter uses a type in com.jpablodrexler.photomanager.domain.enums.
- The types involved
com.jpablodrexler.photomanager.infrastructure.persistence.adapter.AssetRepositoryImpl→com.jpablodrexler.photomanager.domain.enums.ProcessingStatuscom.jpablodrexler.photomanager.infrastructure.persistence.adapter.AssetRepositoryImpl→com.jpablodrexler.photomanager.domain.enums.SortCriteria
- Direction
- com.jpablodrexler.photomanager.infrastructure.persistence.adapter uses com.jpablodrexler.photomanager.domain.enums, so a change to com.jpablodrexler.photomanager.domain.enums can break com.jpablodrexler.photomanager.infrastructure.persistence.adapter, while a change to com.jpablodrexler.photomanager.infrastructure.persistence.adapter can't break com.jpablodrexler.photomanager.domain.enums.
- Position
- Below the diagonal: com.jpablodrexler.photomanager.infrastructure.persistence.adapter uses a module listed above it, which is the healthy direction.
25→10 com.jpablodrexler.photomanager.infrastructure.persistence.adapter uses com.jpablodrexler.photomanager.domain.model✕
- Connections
- 27 pairs of types, where a type in com.jpablodrexler.photomanager.infrastructure.persistence.adapter uses a type in com.jpablodrexler.photomanager.domain.model. Showing 25 of them; the rest are in namespace-graph.json in this report's bundle.
- The types involved
com.jpablodrexler.photomanager.infrastructure.persistence.adapter.AlbumRepositoryImpl→com.jpablodrexler.photomanager.domain.model.Albumcom.jpablodrexler.photomanager.infrastructure.persistence.adapter.AlbumRepositoryImpl→com.jpablodrexler.photomanager.domain.model.Assetcom.jpablodrexler.photomanager.infrastructure.persistence.adapter.AlbumRepositoryImpl→com.jpablodrexler.photomanager.domain.model.AssetFiltercom.jpablodrexler.photomanager.infrastructure.persistence.adapter.AlbumRepositoryImpl→com.jpablodrexler.photomanager.domain.model.PaginatedResultcom.jpablodrexler.photomanager.infrastructure.persistence.adapter.AssetAudioRepositoryImpl→com.jpablodrexler.photomanager.domain.model.AssetAudiocom.jpablodrexler.photomanager.infrastructure.persistence.adapter.AssetExifRepositoryImpl→com.jpablodrexler.photomanager.domain.model.AssetExifcom.jpablodrexler.photomanager.infrastructure.persistence.adapter.AssetRepositoryImpl→com.jpablodrexler.photomanager.domain.model.Assetcom.jpablodrexler.photomanager.infrastructure.persistence.adapter.AssetRepositoryImpl→com.jpablodrexler.photomanager.domain.model.AssetFiltercom.jpablodrexler.photomanager.infrastructure.persistence.adapter.AssetRepositoryImpl→com.jpablodrexler.photomanager.domain.model.Foldercom.jpablodrexler.photomanager.infrastructure.persistence.adapter.AssetRepositoryImpl→com.jpablodrexler.photomanager.domain.model.FolderStatcom.jpablodrexler.photomanager.infrastructure.persistence.adapter.AssetRepositoryImpl→com.jpablodrexler.photomanager.domain.model.FolderStorageEntrycom.jpablodrexler.photomanager.infrastructure.persistence.adapter.AssetRepositoryImpl→com.jpablodrexler.photomanager.domain.model.FormatEntrycom.jpablodrexler.photomanager.infrastructure.persistence.adapter.AssetRepositoryImpl→com.jpablodrexler.photomanager.domain.model.MonthlyCountEntrycom.jpablodrexler.photomanager.infrastructure.persistence.adapter.AssetRepositoryImpl→com.jpablodrexler.photomanager.domain.model.PaginatedResultcom.jpablodrexler.photomanager.infrastructure.persistence.adapter.AssetRepositoryImpl→com.jpablodrexler.photomanager.domain.model.RatingEntrycom.jpablodrexler.photomanager.infrastructure.persistence.adapter.AuditLogRepositoryImpl→com.jpablodrexler.photomanager.domain.model.AuditEventcom.jpablodrexler.photomanager.infrastructure.persistence.adapter.AuditLogRepositoryImpl→com.jpablodrexler.photomanager.domain.model.AuditLogFiltercom.jpablodrexler.photomanager.infrastructure.persistence.adapter.AuditLogRepositoryImpl→com.jpablodrexler.photomanager.domain.model.PaginatedResultcom.jpablodrexler.photomanager.infrastructure.persistence.adapter.ConvertConfigRepositoryImpl→com.jpablodrexler.photomanager.domain.model.ConvertDirectoriesDefinitioncom.jpablodrexler.photomanager.infrastructure.persistence.adapter.FolderRepositoryImpl→com.jpablodrexler.photomanager.domain.model.Foldercom.jpablodrexler.photomanager.infrastructure.persistence.adapter.RecentTargetPathRepositoryImpl→com.jpablodrexler.photomanager.domain.model.RecentTargetPathcom.jpablodrexler.photomanager.infrastructure.persistence.adapter.RefreshTokenRepositoryImpl→com.jpablodrexler.photomanager.domain.model.RefreshTokencom.jpablodrexler.photomanager.infrastructure.persistence.adapter.SearchPresetRepositoryImpl→com.jpablodrexler.photomanager.domain.model.SearchPresetcom.jpablodrexler.photomanager.infrastructure.persistence.adapter.SyncConfigRepositoryImpl→com.jpablodrexler.photomanager.domain.model.SyncDirectoriesDefinitioncom.jpablodrexler.photomanager.infrastructure.persistence.adapter.TagRepositoryImpl→com.jpablodrexler.photomanager.domain.model.Tag
- Direction
- com.jpablodrexler.photomanager.infrastructure.persistence.adapter uses com.jpablodrexler.photomanager.domain.model, so a change to com.jpablodrexler.photomanager.domain.model can break com.jpablodrexler.photomanager.infrastructure.persistence.adapter, while a change to com.jpablodrexler.photomanager.infrastructure.persistence.adapter can't break com.jpablodrexler.photomanager.domain.model.
- Position
- Below the diagonal: com.jpablodrexler.photomanager.infrastructure.persistence.adapter uses a module listed above it, which is the healthy direction.
25→11 com.jpablodrexler.photomanager.infrastructure.persistence.adapter uses com.jpablodrexler.photomanager.infrastructure.persistence.entity✕
- Connections
- 1 pair of types, where a type in com.jpablodrexler.photomanager.infrastructure.persistence.adapter uses a type in com.jpablodrexler.photomanager.infrastructure.persistence.entity.
- The types involved
com.jpablodrexler.photomanager.infrastructure.persistence.adapter.AssetRepositoryImpl→com.jpablodrexler.photomanager.infrastructure.persistence.entity.FolderEntity
- Direction
- com.jpablodrexler.photomanager.infrastructure.persistence.adapter uses com.jpablodrexler.photomanager.infrastructure.persistence.entity, so a change to com.jpablodrexler.photomanager.infrastructure.persistence.entity can break com.jpablodrexler.photomanager.infrastructure.persistence.adapter, while a change to com.jpablodrexler.photomanager.infrastructure.persistence.adapter can't break com.jpablodrexler.photomanager.infrastructure.persistence.entity.
- Position
- Below the diagonal: com.jpablodrexler.photomanager.infrastructure.persistence.adapter uses a module listed above it, which is the healthy direction.
25→17 com.jpablodrexler.photomanager.infrastructure.persistence.adapter uses com.jpablodrexler.photomanager.domain.port.out✕
- Connections
- 15 pairs of types, where a type in com.jpablodrexler.photomanager.infrastructure.persistence.adapter uses a type in com.jpablodrexler.photomanager.domain.port.out.
- The types involved
com.jpablodrexler.photomanager.infrastructure.persistence.adapter.AlbumRepositoryImpl→com.jpablodrexler.photomanager.domain.port.out.AlbumRepositorycom.jpablodrexler.photomanager.infrastructure.persistence.adapter.AlbumRepositoryImpl→com.jpablodrexler.photomanager.domain.port.out.AssetRepositorycom.jpablodrexler.photomanager.infrastructure.persistence.adapter.AssetAudioRepositoryImpl→com.jpablodrexler.photomanager.domain.port.out.AssetAudioRepositorycom.jpablodrexler.photomanager.infrastructure.persistence.adapter.AssetExifRepositoryImpl→com.jpablodrexler.photomanager.domain.port.out.AssetExifRepositorycom.jpablodrexler.photomanager.infrastructure.persistence.adapter.AssetRepositoryImpl→com.jpablodrexler.photomanager.domain.port.out.AssetRepositorycom.jpablodrexler.photomanager.infrastructure.persistence.adapter.AuditLogRepositoryImpl→com.jpablodrexler.photomanager.domain.port.out.AuditLogRepositorycom.jpablodrexler.photomanager.infrastructure.persistence.adapter.ConvertConfigRepositoryImpl→com.jpablodrexler.photomanager.domain.port.out.ConvertConfigRepositorycom.jpablodrexler.photomanager.infrastructure.persistence.adapter.FolderRepositoryImpl→com.jpablodrexler.photomanager.domain.port.out.FolderRepositorycom.jpablodrexler.photomanager.infrastructure.persistence.adapter.RecentTargetPathRepositoryImpl→com.jpablodrexler.photomanager.domain.port.out.RecentTargetPathRepositorycom.jpablodrexler.photomanager.infrastructure.persistence.adapter.RefreshTokenRepositoryImpl→com.jpablodrexler.photomanager.domain.port.out.RefreshTokenRepositorycom.jpablodrexler.photomanager.infrastructure.persistence.adapter.SearchPresetRepositoryImpl→com.jpablodrexler.photomanager.domain.port.out.SearchPresetRepositorycom.jpablodrexler.photomanager.infrastructure.persistence.adapter.SyncConfigRepositoryImpl→com.jpablodrexler.photomanager.domain.port.out.SyncConfigRepositorycom.jpablodrexler.photomanager.infrastructure.persistence.adapter.TagRepositoryImpl→com.jpablodrexler.photomanager.domain.port.out.TagRepositorycom.jpablodrexler.photomanager.infrastructure.persistence.adapter.UserPreferenceRepositoryImpl→com.jpablodrexler.photomanager.domain.port.out.UserPreferenceRepositorycom.jpablodrexler.photomanager.infrastructure.persistence.adapter.UserRepositoryImpl→com.jpablodrexler.photomanager.domain.port.out.UserRepository
- Direction
- com.jpablodrexler.photomanager.infrastructure.persistence.adapter uses com.jpablodrexler.photomanager.domain.port.out, so a change to com.jpablodrexler.photomanager.domain.port.out can break com.jpablodrexler.photomanager.infrastructure.persistence.adapter, while a change to com.jpablodrexler.photomanager.infrastructure.persistence.adapter can't break com.jpablodrexler.photomanager.domain.port.out.
- Position
- Below the diagonal: com.jpablodrexler.photomanager.infrastructure.persistence.adapter uses a module listed above it, which is the healthy direction.
25→18 com.jpablodrexler.photomanager.infrastructure.persistence.adapter uses com.jpablodrexler.photomanager.infrastructure.persistence.mapper✕
- Connections
- 16 pairs of types, where a type in com.jpablodrexler.photomanager.infrastructure.persistence.adapter uses a type in com.jpablodrexler.photomanager.infrastructure.persistence.mapper.
- The types involved
com.jpablodrexler.photomanager.infrastructure.persistence.adapter.AlbumRepositoryImpl→com.jpablodrexler.photomanager.infrastructure.persistence.mapper.AlbumEntityMappercom.jpablodrexler.photomanager.infrastructure.persistence.adapter.AlbumRepositoryImpl→com.jpablodrexler.photomanager.infrastructure.persistence.mapper.AssetEntityMappercom.jpablodrexler.photomanager.infrastructure.persistence.adapter.AssetAudioRepositoryImpl→com.jpablodrexler.photomanager.infrastructure.persistence.mapper.AssetAudioEntityMappercom.jpablodrexler.photomanager.infrastructure.persistence.adapter.AssetExifRepositoryImpl→com.jpablodrexler.photomanager.infrastructure.persistence.mapper.AssetExifEntityMappercom.jpablodrexler.photomanager.infrastructure.persistence.adapter.AssetRepositoryImpl→com.jpablodrexler.photomanager.infrastructure.persistence.mapper.AssetEntityMappercom.jpablodrexler.photomanager.infrastructure.persistence.adapter.AssetRepositoryImpl→com.jpablodrexler.photomanager.infrastructure.persistence.mapper.FolderEntityMappercom.jpablodrexler.photomanager.infrastructure.persistence.adapter.AuditLogRepositoryImpl→com.jpablodrexler.photomanager.infrastructure.persistence.mapper.AuditLogDocumentMappercom.jpablodrexler.photomanager.infrastructure.persistence.adapter.ConvertConfigRepositoryImpl→com.jpablodrexler.photomanager.infrastructure.persistence.mapper.ConvertConfigEntityMappercom.jpablodrexler.photomanager.infrastructure.persistence.adapter.FolderRepositoryImpl→com.jpablodrexler.photomanager.infrastructure.persistence.mapper.FolderEntityMappercom.jpablodrexler.photomanager.infrastructure.persistence.adapter.RecentTargetPathRepositoryImpl→com.jpablodrexler.photomanager.infrastructure.persistence.mapper.RecentTargetPathEntityMappercom.jpablodrexler.photomanager.infrastructure.persistence.adapter.RefreshTokenRepositoryImpl→com.jpablodrexler.photomanager.infrastructure.persistence.mapper.RefreshTokenEntityMappercom.jpablodrexler.photomanager.infrastructure.persistence.adapter.SearchPresetRepositoryImpl→com.jpablodrexler.photomanager.infrastructure.persistence.mapper.SearchPresetEntityMappercom.jpablodrexler.photomanager.infrastructure.persistence.adapter.SyncConfigRepositoryImpl→com.jpablodrexler.photomanager.infrastructure.persistence.mapper.SyncConfigEntityMappercom.jpablodrexler.photomanager.infrastructure.persistence.adapter.TagRepositoryImpl→com.jpablodrexler.photomanager.infrastructure.persistence.mapper.TagEntityMappercom.jpablodrexler.photomanager.infrastructure.persistence.adapter.UserPreferenceRepositoryImpl→com.jpablodrexler.photomanager.infrastructure.persistence.mapper.UserPreferenceMappercom.jpablodrexler.photomanager.infrastructure.persistence.adapter.UserRepositoryImpl→com.jpablodrexler.photomanager.infrastructure.persistence.mapper.UserEntityMapper
- Direction
- com.jpablodrexler.photomanager.infrastructure.persistence.adapter uses com.jpablodrexler.photomanager.infrastructure.persistence.mapper, so a change to com.jpablodrexler.photomanager.infrastructure.persistence.mapper can break com.jpablodrexler.photomanager.infrastructure.persistence.adapter, while a change to com.jpablodrexler.photomanager.infrastructure.persistence.adapter can't break com.jpablodrexler.photomanager.infrastructure.persistence.mapper.
- Position
- Below the diagonal: com.jpablodrexler.photomanager.infrastructure.persistence.adapter uses a module listed above it, which is the healthy direction.
26→5 com.jpablodrexler.photomanager.infrastructure.service uses com.jpablodrexler.photomanager.domain.enums✕
- Connections
- 1 pair of types, where a type in com.jpablodrexler.photomanager.infrastructure.service uses a type in com.jpablodrexler.photomanager.domain.enums.
- The types involved
com.jpablodrexler.photomanager.infrastructure.service.StorageServiceAdapter→com.jpablodrexler.photomanager.domain.enums.ImageRotation
- Direction
- com.jpablodrexler.photomanager.infrastructure.service uses com.jpablodrexler.photomanager.domain.enums, so a change to com.jpablodrexler.photomanager.domain.enums can break com.jpablodrexler.photomanager.infrastructure.service, while a change to com.jpablodrexler.photomanager.infrastructure.service can't break com.jpablodrexler.photomanager.domain.enums.
- Position
- Below the diagonal: com.jpablodrexler.photomanager.infrastructure.service uses a module listed above it, which is the healthy direction.
26→10 com.jpablodrexler.photomanager.infrastructure.service uses com.jpablodrexler.photomanager.domain.model✕
- Connections
- 7 pairs of types, where a type in com.jpablodrexler.photomanager.infrastructure.service uses a type in com.jpablodrexler.photomanager.domain.model.
- The types involved
com.jpablodrexler.photomanager.infrastructure.service.AssetSearchCacheKeyGenerator→com.jpablodrexler.photomanager.domain.model.AssetFiltercom.jpablodrexler.photomanager.infrastructure.service.AudioMetadataService→com.jpablodrexler.photomanager.domain.model.AudioMetadatacom.jpablodrexler.photomanager.infrastructure.service.CatalogFolderServiceAdapter→com.jpablodrexler.photomanager.domain.model.Assetcom.jpablodrexler.photomanager.infrastructure.service.CatalogFolderServiceAdapter→com.jpablodrexler.photomanager.domain.model.Foldercom.jpablodrexler.photomanager.infrastructure.service.M3uPlaylistParserServiceAdapter→com.jpablodrexler.photomanager.domain.model.Assetcom.jpablodrexler.photomanager.infrastructure.service.PlsPlaylistParserServiceAdapter→com.jpablodrexler.photomanager.domain.model.Assetcom.jpablodrexler.photomanager.infrastructure.service.StorageServiceAdapter→com.jpablodrexler.photomanager.domain.model.ExifMetadata
- Direction
- com.jpablodrexler.photomanager.infrastructure.service uses com.jpablodrexler.photomanager.domain.model, so a change to com.jpablodrexler.photomanager.domain.model can break com.jpablodrexler.photomanager.infrastructure.service, while a change to com.jpablodrexler.photomanager.infrastructure.service can't break com.jpablodrexler.photomanager.domain.model.
- Position
- Below the diagonal: com.jpablodrexler.photomanager.infrastructure.service uses a module listed above it, which is the healthy direction.
26→15 com.jpablodrexler.photomanager.infrastructure.service uses com.jpablodrexler.photomanager.domain.port.in.catalog✕
- Connections
- 1 pair of types, where a type in com.jpablodrexler.photomanager.infrastructure.service uses a type in com.jpablodrexler.photomanager.domain.port.in.catalog.
- The types involved
com.jpablodrexler.photomanager.infrastructure.service.CatalogScheduler→com.jpablodrexler.photomanager.domain.port.in.catalog.CatalogAssetsUseCase
- Direction
- com.jpablodrexler.photomanager.infrastructure.service uses com.jpablodrexler.photomanager.domain.port.in.catalog, so a change to com.jpablodrexler.photomanager.domain.port.in.catalog can break com.jpablodrexler.photomanager.infrastructure.service, while a change to com.jpablodrexler.photomanager.infrastructure.service can't break com.jpablodrexler.photomanager.domain.port.in.catalog.
- Position
- Below the diagonal: com.jpablodrexler.photomanager.infrastructure.service uses a module listed above it, which is the healthy direction.
26→17 com.jpablodrexler.photomanager.infrastructure.service uses com.jpablodrexler.photomanager.domain.port.out✕
- Connections
- 25 pairs of types, where a type in com.jpablodrexler.photomanager.infrastructure.service uses a type in com.jpablodrexler.photomanager.domain.port.out.
- The types involved
com.jpablodrexler.photomanager.infrastructure.service.AssetSearchCacheServiceAdapter→com.jpablodrexler.photomanager.domain.port.out.AssetSearchCachePortcom.jpablodrexler.photomanager.infrastructure.service.CatalogFolderServiceAdapter→com.jpablodrexler.photomanager.domain.port.out.AssetAudioRepositorycom.jpablodrexler.photomanager.infrastructure.service.CatalogFolderServiceAdapter→com.jpablodrexler.photomanager.domain.port.out.AssetExifRepositorycom.jpablodrexler.photomanager.infrastructure.service.CatalogFolderServiceAdapter→com.jpablodrexler.photomanager.domain.port.out.AssetRepositorycom.jpablodrexler.photomanager.infrastructure.service.CatalogFolderServiceAdapter→com.jpablodrexler.photomanager.domain.port.out.CatalogFolderPortcom.jpablodrexler.photomanager.infrastructure.service.CatalogFolderServiceAdapter→com.jpablodrexler.photomanager.domain.port.out.FolderRepositorycom.jpablodrexler.photomanager.infrastructure.service.CatalogFolderServiceAdapter→com.jpablodrexler.photomanager.domain.port.out.StoragePortcom.jpablodrexler.photomanager.infrastructure.service.CatalogFolderServiceAdapter→com.jpablodrexler.photomanager.domain.port.out.ThumbnailPortcom.jpablodrexler.photomanager.infrastructure.service.CatalogRunHistoryServiceAdapter→com.jpablodrexler.photomanager.domain.port.out.CatalogRunHistoryPortcom.jpablodrexler.photomanager.infrastructure.service.JwtAuthenticationFilter→com.jpablodrexler.photomanager.domain.port.out.JwtTokenPortcom.jpablodrexler.photomanager.infrastructure.service.JwtTokenServiceAdapter→com.jpablodrexler.photomanager.domain.port.out.JwtTokenPortcom.jpablodrexler.photomanager.infrastructure.service.KafkaProgressRegistry→com.jpablodrexler.photomanager.domain.port.out.ProgressPortcom.jpablodrexler.photomanager.infrastructure.service.M3uPlaylistParserServiceAdapter→com.jpablodrexler.photomanager.domain.port.out.AssetRepositorycom.jpablodrexler.photomanager.infrastructure.service.PlsPlaylistParserServiceAdapter→com.jpablodrexler.photomanager.domain.port.out.AssetRepositorycom.jpablodrexler.photomanager.infrastructure.service.RefreshTokenIssuer→com.jpablodrexler.photomanager.domain.port.out.RefreshTokenRepositorycom.jpablodrexler.photomanager.infrastructure.service.RefreshTokenIssuer→com.jpablodrexler.photomanager.domain.port.out.UserRepositorycom.jpablodrexler.photomanager.infrastructure.service.RefreshTokenServiceAdapter→com.jpablodrexler.photomanager.domain.port.out.RefreshTokenPortcom.jpablodrexler.photomanager.infrastructure.service.RefreshTokenServiceAdapter→com.jpablodrexler.photomanager.domain.port.out.RefreshTokenRepositorycom.jpablodrexler.photomanager.infrastructure.service.RefreshTokenServiceAdapter→com.jpablodrexler.photomanager.domain.port.out.RotatedTokencom.jpablodrexler.photomanager.infrastructure.service.RefreshTokenServiceAdapter→com.jpablodrexler.photomanager.domain.port.out.UserRepositorycom.jpablodrexler.photomanager.infrastructure.service.StorageServiceAdapter→com.jpablodrexler.photomanager.domain.port.out.StoragePortcom.jpablodrexler.photomanager.infrastructure.service.ThumbnailStorageServiceAdapter→com.jpablodrexler.photomanager.domain.port.out.ThumbnailPortcom.jpablodrexler.photomanager.infrastructure.service.UserAuthServiceAdapter→com.jpablodrexler.photomanager.domain.port.out.JwtTokenPortcom.jpablodrexler.photomanager.infrastructure.service.UserAuthServiceAdapter→com.jpablodrexler.photomanager.domain.port.out.UserAuthPortcom.jpablodrexler.photomanager.infrastructure.service.UserAuthServiceAdapter→com.jpablodrexler.photomanager.domain.port.out.UserRepository
- Direction
- com.jpablodrexler.photomanager.infrastructure.service uses com.jpablodrexler.photomanager.domain.port.out, so a change to com.jpablodrexler.photomanager.domain.port.out can break com.jpablodrexler.photomanager.infrastructure.service, while a change to com.jpablodrexler.photomanager.infrastructure.service can't break com.jpablodrexler.photomanager.domain.port.out.
- Position
- Below the diagonal: com.jpablodrexler.photomanager.infrastructure.service uses a module listed above it, which is the healthy direction.
27→5 com.jpablodrexler.photomanager.infrastructure.web.dto.response uses com.jpablodrexler.photomanager.domain.enums✕
- Connections
- 2 pairs of types, where a type in com.jpablodrexler.photomanager.infrastructure.web.dto.response uses a type in com.jpablodrexler.photomanager.domain.enums.
- The types involved
com.jpablodrexler.photomanager.infrastructure.web.dto.response.AssetResponseDto→com.jpablodrexler.photomanager.domain.enums.FileTypecom.jpablodrexler.photomanager.infrastructure.web.dto.response.AssetResponseDto→com.jpablodrexler.photomanager.domain.enums.ImageRotation
- Direction
- com.jpablodrexler.photomanager.infrastructure.web.dto.response uses com.jpablodrexler.photomanager.domain.enums, so a change to com.jpablodrexler.photomanager.domain.enums can break com.jpablodrexler.photomanager.infrastructure.web.dto.response, while a change to com.jpablodrexler.photomanager.infrastructure.web.dto.response can't break com.jpablodrexler.photomanager.domain.enums.
- Position
- Below the diagonal: com.jpablodrexler.photomanager.infrastructure.web.dto.response uses a module listed above it, which is the healthy direction.
27→14 com.jpablodrexler.photomanager.infrastructure.web.dto.response uses com.jpablodrexler.photomanager.application.dto✕
- Connections
- 3 pairs of types, where a type in com.jpablodrexler.photomanager.infrastructure.web.dto.response uses a type in com.jpablodrexler.photomanager.application.dto.
- The types involved
com.jpablodrexler.photomanager.infrastructure.web.dto.response.AlbumResponseDto→com.jpablodrexler.photomanager.application.dto.AlbumFilterJsoncom.jpablodrexler.photomanager.infrastructure.web.dto.response.AlbumResponseDto→com.jpablodrexler.photomanager.application.dto.PaginatedDatacom.jpablodrexler.photomanager.infrastructure.web.dto.response.AlbumSummaryResponseDto→com.jpablodrexler.photomanager.application.dto.AlbumFilterJson
- Direction
- com.jpablodrexler.photomanager.infrastructure.web.dto.response uses com.jpablodrexler.photomanager.application.dto, so a change to com.jpablodrexler.photomanager.application.dto can break com.jpablodrexler.photomanager.infrastructure.web.dto.response, while a change to com.jpablodrexler.photomanager.infrastructure.web.dto.response can't break com.jpablodrexler.photomanager.application.dto.
- Position
- Below the diagonal: com.jpablodrexler.photomanager.infrastructure.web.dto.response uses a module listed above it, which is the healthy direction.
28→12 JPPhotoManager.Domain.Interfaces.Repositories uses JPPhotoManager.Domain.Entities✕
- Connections
- 5 pairs of types, where a type in JPPhotoManager.Domain.Interfaces.Repositories uses a type in JPPhotoManager.Domain.Entities.
- The types involved
JPPhotoManager.Domain.Interfaces.Repositories.IAssetRepository→JPPhotoManager.Domain.Entities.AssetJPPhotoManager.Domain.Interfaces.Repositories.IAssetRepository→JPPhotoManager.Domain.Entities.FolderJPPhotoManager.Domain.Interfaces.Repositories.IConvertAssetsConfigurationRepository→JPPhotoManager.Domain.Entities.ConvertAssetsConfigurationJPPhotoManager.Domain.Interfaces.Repositories.IFolderRepository→JPPhotoManager.Domain.Entities.FolderJPPhotoManager.Domain.Interfaces.Repositories.ISyncAssetsConfigurationRepository→JPPhotoManager.Domain.Entities.SyncAssetsConfiguration
- Direction
- JPPhotoManager.Domain.Interfaces.Repositories uses JPPhotoManager.Domain.Entities, so a change to JPPhotoManager.Domain.Entities can break JPPhotoManager.Domain.Interfaces.Repositories, while a change to JPPhotoManager.Domain.Interfaces.Repositories can't break JPPhotoManager.Domain.Entities.
- Position
- Below the diagonal: JPPhotoManager.Domain.Interfaces.Repositories uses a module listed above it, which is the healthy direction.
28→19 JPPhotoManager.Domain.Interfaces.Repositories uses JPPhotoManager.Domain✕
- Connections
- 1 pair of types, where a type in JPPhotoManager.Domain.Interfaces.Repositories uses a type in JPPhotoManager.Domain.
- The types involved
JPPhotoManager.Domain.Interfaces.Repositories.IAssetRepository→JPPhotoManager.Domain.PaginatedData
- Direction
- JPPhotoManager.Domain.Interfaces.Repositories uses JPPhotoManager.Domain, so a change to JPPhotoManager.Domain can break JPPhotoManager.Domain.Interfaces.Repositories, while a change to JPPhotoManager.Domain.Interfaces.Repositories can't break JPPhotoManager.Domain.
- Position
- Below the diagonal: JPPhotoManager.Domain.Interfaces.Repositories uses a module listed above it, which is the healthy direction.
29→6 JPPhotoManager.Infrastructure.Services uses JPPhotoManager.Domain.Interfaces.Services✕
- Connections
- 7 pairs of types, where a type in JPPhotoManager.Infrastructure.Services uses a type in JPPhotoManager.Domain.Interfaces.Services.
- The types involved
JPPhotoManager.Infrastructure.Services.AssetHashCalculatorService→JPPhotoManager.Domain.Interfaces.Services.IAssetHashCalculatorServiceJPPhotoManager.Infrastructure.Services.GitHubReleaseAvailabilityService→JPPhotoManager.Domain.Interfaces.Services.IReleaseAvailabilityServiceJPPhotoManager.Infrastructure.Services.GitHubReleaseAvailabilityService→JPPhotoManager.Domain.Interfaces.Services.IUserConfigurationServiceJPPhotoManager.Infrastructure.Services.ProcessService→JPPhotoManager.Domain.Interfaces.Services.IProcessServiceJPPhotoManager.Infrastructure.Services.StorageService→JPPhotoManager.Domain.Interfaces.Services.IStorageServiceJPPhotoManager.Infrastructure.Services.StorageService→JPPhotoManager.Domain.Interfaces.Services.IUserConfigurationServiceJPPhotoManager.Infrastructure.Services.UserConfigurationService→JPPhotoManager.Domain.Interfaces.Services.IUserConfigurationService
- Direction
- JPPhotoManager.Infrastructure.Services uses JPPhotoManager.Domain.Interfaces.Services, so a change to JPPhotoManager.Domain.Interfaces.Services can break JPPhotoManager.Infrastructure.Services, while a change to JPPhotoManager.Infrastructure.Services can't break JPPhotoManager.Domain.Interfaces.Services.
- Position
- Below the diagonal: JPPhotoManager.Infrastructure.Services uses a module listed above it, which is the healthy direction.
29→12 JPPhotoManager.Infrastructure.Services uses JPPhotoManager.Domain.Entities✕
- Connections
- 3 pairs of types, where a type in JPPhotoManager.Infrastructure.Services uses a type in JPPhotoManager.Domain.Entities.
- The types involved
JPPhotoManager.Infrastructure.Services.StorageService→JPPhotoManager.Domain.Entities.AssetJPPhotoManager.Infrastructure.Services.StorageService→JPPhotoManager.Domain.Entities.FolderJPPhotoManager.Infrastructure.Services.UserConfigurationService→JPPhotoManager.Domain.Entities.Asset
- Direction
- JPPhotoManager.Infrastructure.Services uses JPPhotoManager.Domain.Entities, so a change to JPPhotoManager.Domain.Entities can break JPPhotoManager.Infrastructure.Services, while a change to JPPhotoManager.Infrastructure.Services can't break JPPhotoManager.Domain.Entities.
- Position
- Below the diagonal: JPPhotoManager.Infrastructure.Services uses a module listed above it, which is the healthy direction.
29→19 JPPhotoManager.Infrastructure.Services uses JPPhotoManager.Domain✕
- Connections
- 3 pairs of types, where a type in JPPhotoManager.Infrastructure.Services uses a type in JPPhotoManager.Domain.
- The types involved
JPPhotoManager.Infrastructure.Services.GitHubReleaseAvailabilityService→JPPhotoManager.Domain.ReleaseJPPhotoManager.Infrastructure.Services.UserConfigurationService→JPPhotoManager.Domain.AboutInformationJPPhotoManager.Infrastructure.Services.UserConfigurationService→JPPhotoManager.Domain.WallpaperStyle
- Direction
- JPPhotoManager.Infrastructure.Services uses JPPhotoManager.Domain, so a change to JPPhotoManager.Domain can break JPPhotoManager.Infrastructure.Services, while a change to JPPhotoManager.Infrastructure.Services can't break JPPhotoManager.Domain.
- Position
- Below the diagonal: JPPhotoManager.Infrastructure.Services uses a module listed above it, which is the healthy direction.
30→5 com.jpablodrexler.photomanager.config uses com.jpablodrexler.photomanager.domain.enums✕
- Connections
- 1 pair of types, where a type in com.jpablodrexler.photomanager.config uses a type in com.jpablodrexler.photomanager.domain.enums.
- The types involved
com.jpablodrexler.photomanager.config.UploadProcessorKafkaConfig→com.jpablodrexler.photomanager.domain.enums.UploadStage
- Direction
- com.jpablodrexler.photomanager.config uses com.jpablodrexler.photomanager.domain.enums, so a change to com.jpablodrexler.photomanager.domain.enums can break com.jpablodrexler.photomanager.config, while a change to com.jpablodrexler.photomanager.config can't break com.jpablodrexler.photomanager.domain.enums.
- Position
- Below the diagonal: com.jpablodrexler.photomanager.config uses a module listed above it, which is the healthy direction.
30→17 com.jpablodrexler.photomanager.config uses com.jpablodrexler.photomanager.domain.port.out✕
- Connections
- 4 pairs of types, where a type in com.jpablodrexler.photomanager.config uses a type in com.jpablodrexler.photomanager.domain.port.out.
- The types involved
com.jpablodrexler.photomanager.config.DataInitializer→com.jpablodrexler.photomanager.domain.port.out.UserAuthPortcom.jpablodrexler.photomanager.config.DataInitializer→com.jpablodrexler.photomanager.domain.port.out.UserRepositorycom.jpablodrexler.photomanager.config.UploadProcessorKafkaConfig→com.jpablodrexler.photomanager.domain.port.out.AssetRepositorycom.jpablodrexler.photomanager.config.UserConfig→com.jpablodrexler.photomanager.domain.port.out.UserRepository
- Direction
- com.jpablodrexler.photomanager.config uses com.jpablodrexler.photomanager.domain.port.out, so a change to com.jpablodrexler.photomanager.domain.port.out can break com.jpablodrexler.photomanager.config, while a change to com.jpablodrexler.photomanager.config can't break com.jpablodrexler.photomanager.domain.port.out.
- Position
- Below the diagonal: com.jpablodrexler.photomanager.config uses a module listed above it, which is the healthy direction.
30→26 com.jpablodrexler.photomanager.config uses com.jpablodrexler.photomanager.infrastructure.service✕
- Connections
- 1 pair of types, where a type in com.jpablodrexler.photomanager.config uses a type in com.jpablodrexler.photomanager.infrastructure.service.
- The types involved
com.jpablodrexler.photomanager.config.SecurityConfig→com.jpablodrexler.photomanager.infrastructure.service.JwtAuthenticationFilter
- Direction
- com.jpablodrexler.photomanager.config uses com.jpablodrexler.photomanager.infrastructure.service, so a change to com.jpablodrexler.photomanager.infrastructure.service can break com.jpablodrexler.photomanager.config, while a change to com.jpablodrexler.photomanager.config can't break com.jpablodrexler.photomanager.infrastructure.service.
- Position
- Below the diagonal: com.jpablodrexler.photomanager.config uses a module listed above it, which is the healthy direction.
31→10 com.jpablodrexler.photomanager.infrastructure.batch uses com.jpablodrexler.photomanager.domain.model✕
- Connections
- 5 pairs of types, where a type in com.jpablodrexler.photomanager.infrastructure.batch uses a type in com.jpablodrexler.photomanager.domain.model.
- The types involved
com.jpablodrexler.photomanager.infrastructure.batch.CatalogAssetItemProcessor→com.jpablodrexler.photomanager.domain.model.AssetExifcom.jpablodrexler.photomanager.infrastructure.batch.CatalogAssetItemWriter→com.jpablodrexler.photomanager.domain.model.Foldercom.jpablodrexler.photomanager.infrastructure.batch.CatalogBatchItem→com.jpablodrexler.photomanager.domain.model.Assetcom.jpablodrexler.photomanager.infrastructure.batch.CatalogBatchItem→com.jpablodrexler.photomanager.domain.model.AssetAudiocom.jpablodrexler.photomanager.infrastructure.batch.CatalogBatchItem→com.jpablodrexler.photomanager.domain.model.AssetExif
- Direction
- com.jpablodrexler.photomanager.infrastructure.batch uses com.jpablodrexler.photomanager.domain.model, so a change to com.jpablodrexler.photomanager.domain.model can break com.jpablodrexler.photomanager.infrastructure.batch, while a change to com.jpablodrexler.photomanager.infrastructure.batch can't break com.jpablodrexler.photomanager.domain.model.
- Position
- Below the diagonal: com.jpablodrexler.photomanager.infrastructure.batch uses a module listed above it, which is the healthy direction.
31→16 com.jpablodrexler.photomanager.infrastructure.batch uses com.jpablodrexler.photomanager.domain.port.in.folder✕
- Connections
- 1 pair of types, where a type in com.jpablodrexler.photomanager.infrastructure.batch uses a type in com.jpablodrexler.photomanager.domain.port.in.folder.
- The types involved
com.jpablodrexler.photomanager.infrastructure.batch.CatalogItemWriteListener→com.jpablodrexler.photomanager.domain.port.in.folder.PruneDeletedFoldersUseCase
- Direction
- com.jpablodrexler.photomanager.infrastructure.batch uses com.jpablodrexler.photomanager.domain.port.in.folder, so a change to com.jpablodrexler.photomanager.domain.port.in.folder can break com.jpablodrexler.photomanager.infrastructure.batch, while a change to com.jpablodrexler.photomanager.infrastructure.batch can't break com.jpablodrexler.photomanager.domain.port.in.folder.
- Position
- Below the diagonal: com.jpablodrexler.photomanager.infrastructure.batch uses a module listed above it, which is the healthy direction.
31→17 com.jpablodrexler.photomanager.infrastructure.batch uses com.jpablodrexler.photomanager.domain.port.out✕
- Connections
- 17 pairs of types, where a type in com.jpablodrexler.photomanager.infrastructure.batch uses a type in com.jpablodrexler.photomanager.domain.port.out.
- The types involved
com.jpablodrexler.photomanager.infrastructure.batch.CatalogAssetItemProcessor→com.jpablodrexler.photomanager.domain.port.out.StoragePortcom.jpablodrexler.photomanager.infrastructure.batch.CatalogAssetItemWriter→com.jpablodrexler.photomanager.domain.port.out.AssetAudioRepositorycom.jpablodrexler.photomanager.infrastructure.batch.CatalogAssetItemWriter→com.jpablodrexler.photomanager.domain.port.out.AssetExifRepositorycom.jpablodrexler.photomanager.infrastructure.batch.CatalogAssetItemWriter→com.jpablodrexler.photomanager.domain.port.out.AssetRepositorycom.jpablodrexler.photomanager.infrastructure.batch.CatalogAssetItemWriter→com.jpablodrexler.photomanager.domain.port.out.FolderRepositorycom.jpablodrexler.photomanager.infrastructure.batch.CatalogAssetItemWriter→com.jpablodrexler.photomanager.domain.port.out.StoragePortcom.jpablodrexler.photomanager.infrastructure.batch.CatalogAssetItemWriter→com.jpablodrexler.photomanager.domain.port.out.ThumbnailPortcom.jpablodrexler.photomanager.infrastructure.batch.CatalogFileItemReader→com.jpablodrexler.photomanager.domain.port.out.AssetRepositorycom.jpablodrexler.photomanager.infrastructure.batch.CatalogFileItemReader→com.jpablodrexler.photomanager.domain.port.out.FolderRepositorycom.jpablodrexler.photomanager.infrastructure.batch.CatalogFileItemReader→com.jpablodrexler.photomanager.domain.port.out.StoragePortcom.jpablodrexler.photomanager.infrastructure.batch.CatalogFolderPartitioner→com.jpablodrexler.photomanager.domain.port.out.StoragePortcom.jpablodrexler.photomanager.infrastructure.batch.CatalogJobConfig→com.jpablodrexler.photomanager.domain.port.out.AssetAudioRepositorycom.jpablodrexler.photomanager.infrastructure.batch.CatalogJobConfig→com.jpablodrexler.photomanager.domain.port.out.AssetExifRepositorycom.jpablodrexler.photomanager.infrastructure.batch.CatalogJobConfig→com.jpablodrexler.photomanager.domain.port.out.AssetRepositorycom.jpablodrexler.photomanager.infrastructure.batch.CatalogJobConfig→com.jpablodrexler.photomanager.domain.port.out.FolderRepositorycom.jpablodrexler.photomanager.infrastructure.batch.CatalogJobConfig→com.jpablodrexler.photomanager.domain.port.out.StoragePortcom.jpablodrexler.photomanager.infrastructure.batch.CatalogJobConfig→com.jpablodrexler.photomanager.domain.port.out.ThumbnailPort
- Direction
- com.jpablodrexler.photomanager.infrastructure.batch uses com.jpablodrexler.photomanager.domain.port.out, so a change to com.jpablodrexler.photomanager.domain.port.out can break com.jpablodrexler.photomanager.infrastructure.batch, while a change to com.jpablodrexler.photomanager.infrastructure.batch can't break com.jpablodrexler.photomanager.domain.port.out.
- Position
- Below the diagonal: com.jpablodrexler.photomanager.infrastructure.batch uses a module listed above it, which is the healthy direction.
31→26 com.jpablodrexler.photomanager.infrastructure.batch uses com.jpablodrexler.photomanager.infrastructure.service✕
- Connections
- 2 pairs of types, where a type in com.jpablodrexler.photomanager.infrastructure.batch uses a type in com.jpablodrexler.photomanager.infrastructure.service.
- The types involved
com.jpablodrexler.photomanager.infrastructure.batch.CatalogAssetItemProcessor→com.jpablodrexler.photomanager.infrastructure.service.AudioMetadataServicecom.jpablodrexler.photomanager.infrastructure.batch.CatalogJobConfig→com.jpablodrexler.photomanager.infrastructure.service.AudioMetadataService
- Direction
- com.jpablodrexler.photomanager.infrastructure.batch uses com.jpablodrexler.photomanager.infrastructure.service, so a change to com.jpablodrexler.photomanager.infrastructure.service can break com.jpablodrexler.photomanager.infrastructure.batch, while a change to com.jpablodrexler.photomanager.infrastructure.batch can't break com.jpablodrexler.photomanager.infrastructure.service.
- Position
- Below the diagonal: com.jpablodrexler.photomanager.infrastructure.batch uses a module listed above it, which is the healthy direction.
32→10 com.jpablodrexler.photomanager.infrastructure.kafka uses com.jpablodrexler.photomanager.domain.model✕
- Connections
- 1 pair of types, where a type in com.jpablodrexler.photomanager.infrastructure.kafka uses a type in com.jpablodrexler.photomanager.domain.model.
- The types involved
com.jpablodrexler.photomanager.infrastructure.kafka.AuditLogKafkaListener→com.jpablodrexler.photomanager.domain.model.AuditEvent
- Direction
- com.jpablodrexler.photomanager.infrastructure.kafka uses com.jpablodrexler.photomanager.domain.model, so a change to com.jpablodrexler.photomanager.domain.model can break com.jpablodrexler.photomanager.infrastructure.kafka, while a change to com.jpablodrexler.photomanager.infrastructure.kafka can't break com.jpablodrexler.photomanager.domain.model.
- Position
- Below the diagonal: com.jpablodrexler.photomanager.infrastructure.kafka uses a module listed above it, which is the healthy direction.
32→14 com.jpablodrexler.photomanager.infrastructure.kafka uses com.jpablodrexler.photomanager.application.dto✕
- Connections
- 16 pairs of types, where a type in com.jpablodrexler.photomanager.infrastructure.kafka uses a type in com.jpablodrexler.photomanager.application.dto.
- The types involved
com.jpablodrexler.photomanager.infrastructure.kafka.AssetExifProcessor→com.jpablodrexler.photomanager.application.dto.AssetUploadedEventcom.jpablodrexler.photomanager.infrastructure.kafka.AssetHashProcessor→com.jpablodrexler.photomanager.application.dto.AssetUploadedEventcom.jpablodrexler.photomanager.infrastructure.kafka.AssetSearchCacheInvalidationListener→com.jpablodrexler.photomanager.application.dto.AssetCatalogedEventcom.jpablodrexler.photomanager.infrastructure.kafka.AssetSearchCacheInvalidationListener→com.jpablodrexler.photomanager.application.dto.AssetDeletedEventcom.jpablodrexler.photomanager.infrastructure.kafka.AssetThumbnailProcessor→com.jpablodrexler.photomanager.application.dto.AssetUploadedEventcom.jpablodrexler.photomanager.infrastructure.kafka.AuditLogKafkaListener→com.jpablodrexler.photomanager.application.dto.AssetCatalogedEventcom.jpablodrexler.photomanager.infrastructure.kafka.AuditLogKafkaListener→com.jpablodrexler.photomanager.application.dto.AssetDeletedEventcom.jpablodrexler.photomanager.infrastructure.kafka.AuditLogKafkaListener→com.jpablodrexler.photomanager.application.dto.CatalogProgressMessagecom.jpablodrexler.photomanager.infrastructure.kafka.AuditLogKafkaListener→com.jpablodrexler.photomanager.application.dto.ConvertAssetsResultcom.jpablodrexler.photomanager.infrastructure.kafka.AuditLogKafkaListener→com.jpablodrexler.photomanager.application.dto.ConvertProgressMessagecom.jpablodrexler.photomanager.infrastructure.kafka.AuditLogKafkaListener→com.jpablodrexler.photomanager.application.dto.SyncAssetsResultcom.jpablodrexler.photomanager.infrastructure.kafka.AuditLogKafkaListener→com.jpablodrexler.photomanager.application.dto.SyncProgressMessagecom.jpablodrexler.photomanager.infrastructure.kafka.KafkaProgressListener→com.jpablodrexler.photomanager.application.dto.CatalogProgressMessagecom.jpablodrexler.photomanager.infrastructure.kafka.KafkaProgressListener→com.jpablodrexler.photomanager.application.dto.ConvertProgressMessagecom.jpablodrexler.photomanager.infrastructure.kafka.KafkaProgressListener→com.jpablodrexler.photomanager.application.dto.SyncProgressMessagecom.jpablodrexler.photomanager.infrastructure.kafka.KafkaProgressListener→com.jpablodrexler.photomanager.application.dto.UploadProgressMessage
- Direction
- com.jpablodrexler.photomanager.infrastructure.kafka uses com.jpablodrexler.photomanager.application.dto, so a change to com.jpablodrexler.photomanager.application.dto can break com.jpablodrexler.photomanager.infrastructure.kafka, while a change to com.jpablodrexler.photomanager.infrastructure.kafka can't break com.jpablodrexler.photomanager.application.dto.
- Position
- Below the diagonal: com.jpablodrexler.photomanager.infrastructure.kafka uses a module listed above it, which is the healthy direction.
32→16 com.jpablodrexler.photomanager.infrastructure.kafka uses com.jpablodrexler.photomanager.domain.port.in.folder✕
- Connections
- 1 pair of types, where a type in com.jpablodrexler.photomanager.infrastructure.kafka uses a type in com.jpablodrexler.photomanager.domain.port.in.folder.
- The types involved
com.jpablodrexler.photomanager.infrastructure.kafka.AssetSearchCacheInvalidationListener→com.jpablodrexler.photomanager.domain.port.in.folder.GetFolderIdByPathUseCase
- Direction
- com.jpablodrexler.photomanager.infrastructure.kafka uses com.jpablodrexler.photomanager.domain.port.in.folder, so a change to com.jpablodrexler.photomanager.domain.port.in.folder can break com.jpablodrexler.photomanager.infrastructure.kafka, while a change to com.jpablodrexler.photomanager.infrastructure.kafka can't break com.jpablodrexler.photomanager.domain.port.in.folder.
- Position
- Below the diagonal: com.jpablodrexler.photomanager.infrastructure.kafka uses a module listed above it, which is the healthy direction.
32→17 com.jpablodrexler.photomanager.infrastructure.kafka uses com.jpablodrexler.photomanager.domain.port.out✕
- Connections
- 10 pairs of types, where a type in com.jpablodrexler.photomanager.infrastructure.kafka uses a type in com.jpablodrexler.photomanager.domain.port.out.
- The types involved
com.jpablodrexler.photomanager.infrastructure.kafka.AssetExifProcessor→com.jpablodrexler.photomanager.domain.port.out.AssetExifRepositorycom.jpablodrexler.photomanager.infrastructure.kafka.AssetExifProcessor→com.jpablodrexler.photomanager.domain.port.out.AssetRepositorycom.jpablodrexler.photomanager.infrastructure.kafka.AssetExifProcessor→com.jpablodrexler.photomanager.domain.port.out.StoragePortcom.jpablodrexler.photomanager.infrastructure.kafka.AssetHashProcessor→com.jpablodrexler.photomanager.domain.port.out.AssetRepositorycom.jpablodrexler.photomanager.infrastructure.kafka.AssetHashProcessor→com.jpablodrexler.photomanager.domain.port.out.StoragePortcom.jpablodrexler.photomanager.infrastructure.kafka.AssetSearchCacheInvalidationListener→com.jpablodrexler.photomanager.domain.port.out.AssetSearchCachePortcom.jpablodrexler.photomanager.infrastructure.kafka.AssetThumbnailProcessor→com.jpablodrexler.photomanager.domain.port.out.AssetRepositorycom.jpablodrexler.photomanager.infrastructure.kafka.AssetThumbnailProcessor→com.jpablodrexler.photomanager.domain.port.out.StoragePortcom.jpablodrexler.photomanager.infrastructure.kafka.AssetThumbnailProcessor→com.jpablodrexler.photomanager.domain.port.out.ThumbnailPortcom.jpablodrexler.photomanager.infrastructure.kafka.AuditLogKafkaListener→com.jpablodrexler.photomanager.domain.port.out.AuditLogRepository
- Direction
- com.jpablodrexler.photomanager.infrastructure.kafka uses com.jpablodrexler.photomanager.domain.port.out, so a change to com.jpablodrexler.photomanager.domain.port.out can break com.jpablodrexler.photomanager.infrastructure.kafka, while a change to com.jpablodrexler.photomanager.infrastructure.kafka can't break com.jpablodrexler.photomanager.domain.port.out.
- Position
- Below the diagonal: com.jpablodrexler.photomanager.infrastructure.kafka uses a module listed above it, which is the healthy direction.
32→26 com.jpablodrexler.photomanager.infrastructure.kafka uses com.jpablodrexler.photomanager.infrastructure.service✕
- Connections
- 1 pair of types, where a type in com.jpablodrexler.photomanager.infrastructure.kafka uses a type in com.jpablodrexler.photomanager.infrastructure.service.
- The types involved
com.jpablodrexler.photomanager.infrastructure.kafka.KafkaProgressListener→com.jpablodrexler.photomanager.infrastructure.service.KafkaProgressRegistry
- Direction
- com.jpablodrexler.photomanager.infrastructure.kafka uses com.jpablodrexler.photomanager.infrastructure.service, so a change to com.jpablodrexler.photomanager.infrastructure.service can break com.jpablodrexler.photomanager.infrastructure.kafka, while a change to com.jpablodrexler.photomanager.infrastructure.kafka can't break com.jpablodrexler.photomanager.infrastructure.service.
- Position
- Below the diagonal: com.jpablodrexler.photomanager.infrastructure.kafka uses a module listed above it, which is the healthy direction.
33→10 com.jpablodrexler.photomanager.infrastructure.web.mapper uses com.jpablodrexler.photomanager.domain.model✕
- Connections
- 23 pairs of types, where a type in com.jpablodrexler.photomanager.infrastructure.web.mapper uses a type in com.jpablodrexler.photomanager.domain.model.
- The types involved
com.jpablodrexler.photomanager.infrastructure.web.mapper.AlbumWebMapper→com.jpablodrexler.photomanager.domain.model.AlbumDatacom.jpablodrexler.photomanager.infrastructure.web.mapper.AnalyticsWebMapper→com.jpablodrexler.photomanager.domain.model.AnalyticsDatacom.jpablodrexler.photomanager.infrastructure.web.mapper.AnalyticsWebMapper→com.jpablodrexler.photomanager.domain.model.FolderStorageEntrycom.jpablodrexler.photomanager.infrastructure.web.mapper.AnalyticsWebMapper→com.jpablodrexler.photomanager.domain.model.FormatEntrycom.jpablodrexler.photomanager.infrastructure.web.mapper.AnalyticsWebMapper→com.jpablodrexler.photomanager.domain.model.MonthlyCountEntrycom.jpablodrexler.photomanager.infrastructure.web.mapper.AnalyticsWebMapper→com.jpablodrexler.photomanager.domain.model.RatingEntrycom.jpablodrexler.photomanager.infrastructure.web.mapper.AssetWebMapper→com.jpablodrexler.photomanager.domain.model.Assetcom.jpablodrexler.photomanager.infrastructure.web.mapper.AssetWebMapper→com.jpablodrexler.photomanager.domain.model.AssetExifcom.jpablodrexler.photomanager.infrastructure.web.mapper.AssetWebMapper→com.jpablodrexler.photomanager.domain.model.CropRegioncom.jpablodrexler.photomanager.infrastructure.web.mapper.AssetWebMapper→com.jpablodrexler.photomanager.domain.model.RenamePreviewcom.jpablodrexler.photomanager.infrastructure.web.mapper.AssetWebMapper→com.jpablodrexler.photomanager.domain.model.TimelineGroupcom.jpablodrexler.photomanager.infrastructure.web.mapper.AuditLogWebMapper→com.jpablodrexler.photomanager.domain.model.AuditEventcom.jpablodrexler.photomanager.infrastructure.web.mapper.ConvertWebMapper→com.jpablodrexler.photomanager.domain.model.ConvertDirectoriesDefinitioncom.jpablodrexler.photomanager.infrastructure.web.mapper.FolderWebMapper→com.jpablodrexler.photomanager.domain.model.Foldercom.jpablodrexler.photomanager.infrastructure.web.mapper.HomeWebMapper→com.jpablodrexler.photomanager.domain.model.AssetSummarycom.jpablodrexler.photomanager.infrastructure.web.mapper.HomeWebMapper→com.jpablodrexler.photomanager.domain.model.FolderStatcom.jpablodrexler.photomanager.infrastructure.web.mapper.HomeWebMapper→com.jpablodrexler.photomanager.domain.model.HomeStatscom.jpablodrexler.photomanager.infrastructure.web.mapper.SearchPresetFilterJsonConverter→com.jpablodrexler.photomanager.domain.model.FilterPresetcom.jpablodrexler.photomanager.infrastructure.web.mapper.SearchPresetWebMapper→com.jpablodrexler.photomanager.domain.model.FilterPresetcom.jpablodrexler.photomanager.infrastructure.web.mapper.SearchPresetWebMapper→com.jpablodrexler.photomanager.domain.model.SearchPresetcom.jpablodrexler.photomanager.infrastructure.web.mapper.SessionWebMapper→com.jpablodrexler.photomanager.domain.model.SessionInfocom.jpablodrexler.photomanager.infrastructure.web.mapper.SyncWebMapper→com.jpablodrexler.photomanager.domain.model.SyncDirectoriesDefinitioncom.jpablodrexler.photomanager.infrastructure.web.mapper.UserAdminWebMapper→com.jpablodrexler.photomanager.domain.model.UserSummary
- Direction
- com.jpablodrexler.photomanager.infrastructure.web.mapper uses com.jpablodrexler.photomanager.domain.model, so a change to com.jpablodrexler.photomanager.domain.model can break com.jpablodrexler.photomanager.infrastructure.web.mapper, while a change to com.jpablodrexler.photomanager.infrastructure.web.mapper can't break com.jpablodrexler.photomanager.domain.model.
- Position
- Below the diagonal: com.jpablodrexler.photomanager.infrastructure.web.mapper uses a module listed above it, which is the healthy direction.
33→14 com.jpablodrexler.photomanager.infrastructure.web.mapper uses com.jpablodrexler.photomanager.application.dto✕
- Connections
- 2 pairs of types, where a type in com.jpablodrexler.photomanager.infrastructure.web.mapper uses a type in com.jpablodrexler.photomanager.application.dto.
- The types involved
com.jpablodrexler.photomanager.infrastructure.web.mapper.AlbumFilterJsonConverter→com.jpablodrexler.photomanager.application.dto.AlbumFilterJsoncom.jpablodrexler.photomanager.infrastructure.web.mapper.AlbumWebMapper→com.jpablodrexler.photomanager.application.dto.PaginatedData
- Direction
- com.jpablodrexler.photomanager.infrastructure.web.mapper uses com.jpablodrexler.photomanager.application.dto, so a change to com.jpablodrexler.photomanager.application.dto can break com.jpablodrexler.photomanager.infrastructure.web.mapper, while a change to com.jpablodrexler.photomanager.infrastructure.web.mapper can't break com.jpablodrexler.photomanager.application.dto.
- Position
- Below the diagonal: com.jpablodrexler.photomanager.infrastructure.web.mapper uses a module listed above it, which is the healthy direction.
33→27 com.jpablodrexler.photomanager.infrastructure.web.mapper uses com.jpablodrexler.photomanager.infrastructure.web.dto.response✕
- Connections
- 20 pairs of types, where a type in com.jpablodrexler.photomanager.infrastructure.web.mapper uses a type in com.jpablodrexler.photomanager.infrastructure.web.dto.response.
- The types involved
com.jpablodrexler.photomanager.infrastructure.web.mapper.AlbumWebMapper→com.jpablodrexler.photomanager.infrastructure.web.dto.response.AlbumResponseDtocom.jpablodrexler.photomanager.infrastructure.web.mapper.AlbumWebMapper→com.jpablodrexler.photomanager.infrastructure.web.dto.response.AlbumSummaryResponseDtocom.jpablodrexler.photomanager.infrastructure.web.mapper.AlbumWebMapper→com.jpablodrexler.photomanager.infrastructure.web.dto.response.AssetResponseDtocom.jpablodrexler.photomanager.infrastructure.web.mapper.AnalyticsWebMapper→com.jpablodrexler.photomanager.infrastructure.web.dto.response.AnalyticsResponseDtocom.jpablodrexler.photomanager.infrastructure.web.mapper.AnalyticsWebMapper→com.jpablodrexler.photomanager.infrastructure.web.dto.response.FolderStorageEntryDtocom.jpablodrexler.photomanager.infrastructure.web.mapper.AnalyticsWebMapper→com.jpablodrexler.photomanager.infrastructure.web.dto.response.FormatEntryDtocom.jpablodrexler.photomanager.infrastructure.web.mapper.AnalyticsWebMapper→com.jpablodrexler.photomanager.infrastructure.web.dto.response.MonthlyCountEntryDtocom.jpablodrexler.photomanager.infrastructure.web.mapper.AnalyticsWebMapper→com.jpablodrexler.photomanager.infrastructure.web.dto.response.RatingEntryDtocom.jpablodrexler.photomanager.infrastructure.web.mapper.AssetWebMapper→com.jpablodrexler.photomanager.infrastructure.web.dto.response.AssetResponseDtocom.jpablodrexler.photomanager.infrastructure.web.mapper.AssetWebMapper→com.jpablodrexler.photomanager.infrastructure.web.dto.response.ExifMetadataResponseDtocom.jpablodrexler.photomanager.infrastructure.web.mapper.AssetWebMapper→com.jpablodrexler.photomanager.infrastructure.web.dto.response.RenamePreviewResponseDtocom.jpablodrexler.photomanager.infrastructure.web.mapper.AssetWebMapper→com.jpablodrexler.photomanager.infrastructure.web.dto.response.TimelineGroupResponseDtocom.jpablodrexler.photomanager.infrastructure.web.mapper.AuditLogWebMapper→com.jpablodrexler.photomanager.infrastructure.web.dto.response.AuditLogEntryResponseDtocom.jpablodrexler.photomanager.infrastructure.web.mapper.FolderWebMapper→com.jpablodrexler.photomanager.infrastructure.web.dto.response.FolderResponseDtocom.jpablodrexler.photomanager.infrastructure.web.mapper.HomeWebMapper→com.jpablodrexler.photomanager.infrastructure.web.dto.response.AssetSummaryResponseDtocom.jpablodrexler.photomanager.infrastructure.web.mapper.HomeWebMapper→com.jpablodrexler.photomanager.infrastructure.web.dto.response.FolderStatResponseDtocom.jpablodrexler.photomanager.infrastructure.web.mapper.HomeWebMapper→com.jpablodrexler.photomanager.infrastructure.web.dto.response.HomeStatsResponseDtocom.jpablodrexler.photomanager.infrastructure.web.mapper.SearchPresetWebMapper→com.jpablodrexler.photomanager.infrastructure.web.dto.response.SearchPresetResponseDtocom.jpablodrexler.photomanager.infrastructure.web.mapper.SessionWebMapper→com.jpablodrexler.photomanager.infrastructure.web.dto.response.SessionResponseDtocom.jpablodrexler.photomanager.infrastructure.web.mapper.UserAdminWebMapper→com.jpablodrexler.photomanager.infrastructure.web.dto.response.UserSummaryResponseDto
- Direction
- com.jpablodrexler.photomanager.infrastructure.web.mapper uses com.jpablodrexler.photomanager.infrastructure.web.dto.response, so a change to com.jpablodrexler.photomanager.infrastructure.web.dto.response can break com.jpablodrexler.photomanager.infrastructure.web.mapper, while a change to com.jpablodrexler.photomanager.infrastructure.web.mapper can't break com.jpablodrexler.photomanager.infrastructure.web.dto.response.
- Position
- Below the diagonal: com.jpablodrexler.photomanager.infrastructure.web.mapper uses a module listed above it, which is the healthy direction.
34→6 JPPhotoManager.Application uses JPPhotoManager.Domain.Interfaces.Services✕
- Connections
- 10 pairs of types, where a type in JPPhotoManager.Application uses a type in JPPhotoManager.Domain.Interfaces.Services.
- The types involved
JPPhotoManager.Application.Application→JPPhotoManager.Domain.Interfaces.Services.IBatchRenameServiceJPPhotoManager.Application.Application→JPPhotoManager.Domain.Interfaces.Services.ICatalogAssetsServiceJPPhotoManager.Application.Application→JPPhotoManager.Domain.Interfaces.Services.IConvertAssetsServiceJPPhotoManager.Application.Application→JPPhotoManager.Domain.Interfaces.Services.IFindDuplicatedAssetsServiceJPPhotoManager.Application.Application→JPPhotoManager.Domain.Interfaces.Services.IMoveAssetsServiceJPPhotoManager.Application.Application→JPPhotoManager.Domain.Interfaces.Services.INewReleaseNotificationServiceJPPhotoManager.Application.Application→JPPhotoManager.Domain.Interfaces.Services.IProcessServiceJPPhotoManager.Application.Application→JPPhotoManager.Domain.Interfaces.Services.IStorageServiceJPPhotoManager.Application.Application→JPPhotoManager.Domain.Interfaces.Services.ISyncAssetsServiceJPPhotoManager.Application.Application→JPPhotoManager.Domain.Interfaces.Services.IUserConfigurationService
- Direction
- JPPhotoManager.Application uses JPPhotoManager.Domain.Interfaces.Services, so a change to JPPhotoManager.Domain.Interfaces.Services can break JPPhotoManager.Application, while a change to JPPhotoManager.Application can't break JPPhotoManager.Domain.Interfaces.Services.
- Position
- Below the diagonal: JPPhotoManager.Application uses a module listed above it, which is the healthy direction.
34→12 JPPhotoManager.Application uses JPPhotoManager.Domain.Entities✕
- Connections
- 8 pairs of types, where a type in JPPhotoManager.Application uses a type in JPPhotoManager.Domain.Entities.
- The types involved
JPPhotoManager.Application.Application→JPPhotoManager.Domain.Entities.AssetJPPhotoManager.Application.Application→JPPhotoManager.Domain.Entities.ConvertAssetsConfigurationJPPhotoManager.Application.Application→JPPhotoManager.Domain.Entities.FolderJPPhotoManager.Application.Application→JPPhotoManager.Domain.Entities.SyncAssetsConfigurationJPPhotoManager.Application.IApplication→JPPhotoManager.Domain.Entities.AssetJPPhotoManager.Application.IApplication→JPPhotoManager.Domain.Entities.ConvertAssetsConfigurationJPPhotoManager.Application.IApplication→JPPhotoManager.Domain.Entities.FolderJPPhotoManager.Application.IApplication→JPPhotoManager.Domain.Entities.SyncAssetsConfiguration
- Direction
- JPPhotoManager.Application uses JPPhotoManager.Domain.Entities, so a change to JPPhotoManager.Domain.Entities can break JPPhotoManager.Application, while a change to JPPhotoManager.Application can't break JPPhotoManager.Domain.Entities.
- Position
- Below the diagonal: JPPhotoManager.Application uses a module listed above it, which is the healthy direction.
34→19 JPPhotoManager.Application uses JPPhotoManager.Domain✕
- Connections
- 17 pairs of types, where a type in JPPhotoManager.Application uses a type in JPPhotoManager.Domain.
- The types involved
JPPhotoManager.Application.Application→JPPhotoManager.Domain.AboutInformationJPPhotoManager.Application.Application→JPPhotoManager.Domain.BatchRenameResultJPPhotoManager.Application.Application→JPPhotoManager.Domain.CatalogChangeCallbackJPPhotoManager.Application.Application→JPPhotoManager.Domain.ConvertAssetsResultJPPhotoManager.Application.Application→JPPhotoManager.Domain.PaginatedDataJPPhotoManager.Application.Application→JPPhotoManager.Domain.ProcessStatusChangedCallbackJPPhotoManager.Application.Application→JPPhotoManager.Domain.ReleaseJPPhotoManager.Application.Application→JPPhotoManager.Domain.SyncAssetsResultJPPhotoManager.Application.Application→JPPhotoManager.Domain.WallpaperStyleJPPhotoManager.Application.IApplication→JPPhotoManager.Domain.AboutInformationJPPhotoManager.Application.IApplication→JPPhotoManager.Domain.CatalogChangeCallbackJPPhotoManager.Application.IApplication→JPPhotoManager.Domain.ConvertAssetsResultJPPhotoManager.Application.IApplication→JPPhotoManager.Domain.PaginatedDataJPPhotoManager.Application.IApplication→JPPhotoManager.Domain.ProcessStatusChangedCallbackJPPhotoManager.Application.IApplication→JPPhotoManager.Domain.ReleaseJPPhotoManager.Application.IApplication→JPPhotoManager.Domain.SyncAssetsResultJPPhotoManager.Application.IApplication→JPPhotoManager.Domain.WallpaperStyle
- Direction
- JPPhotoManager.Application uses JPPhotoManager.Domain, so a change to JPPhotoManager.Domain can break JPPhotoManager.Application, while a change to JPPhotoManager.Application can't break JPPhotoManager.Domain.
- Position
- Below the diagonal: JPPhotoManager.Application uses a module listed above it, which is the healthy direction.
34→28 JPPhotoManager.Application uses JPPhotoManager.Domain.Interfaces.Repositories✕
- Connections
- 5 pairs of types, where a type in JPPhotoManager.Application uses a type in JPPhotoManager.Domain.Interfaces.Repositories.
- The types involved
JPPhotoManager.Application.Application→JPPhotoManager.Domain.Interfaces.Repositories.IAssetRepositoryJPPhotoManager.Application.Application→JPPhotoManager.Domain.Interfaces.Repositories.IConvertAssetsConfigurationRepositoryJPPhotoManager.Application.Application→JPPhotoManager.Domain.Interfaces.Repositories.IFolderRepositoryJPPhotoManager.Application.Application→JPPhotoManager.Domain.Interfaces.Repositories.IRecentTargetPathRepositoryJPPhotoManager.Application.Application→JPPhotoManager.Domain.Interfaces.Repositories.ISyncAssetsConfigurationRepository
- Direction
- JPPhotoManager.Application uses JPPhotoManager.Domain.Interfaces.Repositories, so a change to JPPhotoManager.Domain.Interfaces.Repositories can break JPPhotoManager.Application, while a change to JPPhotoManager.Application can't break JPPhotoManager.Domain.Interfaces.Repositories.
- Position
- Below the diagonal: JPPhotoManager.Application uses a module listed above it, which is the healthy direction.
35→6 JPPhotoManager.Domain.Services uses JPPhotoManager.Domain.Interfaces.Services✕
- Connections
- 25 pairs of types, where a type in JPPhotoManager.Domain.Services uses a type in JPPhotoManager.Domain.Interfaces.Services.
- The types involved
JPPhotoManager.Domain.Services.BatchRenameService→JPPhotoManager.Domain.Interfaces.Services.IBatchRenameServiceJPPhotoManager.Domain.Services.BatchRenameService→JPPhotoManager.Domain.Interfaces.Services.IStorageServiceJPPhotoManager.Domain.Services.CatalogAssetsService→JPPhotoManager.Domain.Interfaces.Services.IAssetHashCalculatorServiceJPPhotoManager.Domain.Services.CatalogAssetsService→JPPhotoManager.Domain.Interfaces.Services.ICatalogAssetsServiceJPPhotoManager.Domain.Services.CatalogAssetsService→JPPhotoManager.Domain.Interfaces.Services.IDirectoryComparerJPPhotoManager.Domain.Services.CatalogAssetsService→JPPhotoManager.Domain.Interfaces.Services.IStorageServiceJPPhotoManager.Domain.Services.CatalogAssetsService→JPPhotoManager.Domain.Interfaces.Services.IUserConfigurationServiceJPPhotoManager.Domain.Services.ConvertAssetsService→JPPhotoManager.Domain.Interfaces.Services.IConvertAssetsServiceJPPhotoManager.Domain.Services.ConvertAssetsService→JPPhotoManager.Domain.Interfaces.Services.IDirectoryComparerJPPhotoManager.Domain.Services.ConvertAssetsService→JPPhotoManager.Domain.Interfaces.Services.IStorageServiceJPPhotoManager.Domain.Services.ConvertAssetsService→JPPhotoManager.Domain.Interfaces.Services.IUniqueFileNameProviderServiceJPPhotoManager.Domain.Services.DirectoryComparer→JPPhotoManager.Domain.Interfaces.Services.IDirectoryComparerJPPhotoManager.Domain.Services.DirectoryComparer→JPPhotoManager.Domain.Interfaces.Services.IStorageServiceJPPhotoManager.Domain.Services.FindDuplicatedAssetsService→JPPhotoManager.Domain.Interfaces.Services.IFindDuplicatedAssetsServiceJPPhotoManager.Domain.Services.FindDuplicatedAssetsService→JPPhotoManager.Domain.Interfaces.Services.IStorageServiceJPPhotoManager.Domain.Services.MoveAssetsService→JPPhotoManager.Domain.Interfaces.Services.IMoveAssetsServiceJPPhotoManager.Domain.Services.MoveAssetsService→JPPhotoManager.Domain.Interfaces.Services.IStorageServiceJPPhotoManager.Domain.Services.NewReleaseNotificationService→JPPhotoManager.Domain.Interfaces.Services.INewReleaseNotificationServiceJPPhotoManager.Domain.Services.NewReleaseNotificationService→JPPhotoManager.Domain.Interfaces.Services.IReleaseAvailabilityServiceJPPhotoManager.Domain.Services.NewReleaseNotificationService→JPPhotoManager.Domain.Interfaces.Services.IUserConfigurationServiceJPPhotoManager.Domain.Services.SyncAssetsService→JPPhotoManager.Domain.Interfaces.Services.IDirectoryComparerJPPhotoManager.Domain.Services.SyncAssetsService→JPPhotoManager.Domain.Interfaces.Services.IStorageServiceJPPhotoManager.Domain.Services.SyncAssetsService→JPPhotoManager.Domain.Interfaces.Services.ISyncAssetsServiceJPPhotoManager.Domain.Services.UniqueFileNameProviderService→JPPhotoManager.Domain.Interfaces.Services.IStorageServiceJPPhotoManager.Domain.Services.UniqueFileNameProviderService→JPPhotoManager.Domain.Interfaces.Services.IUniqueFileNameProviderService
- Direction
- JPPhotoManager.Domain.Services uses JPPhotoManager.Domain.Interfaces.Services, so a change to JPPhotoManager.Domain.Interfaces.Services can break JPPhotoManager.Domain.Services, while a change to JPPhotoManager.Domain.Services can't break JPPhotoManager.Domain.Interfaces.Services.
- Position
- Below the diagonal: JPPhotoManager.Domain.Services uses a module listed above it, which is the healthy direction.
35→12 JPPhotoManager.Domain.Services uses JPPhotoManager.Domain.Entities✕
- Connections
- 7 pairs of types, where a type in JPPhotoManager.Domain.Services uses a type in JPPhotoManager.Domain.Entities.
- The types involved
JPPhotoManager.Domain.Services.BatchRenameService→JPPhotoManager.Domain.Entities.AssetJPPhotoManager.Domain.Services.CatalogAssetsService→JPPhotoManager.Domain.Entities.AssetJPPhotoManager.Domain.Services.CatalogAssetsService→JPPhotoManager.Domain.Entities.FolderJPPhotoManager.Domain.Services.DirectoryComparer→JPPhotoManager.Domain.Entities.AssetJPPhotoManager.Domain.Services.FindDuplicatedAssetsService→JPPhotoManager.Domain.Entities.AssetJPPhotoManager.Domain.Services.MoveAssetsService→JPPhotoManager.Domain.Entities.AssetJPPhotoManager.Domain.Services.MoveAssetsService→JPPhotoManager.Domain.Entities.Folder
- Direction
- JPPhotoManager.Domain.Services uses JPPhotoManager.Domain.Entities, so a change to JPPhotoManager.Domain.Entities can break JPPhotoManager.Domain.Services, while a change to JPPhotoManager.Domain.Services can't break JPPhotoManager.Domain.Entities.
- Position
- Below the diagonal: JPPhotoManager.Domain.Services uses a module listed above it, which is the healthy direction.
35→19 JPPhotoManager.Domain.Services uses JPPhotoManager.Domain✕
- Connections
- 7 pairs of types, where a type in JPPhotoManager.Domain.Services uses a type in JPPhotoManager.Domain.
- The types involved
JPPhotoManager.Domain.Services.BatchRenameService→JPPhotoManager.Domain.BatchRenameResultJPPhotoManager.Domain.Services.CatalogAssetsService→JPPhotoManager.Domain.CatalogChangeCallbackJPPhotoManager.Domain.Services.ConvertAssetsService→JPPhotoManager.Domain.ConvertAssetsResultJPPhotoManager.Domain.Services.ConvertAssetsService→JPPhotoManager.Domain.ProcessStatusChangedCallbackJPPhotoManager.Domain.Services.NewReleaseNotificationService→JPPhotoManager.Domain.ReleaseJPPhotoManager.Domain.Services.SyncAssetsService→JPPhotoManager.Domain.ProcessStatusChangedCallbackJPPhotoManager.Domain.Services.SyncAssetsService→JPPhotoManager.Domain.SyncAssetsResult
- Direction
- JPPhotoManager.Domain.Services uses JPPhotoManager.Domain, so a change to JPPhotoManager.Domain can break JPPhotoManager.Domain.Services, while a change to JPPhotoManager.Domain.Services can't break JPPhotoManager.Domain.
- Position
- Below the diagonal: JPPhotoManager.Domain.Services uses a module listed above it, which is the healthy direction.
35→28 JPPhotoManager.Domain.Services uses JPPhotoManager.Domain.Interfaces.Repositories✕
- Connections
- 10 pairs of types, where a type in JPPhotoManager.Domain.Services uses a type in JPPhotoManager.Domain.Interfaces.Repositories.
- The types involved
JPPhotoManager.Domain.Services.CatalogAssetsService→JPPhotoManager.Domain.Interfaces.Repositories.IAssetRepositoryJPPhotoManager.Domain.Services.CatalogAssetsService→JPPhotoManager.Domain.Interfaces.Repositories.IFolderRepositoryJPPhotoManager.Domain.Services.ConvertAssetsService→JPPhotoManager.Domain.Interfaces.Repositories.IAssetRepositoryJPPhotoManager.Domain.Services.ConvertAssetsService→JPPhotoManager.Domain.Interfaces.Repositories.IConvertAssetsConfigurationRepositoryJPPhotoManager.Domain.Services.FindDuplicatedAssetsService→JPPhotoManager.Domain.Interfaces.Repositories.IAssetRepositoryJPPhotoManager.Domain.Services.MoveAssetsService→JPPhotoManager.Domain.Interfaces.Repositories.IAssetRepositoryJPPhotoManager.Domain.Services.MoveAssetsService→JPPhotoManager.Domain.Interfaces.Repositories.IFolderRepositoryJPPhotoManager.Domain.Services.MoveAssetsService→JPPhotoManager.Domain.Interfaces.Repositories.IRecentTargetPathRepositoryJPPhotoManager.Domain.Services.SyncAssetsService→JPPhotoManager.Domain.Interfaces.Repositories.IAssetRepositoryJPPhotoManager.Domain.Services.SyncAssetsService→JPPhotoManager.Domain.Interfaces.Repositories.ISyncAssetsConfigurationRepository
- Direction
- JPPhotoManager.Domain.Services uses JPPhotoManager.Domain.Interfaces.Repositories, so a change to JPPhotoManager.Domain.Interfaces.Repositories can break JPPhotoManager.Domain.Services, while a change to JPPhotoManager.Domain.Services can't break JPPhotoManager.Domain.Interfaces.Repositories.
- Position
- Below the diagonal: JPPhotoManager.Domain.Services uses a module listed above it, which is the healthy direction.
36→6 JPPhotoManager.Infrastructure.Repositories uses JPPhotoManager.Domain.Interfaces.Services✕
- Connections
- 2 pairs of types, where a type in JPPhotoManager.Infrastructure.Repositories uses a type in JPPhotoManager.Domain.Interfaces.Services.
- The types involved
JPPhotoManager.Infrastructure.Repositories.AssetRepository→JPPhotoManager.Domain.Interfaces.Services.IStorageServiceJPPhotoManager.Infrastructure.Repositories.AssetRepository→JPPhotoManager.Domain.Interfaces.Services.IUserConfigurationService
- Direction
- JPPhotoManager.Infrastructure.Repositories uses JPPhotoManager.Domain.Interfaces.Services, so a change to JPPhotoManager.Domain.Interfaces.Services can break JPPhotoManager.Infrastructure.Repositories, while a change to JPPhotoManager.Infrastructure.Repositories can't break JPPhotoManager.Domain.Interfaces.Services.
- Position
- Below the diagonal: JPPhotoManager.Infrastructure.Repositories uses a module listed above it, which is the healthy direction.
36→12 JPPhotoManager.Infrastructure.Repositories uses JPPhotoManager.Domain.Entities✕
- Connections
- 5 pairs of types, where a type in JPPhotoManager.Infrastructure.Repositories uses a type in JPPhotoManager.Domain.Entities.
- The types involved
JPPhotoManager.Infrastructure.Repositories.AssetRepository→JPPhotoManager.Domain.Entities.AssetJPPhotoManager.Infrastructure.Repositories.AssetRepository→JPPhotoManager.Domain.Entities.FolderJPPhotoManager.Infrastructure.Repositories.ConvertAssetsConfigurationRepository→JPPhotoManager.Domain.Entities.ConvertAssetsConfigurationJPPhotoManager.Infrastructure.Repositories.FolderRepository→JPPhotoManager.Domain.Entities.FolderJPPhotoManager.Infrastructure.Repositories.SyncAssetsConfigurationRepository→JPPhotoManager.Domain.Entities.SyncAssetsConfiguration
- Direction
- JPPhotoManager.Infrastructure.Repositories uses JPPhotoManager.Domain.Entities, so a change to JPPhotoManager.Domain.Entities can break JPPhotoManager.Infrastructure.Repositories, while a change to JPPhotoManager.Infrastructure.Repositories can't break JPPhotoManager.Domain.Entities.
- Position
- Below the diagonal: JPPhotoManager.Infrastructure.Repositories uses a module listed above it, which is the healthy direction.
36→19 JPPhotoManager.Infrastructure.Repositories uses JPPhotoManager.Domain✕
- Connections
- 1 pair of types, where a type in JPPhotoManager.Infrastructure.Repositories uses a type in JPPhotoManager.Domain.
- The types involved
JPPhotoManager.Infrastructure.Repositories.AssetRepository→JPPhotoManager.Domain.PaginatedData
- Direction
- JPPhotoManager.Infrastructure.Repositories uses JPPhotoManager.Domain, so a change to JPPhotoManager.Domain can break JPPhotoManager.Infrastructure.Repositories, while a change to JPPhotoManager.Infrastructure.Repositories can't break JPPhotoManager.Domain.
- Position
- Below the diagonal: JPPhotoManager.Infrastructure.Repositories uses a module listed above it, which is the healthy direction.
36→28 JPPhotoManager.Infrastructure.Repositories uses JPPhotoManager.Domain.Interfaces.Repositories✕
- Connections
- 5 pairs of types, where a type in JPPhotoManager.Infrastructure.Repositories uses a type in JPPhotoManager.Domain.Interfaces.Repositories.
- The types involved
JPPhotoManager.Infrastructure.Repositories.AssetRepository→JPPhotoManager.Domain.Interfaces.Repositories.IAssetRepositoryJPPhotoManager.Infrastructure.Repositories.ConvertAssetsConfigurationRepository→JPPhotoManager.Domain.Interfaces.Repositories.IConvertAssetsConfigurationRepositoryJPPhotoManager.Infrastructure.Repositories.FolderRepository→JPPhotoManager.Domain.Interfaces.Repositories.IFolderRepositoryJPPhotoManager.Infrastructure.Repositories.RecentTargetPathRepository→JPPhotoManager.Domain.Interfaces.Repositories.IRecentTargetPathRepositoryJPPhotoManager.Infrastructure.Repositories.SyncAssetsConfigurationRepository→JPPhotoManager.Domain.Interfaces.Repositories.ISyncAssetsConfigurationRepository
- Direction
- JPPhotoManager.Infrastructure.Repositories uses JPPhotoManager.Domain.Interfaces.Repositories, so a change to JPPhotoManager.Domain.Interfaces.Repositories can break JPPhotoManager.Infrastructure.Repositories, while a change to JPPhotoManager.Infrastructure.Repositories can't break JPPhotoManager.Domain.Interfaces.Repositories.
- Position
- Below the diagonal: JPPhotoManager.Infrastructure.Repositories uses a module listed above it, which is the healthy direction.
37→5 com.jpablodrexler.photomanager.infrastructure.web.controller uses com.jpablodrexler.photomanager.domain.enums✕
- Connections
- 1 pair of types, where a type in com.jpablodrexler.photomanager.infrastructure.web.controller uses a type in com.jpablodrexler.photomanager.domain.enums.
- The types involved
com.jpablodrexler.photomanager.infrastructure.web.controller.AssetController→com.jpablodrexler.photomanager.domain.enums.SortCriteria
- Direction
- com.jpablodrexler.photomanager.infrastructure.web.controller uses com.jpablodrexler.photomanager.domain.enums, so a change to com.jpablodrexler.photomanager.domain.enums can break com.jpablodrexler.photomanager.infrastructure.web.controller, while a change to com.jpablodrexler.photomanager.infrastructure.web.controller can't break com.jpablodrexler.photomanager.domain.enums.
- Position
- Below the diagonal: com.jpablodrexler.photomanager.infrastructure.web.controller uses a module listed above it, which is the healthy direction.
37→10 com.jpablodrexler.photomanager.infrastructure.web.controller uses com.jpablodrexler.photomanager.domain.model✕
- Connections
- 1 pair of types, where a type in com.jpablodrexler.photomanager.infrastructure.web.controller uses a type in com.jpablodrexler.photomanager.domain.model.
- The types involved
com.jpablodrexler.photomanager.infrastructure.web.controller.UserPreferenceController→com.jpablodrexler.photomanager.domain.model.User
- Direction
- com.jpablodrexler.photomanager.infrastructure.web.controller uses com.jpablodrexler.photomanager.domain.model, so a change to com.jpablodrexler.photomanager.domain.model can break com.jpablodrexler.photomanager.infrastructure.web.controller, while a change to com.jpablodrexler.photomanager.infrastructure.web.controller can't break com.jpablodrexler.photomanager.domain.model.
- Position
- Below the diagonal: com.jpablodrexler.photomanager.infrastructure.web.controller uses a module listed above it, which is the healthy direction.
37→14 com.jpablodrexler.photomanager.infrastructure.web.controller uses com.jpablodrexler.photomanager.application.dto✕
- Connections
- 3 pairs of types, where a type in com.jpablodrexler.photomanager.infrastructure.web.controller uses a type in com.jpablodrexler.photomanager.application.dto.
- The types involved
com.jpablodrexler.photomanager.infrastructure.web.controller.AssetController→com.jpablodrexler.photomanager.application.dto.PaginatedDatacom.jpablodrexler.photomanager.infrastructure.web.controller.AuditLogController→com.jpablodrexler.photomanager.application.dto.PaginatedDatacom.jpablodrexler.photomanager.infrastructure.web.controller.RecycleBinController→com.jpablodrexler.photomanager.application.dto.PaginatedData
- Direction
- com.jpablodrexler.photomanager.infrastructure.web.controller uses com.jpablodrexler.photomanager.application.dto, so a change to com.jpablodrexler.photomanager.application.dto can break com.jpablodrexler.photomanager.infrastructure.web.controller, while a change to com.jpablodrexler.photomanager.infrastructure.web.controller can't break com.jpablodrexler.photomanager.application.dto.
- Position
- Below the diagonal: com.jpablodrexler.photomanager.infrastructure.web.controller uses a module listed above it, which is the healthy direction.
37→15 com.jpablodrexler.photomanager.infrastructure.web.controller uses com.jpablodrexler.photomanager.domain.port.in.catalog✕
- Connections
- 2 pairs of types, where a type in com.jpablodrexler.photomanager.infrastructure.web.controller uses a type in com.jpablodrexler.photomanager.domain.port.in.catalog.
- The types involved
com.jpablodrexler.photomanager.infrastructure.web.controller.AssetController→com.jpablodrexler.photomanager.domain.port.in.catalog.CatalogAssetsUseCasecom.jpablodrexler.photomanager.infrastructure.web.controller.AssetController→com.jpablodrexler.photomanager.domain.port.in.catalog.GetDuplicatedAssetsUseCase
- Direction
- com.jpablodrexler.photomanager.infrastructure.web.controller uses com.jpablodrexler.photomanager.domain.port.in.catalog, so a change to com.jpablodrexler.photomanager.domain.port.in.catalog can break com.jpablodrexler.photomanager.infrastructure.web.controller, while a change to com.jpablodrexler.photomanager.infrastructure.web.controller can't break com.jpablodrexler.photomanager.domain.port.in.catalog.
- Position
- Below the diagonal: com.jpablodrexler.photomanager.infrastructure.web.controller uses a module listed above it, which is the healthy direction.
37→16 com.jpablodrexler.photomanager.infrastructure.web.controller uses com.jpablodrexler.photomanager.domain.port.in.folder✕
- Connections
- 5 pairs of types, where a type in com.jpablodrexler.photomanager.infrastructure.web.controller uses a type in com.jpablodrexler.photomanager.domain.port.in.folder.
- The types involved
com.jpablodrexler.photomanager.infrastructure.web.controller.AssetController→com.jpablodrexler.photomanager.domain.port.in.folder.GetFolderIdByPathUseCasecom.jpablodrexler.photomanager.infrastructure.web.controller.FolderController→com.jpablodrexler.photomanager.domain.port.in.folder.GetDrivesUseCasecom.jpablodrexler.photomanager.infrastructure.web.controller.FolderController→com.jpablodrexler.photomanager.domain.port.in.folder.GetInitialFolderUseCasecom.jpablodrexler.photomanager.infrastructure.web.controller.FolderController→com.jpablodrexler.photomanager.domain.port.in.folder.GetRecentTargetPathsUseCasecom.jpablodrexler.photomanager.infrastructure.web.controller.FolderController→com.jpablodrexler.photomanager.domain.port.in.folder.GetSubFoldersUseCase
- Direction
- com.jpablodrexler.photomanager.infrastructure.web.controller uses com.jpablodrexler.photomanager.domain.port.in.folder, so a change to com.jpablodrexler.photomanager.domain.port.in.folder can break com.jpablodrexler.photomanager.infrastructure.web.controller, while a change to com.jpablodrexler.photomanager.infrastructure.web.controller can't break com.jpablodrexler.photomanager.domain.port.in.folder.
- Position
- Below the diagonal: com.jpablodrexler.photomanager.infrastructure.web.controller uses a module listed above it, which is the healthy direction.
37→26 com.jpablodrexler.photomanager.infrastructure.web.controller uses com.jpablodrexler.photomanager.infrastructure.service✕
- Connections
- 3 pairs of types, where a type in com.jpablodrexler.photomanager.infrastructure.web.controller uses a type in com.jpablodrexler.photomanager.infrastructure.service.
- The types involved
com.jpablodrexler.photomanager.infrastructure.web.controller.AssetController→com.jpablodrexler.photomanager.infrastructure.service.KafkaProgressRegistrycom.jpablodrexler.photomanager.infrastructure.web.controller.ConvertController→com.jpablodrexler.photomanager.infrastructure.service.KafkaProgressRegistrycom.jpablodrexler.photomanager.infrastructure.web.controller.SyncController→com.jpablodrexler.photomanager.infrastructure.service.KafkaProgressRegistry
- Direction
- com.jpablodrexler.photomanager.infrastructure.web.controller uses com.jpablodrexler.photomanager.infrastructure.service, so a change to com.jpablodrexler.photomanager.infrastructure.service can break com.jpablodrexler.photomanager.infrastructure.web.controller, while a change to com.jpablodrexler.photomanager.infrastructure.web.controller can't break com.jpablodrexler.photomanager.infrastructure.service.
- Position
- Below the diagonal: com.jpablodrexler.photomanager.infrastructure.web.controller uses a module listed above it, which is the healthy direction.
37→27 com.jpablodrexler.photomanager.infrastructure.web.controller uses com.jpablodrexler.photomanager.infrastructure.web.dto.response✕
- Connections
- 18 pairs of types, where a type in com.jpablodrexler.photomanager.infrastructure.web.controller uses a type in com.jpablodrexler.photomanager.infrastructure.web.dto.response.
- The types involved
com.jpablodrexler.photomanager.infrastructure.web.controller.AlbumController→com.jpablodrexler.photomanager.infrastructure.web.dto.response.AlbumResponseDtocom.jpablodrexler.photomanager.infrastructure.web.controller.AlbumController→com.jpablodrexler.photomanager.infrastructure.web.dto.response.AlbumSummaryResponseDtocom.jpablodrexler.photomanager.infrastructure.web.controller.AnalyticsController→com.jpablodrexler.photomanager.infrastructure.web.dto.response.AnalyticsResponseDtocom.jpablodrexler.photomanager.infrastructure.web.controller.AssetController→com.jpablodrexler.photomanager.infrastructure.web.dto.response.AssetResponseDtocom.jpablodrexler.photomanager.infrastructure.web.controller.AssetController→com.jpablodrexler.photomanager.infrastructure.web.dto.response.ExifMetadataResponseDtocom.jpablodrexler.photomanager.infrastructure.web.controller.AssetController→com.jpablodrexler.photomanager.infrastructure.web.dto.response.RenameAssetsResponseDtocom.jpablodrexler.photomanager.infrastructure.web.controller.AssetController→com.jpablodrexler.photomanager.infrastructure.web.dto.response.TimelineGroupResponseDtocom.jpablodrexler.photomanager.infrastructure.web.controller.AssetController→com.jpablodrexler.photomanager.infrastructure.web.dto.response.UploadAssetResponseDtocom.jpablodrexler.photomanager.infrastructure.web.controller.AuditLogController→com.jpablodrexler.photomanager.infrastructure.web.dto.response.AuditLogEntryResponseDtocom.jpablodrexler.photomanager.infrastructure.web.controller.AuthController→com.jpablodrexler.photomanager.infrastructure.web.dto.response.LoginResponseDtocom.jpablodrexler.photomanager.infrastructure.web.controller.AuthController→com.jpablodrexler.photomanager.infrastructure.web.dto.response.MeResponseDtocom.jpablodrexler.photomanager.infrastructure.web.controller.AuthController→com.jpablodrexler.photomanager.infrastructure.web.dto.response.SessionResponseDtocom.jpablodrexler.photomanager.infrastructure.web.controller.FolderController→com.jpablodrexler.photomanager.infrastructure.web.dto.response.FolderResponseDtocom.jpablodrexler.photomanager.infrastructure.web.controller.HomeController→com.jpablodrexler.photomanager.infrastructure.web.dto.response.HomeStatsResponseDtocom.jpablodrexler.photomanager.infrastructure.web.controller.MediaController→com.jpablodrexler.photomanager.infrastructure.web.dto.response.AssetResponseDtocom.jpablodrexler.photomanager.infrastructure.web.controller.RecycleBinController→com.jpablodrexler.photomanager.infrastructure.web.dto.response.AssetResponseDtocom.jpablodrexler.photomanager.infrastructure.web.controller.SearchPresetController→com.jpablodrexler.photomanager.infrastructure.web.dto.response.SearchPresetResponseDtocom.jpablodrexler.photomanager.infrastructure.web.controller.UserAdminController→com.jpablodrexler.photomanager.infrastructure.web.dto.response.UserSummaryResponseDto
- Direction
- com.jpablodrexler.photomanager.infrastructure.web.controller uses com.jpablodrexler.photomanager.infrastructure.web.dto.response, so a change to com.jpablodrexler.photomanager.infrastructure.web.dto.response can break com.jpablodrexler.photomanager.infrastructure.web.controller, while a change to com.jpablodrexler.photomanager.infrastructure.web.controller can't break com.jpablodrexler.photomanager.infrastructure.web.dto.response.
- Position
- Below the diagonal: com.jpablodrexler.photomanager.infrastructure.web.controller uses a module listed above it, which is the healthy direction.
37→33 com.jpablodrexler.photomanager.infrastructure.web.controller uses com.jpablodrexler.photomanager.infrastructure.web.mapper✕
- Connections
- 15 pairs of types, where a type in com.jpablodrexler.photomanager.infrastructure.web.controller uses a type in com.jpablodrexler.photomanager.infrastructure.web.mapper.
- The types involved
com.jpablodrexler.photomanager.infrastructure.web.controller.AlbumController→com.jpablodrexler.photomanager.infrastructure.web.mapper.AlbumFilterJsonConvertercom.jpablodrexler.photomanager.infrastructure.web.controller.AlbumController→com.jpablodrexler.photomanager.infrastructure.web.mapper.AlbumWebMappercom.jpablodrexler.photomanager.infrastructure.web.controller.AlbumController→com.jpablodrexler.photomanager.infrastructure.web.mapper.AssetWebMappercom.jpablodrexler.photomanager.infrastructure.web.controller.AnalyticsController→com.jpablodrexler.photomanager.infrastructure.web.mapper.AnalyticsWebMappercom.jpablodrexler.photomanager.infrastructure.web.controller.AssetController→com.jpablodrexler.photomanager.infrastructure.web.mapper.AssetWebMappercom.jpablodrexler.photomanager.infrastructure.web.controller.AuditLogController→com.jpablodrexler.photomanager.infrastructure.web.mapper.AuditLogWebMappercom.jpablodrexler.photomanager.infrastructure.web.controller.AuthController→com.jpablodrexler.photomanager.infrastructure.web.mapper.SessionWebMappercom.jpablodrexler.photomanager.infrastructure.web.controller.ConvertController→com.jpablodrexler.photomanager.infrastructure.web.mapper.ConvertWebMappercom.jpablodrexler.photomanager.infrastructure.web.controller.FolderController→com.jpablodrexler.photomanager.infrastructure.web.mapper.FolderWebMappercom.jpablodrexler.photomanager.infrastructure.web.controller.HomeController→com.jpablodrexler.photomanager.infrastructure.web.mapper.HomeWebMappercom.jpablodrexler.photomanager.infrastructure.web.controller.MediaController→com.jpablodrexler.photomanager.infrastructure.web.mapper.AssetWebMappercom.jpablodrexler.photomanager.infrastructure.web.controller.RecycleBinController→com.jpablodrexler.photomanager.infrastructure.web.mapper.AssetWebMappercom.jpablodrexler.photomanager.infrastructure.web.controller.SearchPresetController→com.jpablodrexler.photomanager.infrastructure.web.mapper.SearchPresetWebMappercom.jpablodrexler.photomanager.infrastructure.web.controller.SyncController→com.jpablodrexler.photomanager.infrastructure.web.mapper.SyncWebMappercom.jpablodrexler.photomanager.infrastructure.web.controller.UserAdminController→com.jpablodrexler.photomanager.infrastructure.web.mapper.UserAdminWebMapper
- Direction
- com.jpablodrexler.photomanager.infrastructure.web.controller uses com.jpablodrexler.photomanager.infrastructure.web.mapper, so a change to com.jpablodrexler.photomanager.infrastructure.web.mapper can break com.jpablodrexler.photomanager.infrastructure.web.controller, while a change to com.jpablodrexler.photomanager.infrastructure.web.controller can't break com.jpablodrexler.photomanager.infrastructure.web.mapper.
- Position
- Below the diagonal: com.jpablodrexler.photomanager.infrastructure.web.controller uses a module listed above it, which is the healthy direction.
38→12 JPPhotoManager.UI.ViewModels uses JPPhotoManager.Domain.Entities✕
- Connections
- 12 pairs of types, where a type in JPPhotoManager.UI.ViewModels uses a type in JPPhotoManager.Domain.Entities.
- The types involved
JPPhotoManager.UI.ViewModels.ApplicationViewModel→JPPhotoManager.Domain.Entities.AssetJPPhotoManager.UI.ViewModels.ApplicationViewModel→JPPhotoManager.Domain.Entities.FolderJPPhotoManager.UI.ViewModels.ConvertAssetsViewModel→JPPhotoManager.Domain.Entities.ConvertAssetsConfigurationJPPhotoManager.UI.ViewModels.ConvertAssetsViewModel→JPPhotoManager.Domain.Entities.ConvertAssetsDirectoriesDefinitionJPPhotoManager.UI.ViewModels.DuplicatedAssetViewModel→JPPhotoManager.Domain.Entities.AssetJPPhotoManager.UI.ViewModels.FindDuplicatedAssetsViewModel→JPPhotoManager.Domain.Entities.AssetJPPhotoManager.UI.ViewModels.FolderAddedEventArgs→JPPhotoManager.Domain.Entities.FolderJPPhotoManager.UI.ViewModels.FolderNavigationViewModel→JPPhotoManager.Domain.Entities.FolderJPPhotoManager.UI.ViewModels.FolderRemovedEventArgs→JPPhotoManager.Domain.Entities.FolderJPPhotoManager.UI.ViewModels.FolderViewModel→JPPhotoManager.Domain.Entities.FolderJPPhotoManager.UI.ViewModels.SyncAssetsViewModel→JPPhotoManager.Domain.Entities.SyncAssetsConfigurationJPPhotoManager.UI.ViewModels.SyncAssetsViewModel→JPPhotoManager.Domain.Entities.SyncAssetsDirectoriesDefinition
- Direction
- JPPhotoManager.UI.ViewModels uses JPPhotoManager.Domain.Entities, so a change to JPPhotoManager.Domain.Entities can break JPPhotoManager.UI.ViewModels, while a change to JPPhotoManager.UI.ViewModels can't break JPPhotoManager.Domain.Entities.
- Position
- Below the diagonal: JPPhotoManager.UI.ViewModels uses a module listed above it, which is the healthy direction.
38→19 JPPhotoManager.UI.ViewModels uses JPPhotoManager.Domain✕
- Connections
- 10 pairs of types, where a type in JPPhotoManager.UI.ViewModels uses a type in JPPhotoManager.Domain.
- The types involved
JPPhotoManager.UI.ViewModels.ApplicationViewModel→JPPhotoManager.Domain.AppModeEnumJPPhotoManager.UI.ViewModels.ApplicationViewModel→JPPhotoManager.Domain.CatalogChangeCallbackJPPhotoManager.UI.ViewModels.ApplicationViewModel→JPPhotoManager.Domain.CatalogChangeCallbackEventArgsJPPhotoManager.UI.ViewModels.ApplicationViewModel→JPPhotoManager.Domain.PaginatedDataJPPhotoManager.UI.ViewModels.ApplicationViewModel→JPPhotoManager.Domain.SortCriteriaEnumJPPhotoManager.UI.ViewModels.BaseProcessViewModel→JPPhotoManager.Domain.ProcessStatusChangedCallbackJPPhotoManager.UI.ViewModels.BaseProcessViewModel→JPPhotoManager.Domain.ProcessStatusChangedCallbackEventArgsJPPhotoManager.UI.ViewModels.BaseProcessViewModel→JPPhotoManager.Domain.ProcessStepEnumJPPhotoManager.UI.ViewModels.ConvertAssetsViewModel→JPPhotoManager.Domain.ProcessStatusChangedCallbackJPPhotoManager.UI.ViewModels.SyncAssetsViewModel→JPPhotoManager.Domain.ProcessStatusChangedCallback
- Direction
- JPPhotoManager.UI.ViewModels uses JPPhotoManager.Domain, so a change to JPPhotoManager.Domain can break JPPhotoManager.UI.ViewModels, while a change to JPPhotoManager.UI.ViewModels can't break JPPhotoManager.Domain.
- Position
- Below the diagonal: JPPhotoManager.UI.ViewModels uses a module listed above it, which is the healthy direction.
38→34 JPPhotoManager.UI.ViewModels uses JPPhotoManager.Application✕
- Connections
- 9 pairs of types, where a type in JPPhotoManager.UI.ViewModels uses a type in JPPhotoManager.Application.
- The types involved
JPPhotoManager.UI.ViewModels.ApplicationViewModel→JPPhotoManager.Application.IApplicationJPPhotoManager.UI.ViewModels.BaseProcessViewModel→JPPhotoManager.Application.IApplicationJPPhotoManager.UI.ViewModels.BaseViewModel→JPPhotoManager.Application.IApplicationJPPhotoManager.UI.ViewModels.ConvertAssetsViewModel→JPPhotoManager.Application.IApplicationJPPhotoManager.UI.ViewModels.DuplicatedAssetViewModel→JPPhotoManager.Application.IApplicationJPPhotoManager.UI.ViewModels.FindDuplicatedAssetsViewModel→JPPhotoManager.Application.IApplicationJPPhotoManager.UI.ViewModels.FolderNavigationViewModel→JPPhotoManager.Application.IApplicationJPPhotoManager.UI.ViewModels.FolderViewModel→JPPhotoManager.Application.IApplicationJPPhotoManager.UI.ViewModels.SyncAssetsViewModel→JPPhotoManager.Application.IApplication
- Direction
- JPPhotoManager.UI.ViewModels uses JPPhotoManager.Application, so a change to JPPhotoManager.Application can break JPPhotoManager.UI.ViewModels, while a change to JPPhotoManager.UI.ViewModels can't break JPPhotoManager.Application.
- Position
- Below the diagonal: JPPhotoManager.UI.ViewModels uses a module listed above it, which is the healthy direction.
39→12 JPPhotoManager.UI.Windows uses JPPhotoManager.Domain.Entities✕
- Connections
- 3 pairs of types, where a type in JPPhotoManager.UI.Windows uses a type in JPPhotoManager.Domain.Entities.
- The types involved
JPPhotoManager.UI.Windows.ConvertAssetsWindow→JPPhotoManager.Domain.Entities.ConvertAssetsDirectoriesDefinitionJPPhotoManager.UI.Windows.SyncAssetsWindow→JPPhotoManager.Domain.Entities.SyncAssetsDirectoriesDefinitionJPPhotoManager.UI.Windows.ThumbnailSelectedEventArgs→JPPhotoManager.Domain.Entities.Asset
- Direction
- JPPhotoManager.UI.Windows uses JPPhotoManager.Domain.Entities, so a change to JPPhotoManager.Domain.Entities can break JPPhotoManager.UI.Windows, while a change to JPPhotoManager.UI.Windows can't break JPPhotoManager.Domain.Entities.
- Position
- Below the diagonal: JPPhotoManager.UI.Windows uses a module listed above it, which is the healthy direction.
39→19 JPPhotoManager.UI.Windows uses JPPhotoManager.Domain✕
- Connections
- 1 pair of types, where a type in JPPhotoManager.UI.Windows uses a type in JPPhotoManager.Domain.
- The types involved
JPPhotoManager.UI.Windows.AboutWindow→JPPhotoManager.Domain.AboutInformation
- Direction
- JPPhotoManager.UI.Windows uses JPPhotoManager.Domain, so a change to JPPhotoManager.Domain can break JPPhotoManager.UI.Windows, while a change to JPPhotoManager.UI.Windows can't break JPPhotoManager.Domain.
- Position
- Below the diagonal: JPPhotoManager.UI.Windows uses a module listed above it, which is the healthy direction.
39→34 JPPhotoManager.UI.Windows uses JPPhotoManager.Application✕
- Connections
- 1 pair of types, where a type in JPPhotoManager.UI.Windows uses a type in JPPhotoManager.Application.
- The types involved
JPPhotoManager.UI.Windows.MainWindow→JPPhotoManager.Application.IApplication
- Direction
- JPPhotoManager.UI.Windows uses JPPhotoManager.Application, so a change to JPPhotoManager.Application can break JPPhotoManager.UI.Windows, while a change to JPPhotoManager.UI.Windows can't break JPPhotoManager.Application.
- Position
- Below the diagonal: JPPhotoManager.UI.Windows uses a module listed above it, which is the healthy direction.
39→38 JPPhotoManager.UI.Windows uses JPPhotoManager.UI.ViewModels✕
- Connections
- 5 pairs of types, where a type in JPPhotoManager.UI.Windows uses a type in JPPhotoManager.UI.ViewModels.
- The types involved
JPPhotoManager.UI.Windows.ConvertAssetsWindow→JPPhotoManager.UI.ViewModels.ConvertAssetsViewModelJPPhotoManager.UI.Windows.DuplicatedAssetsWindow→JPPhotoManager.UI.ViewModels.FindDuplicatedAssetsViewModelJPPhotoManager.UI.Windows.FolderNavigationWindow→JPPhotoManager.UI.ViewModels.FolderNavigationViewModelJPPhotoManager.UI.Windows.MainWindow→JPPhotoManager.UI.ViewModels.ApplicationViewModelJPPhotoManager.UI.Windows.SyncAssetsWindow→JPPhotoManager.UI.ViewModels.SyncAssetsViewModel
- Direction
- JPPhotoManager.UI.Windows uses JPPhotoManager.UI.ViewModels, so a change to JPPhotoManager.UI.ViewModels can break JPPhotoManager.UI.Windows, while a change to JPPhotoManager.UI.Windows can't break JPPhotoManager.UI.ViewModels.
- Position
- Below the diagonal: JPPhotoManager.UI.Windows uses a module listed above it, which is the healthy direction.
39→40 JPPhotoManager.UI.Windows uses JPPhotoManager.UI.Controls part of a loop✕
- Connections
- 4 pairs of types, where a type in JPPhotoManager.UI.Windows uses a type in JPPhotoManager.UI.Controls.
- The types involved
JPPhotoManager.UI.Windows.FolderNavigationWindow→JPPhotoManager.UI.Controls.FolderNavigationControlJPPhotoManager.UI.Windows.MainWindow→JPPhotoManager.UI.Controls.FolderNavigationControlJPPhotoManager.UI.Windows.MainWindow→JPPhotoManager.UI.Controls.ThumbnailsUserControlJPPhotoManager.UI.Windows.MainWindow→JPPhotoManager.UI.Controls.ViewerUserControl
- Direction
- JPPhotoManager.UI.Windows uses JPPhotoManager.UI.Controls, so a change to JPPhotoManager.UI.Controls can break JPPhotoManager.UI.Windows, while a change to JPPhotoManager.UI.Windows can't break JPPhotoManager.UI.Controls.
- Position
- Above the diagonal, so it is part of a loop. Neither module can be changed, tested or released on its own until one of these dependencies is removed.
40→12 JPPhotoManager.UI.Controls uses JPPhotoManager.Domain.Entities✕
- Connections
- 2 pairs of types, where a type in JPPhotoManager.UI.Controls uses a type in JPPhotoManager.Domain.Entities.
- The types involved
JPPhotoManager.UI.Controls.FolderNavigationControl→JPPhotoManager.Domain.Entities.FolderJPPhotoManager.UI.Controls.ThumbnailsUserControl→JPPhotoManager.Domain.Entities.Asset
- Direction
- JPPhotoManager.UI.Controls uses JPPhotoManager.Domain.Entities, so a change to JPPhotoManager.Domain.Entities can break JPPhotoManager.UI.Controls, while a change to JPPhotoManager.UI.Controls can't break JPPhotoManager.Domain.Entities.
- Position
- Below the diagonal: JPPhotoManager.UI.Controls uses a module listed above it, which is the healthy direction.
40→19 JPPhotoManager.UI.Controls uses JPPhotoManager.Domain✕
- Connections
- 1 pair of types, where a type in JPPhotoManager.UI.Controls uses a type in JPPhotoManager.Domain.
- The types involved
JPPhotoManager.UI.Controls.ThumbnailsUserControl→JPPhotoManager.Domain.PaginatedData
- Direction
- JPPhotoManager.UI.Controls uses JPPhotoManager.Domain, so a change to JPPhotoManager.Domain can break JPPhotoManager.UI.Controls, while a change to JPPhotoManager.UI.Controls can't break JPPhotoManager.Domain.
- Position
- Below the diagonal: JPPhotoManager.UI.Controls uses a module listed above it, which is the healthy direction.
40→34 JPPhotoManager.UI.Controls uses JPPhotoManager.Application✕
- Connections
- 1 pair of types, where a type in JPPhotoManager.UI.Controls uses a type in JPPhotoManager.Application.
- The types involved
JPPhotoManager.UI.Controls.ThumbnailsUserControl→JPPhotoManager.Application.IApplication
- Direction
- JPPhotoManager.UI.Controls uses JPPhotoManager.Application, so a change to JPPhotoManager.Application can break JPPhotoManager.UI.Controls, while a change to JPPhotoManager.UI.Controls can't break JPPhotoManager.Application.
- Position
- Below the diagonal: JPPhotoManager.UI.Controls uses a module listed above it, which is the healthy direction.
40→38 JPPhotoManager.UI.Controls uses JPPhotoManager.UI.ViewModels✕
- Connections
- 5 pairs of types, where a type in JPPhotoManager.UI.Controls uses a type in JPPhotoManager.UI.ViewModels.
- The types involved
JPPhotoManager.UI.Controls.FolderNavigationControl→JPPhotoManager.UI.ViewModels.ApplicationViewModelJPPhotoManager.UI.Controls.FolderNavigationControl→JPPhotoManager.UI.ViewModels.FolderAddedEventArgsJPPhotoManager.UI.Controls.FolderNavigationControl→JPPhotoManager.UI.ViewModels.FolderRemovedEventArgsJPPhotoManager.UI.Controls.ThumbnailsUserControl→JPPhotoManager.UI.ViewModels.ApplicationViewModelJPPhotoManager.UI.Controls.ViewerUserControl→JPPhotoManager.UI.ViewModels.ApplicationViewModel
- Direction
- JPPhotoManager.UI.Controls uses JPPhotoManager.UI.ViewModels, so a change to JPPhotoManager.UI.ViewModels can break JPPhotoManager.UI.Controls, while a change to JPPhotoManager.UI.Controls can't break JPPhotoManager.UI.ViewModels.
- Position
- Below the diagonal: JPPhotoManager.UI.Controls uses a module listed above it, which is the healthy direction.
40→39 JPPhotoManager.UI.Controls uses JPPhotoManager.UI.Windows✕
- Connections
- 2 pairs of types, where a type in JPPhotoManager.UI.Controls uses a type in JPPhotoManager.UI.Windows.
- The types involved
JPPhotoManager.UI.Controls.ThumbnailsUserControl→JPPhotoManager.UI.Windows.ThumbnailSelectedEventHandlerJPPhotoManager.UI.Controls.ViewerUserControl→JPPhotoManager.UI.Windows.ThumbnailSelectedEventHandler
- Direction
- JPPhotoManager.UI.Controls uses JPPhotoManager.UI.Windows, so a change to JPPhotoManager.UI.Windows can break JPPhotoManager.UI.Controls, while a change to JPPhotoManager.UI.Controls can't break JPPhotoManager.UI.Windows.
- Position
- Below the diagonal: JPPhotoManager.UI.Controls uses a module listed above it, which is the healthy direction.
At a glance — Code Health
At a glance — Architecture
At a glance — Maturity
At a glance — Readiness
At a glance — Security
At a glance — Domain Modelling
At a glance — Performance
Security & Compliance — OWASP Top-10 mapping
| OWASP category | Findings | Severity |
|---|---|---|
| A02:2025 — Security Misconfiguration | 244 | High / Critical |
| A03:2025 — Software Supply Chain Failures | 42 | High / Critical |
| A05:2025 — Injection | 37 | High / Critical |
| A07:2025 — Authentication Failures | 2 | High / Critical |
Roadmap
First, reconcile the README to accurately reflect existing scripts and remove references to missing files. Next, address the 191 medium-severity IaC findings in backend, frontend, and grafana configurations, while simultaneously resolving the lack of Architecture Decision Records by documenting key design choices. Finally, improve latency hygiene by replacing synchronous APIs with their asynchronous counterparts in TypeScript and JavaScript code.
| Do this | Helps | Effort | Dimension |
|---|---|---|---|
| Resolve the 1 No ADRs found finding(s) in ADR Quality. | +4.5 pts | Low | ADR Quality |
| Reconcile the README with reality: JPPhotoManagerWeb/README.md runs `bash scripts/complexity-report.sh`, but `scripts/complexity-report.sh` does not exist; JPPhotoManagerWeb/README.md runs `bash scripts/dead-code-report.sh`, but `scripts/dead-code-report.sh` does not exist; JPPhotoManagerWeb/README.md runs `bash scripts/auth-coverage-report.sh`, but `scripts/auth-coverage-report.sh` does not exist; JPPhotoManagerWeb/README.md runs `bash scripts/coverage-report.sh`, but `scripts/coverage-report.sh` does not exist; JPPhotoManagerWeb/README.md runs `bash scripts/mutation-report.sh`, but `scripts/mutation-report.sh` does not exist. | +4.5 pts | Medium | Documentation accuracy |
| Record your significant design decisions. Write one short document per decision, giving its date, the situation, the decision and its consequences, and keep them together with your other design documents. A docs/adr folder with each file named by number and title is the easiest place to find them. | +3.1 pts | Medium | Architecture documentation |
| Resolve the 4 REDACTED finding(s) in Supply-chain Provenance & Signing — start with REDACTED, REDACTED, REDACTED. | +1.3 pts | Low | Supply-chain Provenance & Signing |
| Resolve the 1 No network policy finding(s) in Network Egress Confinement. | +1.2 pts | Low | Network Egress Confinement |
| Resolve the 8 No seccomp profile finding(s) in Kernel & Syscall Confinement — start with REDACTED, REDACTED, REDACTED. | +1.2 pts | Low | Kernel & Syscall Confinement |
| TypeScript/JavaScript: use the promise APIs (fs/promises, a promisified child_process.execFile, the async zlib/crypto functions) and await them instead of the *Sync variants. | +1.8 pts | Medium | Async & latency hygiene |
| Resolve the 5 WriteOnlyPrivateField finding(s) in Explicit Debt — start with ConvertAssetsService.cs (2), CatalogAssetsService.cs, SyncAssetsService.cs. | +0.7 pts | Low | Explicit Debt |
File quality
| File | Score | Band | Worst signal |
|---|---|---|---|
| REDACTED | 0.2 | Slop | Secrets (history): High secret: REDACTED |
| REDACTED | 0.9 | Slop | Static Analysis (SAST): High: REDACTED |
| REDACTED | 1.6 | Slop | IaC & Container Security: High IaC: REDACTED |
| REDACTED | 1.6 | Slop | IaC & Container Security: High IaC: REDACTED |
| REDACTED | 1.6 | Slop | IaC & Container Security: High IaC: REDACTED |
| REDACTED | 1.6 | Slop | IaC & Container Security: High IaC: REDACTED |
| REDACTED | 1.6 | Slop | IaC & Container Security: High IaC: REDACTED |
| REDACTED | 1.6 | Slop | IaC & Container Security: High IaC: REDACTED |
| REDACTED | 1.6 | Slop | IaC & Container Security: High IaC: REDACTED |
| REDACTED | 1.6 | Slop | IaC & Container Security: High IaC: REDACTED |
| REDACTED | 1.9 | Slop | IaC & Container Security: High IaC: REDACTED |
| REDACTED | 2.3 | Slop | Static Analysis (SAST): High: REDACTED |
| JPPhotoManager/JPPhotoManager.Domain/Services/ConvertAssetsService.cs | 2.4 | Slop | Explicit Debt: WriteOnlyPrivateField |
| REDACTED | 2.5 | Slop | Static Analysis (SAST): High: REDACTED |
| REDACTED | 3.4 | Slop | IaC & Container Security: High IaC: REDACTED |
| JPPhotoManager/JPPhotoManager.Domain/Services/CatalogAssetsService.cs | 3.4 | Slop | Explicit Debt: WriteOnlyPrivateField |
| REDACTED | 3.7 | Slop | Static Analysis (SAST): High: REDACTED |
| JPPhotoManager/JPPhotoManager.Domain/Services/SyncAssetsService.cs | 4.3 | Mixed | Explicit Debt: WriteOnlyPrivateField |
| JPPhotoManager/JPPhotoManager.UI/ViewModels/FindDuplicatedAssetsViewModel.cs | 4.9 | Mixed | Explicit Debt: WriteOnlyPrivateField |
| JPPhotoManager/JPPhotoManager.Domain/Services/MoveAssetsService.cs | 6.0 | Mixed | Explicit Debt: TodoComment |
How the grades work
A definite problem that already costs you something and drags the score down: a missing authorisation check, a dependency with a known exploit, a build that does not reproduce. Failure here tends to cause failures elsewhere.
Likely wrong, but not failing yet. It degrades the codebase over a longer horizon and can cause failures elsewhere — not urgent this week, not something to carry for two years either.
Recorded, with no effect on how the codebase functions. Present so the survey is complete, not because it needs doing.
Something this survey could not settle from the outside, and which could be critical or serious. Either a control was required and no positive evidence of it exists in the repository — a backup job that nothing shows was ever restored from proves nothing about restores — or our own analysis could not run over that part of the tree. This is not a clean result. These are excluded from the score rather than awarded a pass, so the number on the cover neither rewards nor penalises them: if you act on this survey without resolving them, you carry that risk yourself. Each one is named under Limitations.
Methodology & how to trust this report
Watchdog is a deep, periodic assessment — run each sprint, monthly, or quarterly, taking the time to go wider and deeper than a quick check and surfacing in one coherent report what you'd otherwise piece together from a dozen separate tools. It scores deterministically: the same commit yields the same score, every run. 88 of 92 evaluated dimensions are computed purely by tools and static analysis (confidence 1.0); 4 documentation/naming judgement(s) are LLM-assisted and labelled advisory. Overall confidence is 0.8 — the weighted average across measured dimensions; it falls as more of the score leans on LLM-assisted judgement and rises when it's fully tool-backed.
What we checked — 92 dimensions across the health lenses
- Can you open the finding? Real findings cite a repo-relative file and line you can open at the cited line — never an absolute scratch path. Here, 598 of 614 do; the remainder are repo-wide signals — a dimension-level measurement, not a single line.
- Is there a tool behind the number? Every score below names the method that produced it — Roslyn, git, a scanner, or (for a handful of documentation/naming dimensions) an LLM labelled sampled · advisory — not a narrative.
- Does re-running give the same result? Run it again on the same commit and the score — and this report, byte for byte — is identical. A report whose numbers move between runs is describing the run, not the code.
Tools & methods
| Method | Backs | Version | Evaluator |
|---|---|---|---|
| Roslyn static analysis | Complexity, cohesion, coupling, dead code, API surface, layering | 5.3.0 | ✓ deterministic |
| Native secret scanner | Hardcoded secrets / credentials | 1.0.0 | ✓ deterministic |
| Watchdog duplication detector (in-process) | Code duplication | 1.0.0 | ✓ deterministic |
| Coverage (coverlet / dotnet-coverage) | Line & branch coverage | 10.0.400 | ✓ deterministic |
| NuGet / dotnet | Outdated, vulnerable & deprecated dependencies | 10.0.400 | ✓ deterministic |
| git / LibGit2Sharp | Churn hotspots, knowledge concentration, history | 2.43.0 · 0.31.0 | ✓ deterministic |
| gitleaks · semgrep · trivy · checkov | Secrets in history, SAST, CVEs, IaC & container, PII / GDPR | 1.86.0 · 0.69.3 · 3.2.533 | ✓ deterministic |
| LLM (sampled · advisory) | Documentation quality, ADR conformance, naming — sampled over a bounded sample; advisory, never a deterministic measurement | Local LLM | ◐ LLM · sampled · advisory |
Run transparency — what happened this run
- D8 Code Coverage — not measured this run — Watchdog could not measure this here. That is a gap on our side — a collector, parser or image we have not built yet — and it is neither a defect in this repository nor evidence that the check would have passed. Coverage NOT MEASURED: the .NET half could not be measured — no coverage produced (collector absent, or test run exceeded the inline budget); the JavaScript/TypeScript half could not be measured — the JavaScript/TypeScript suite(s) run through a browser-driven runner the coverage collector does not drive — JPPhotoManagerWeb/frontend/ (cypress) — a gap in the analyzer, not something this repository is missing. This repository's production source spans both ecosystems, and no partial figure is published as if it were the whole: coverage is excluded from the score rather than counted as a near-zero. This is OUR limitation, not a defect in the repo. In the meantime, commit (or publish into the working tree) the lcov/Cobertura report your CI produces and the real number is read on the next scan. You can widen what we reach: optional: commit the lcov/Cobertura report your CI produces, and the real number is read on the next scan.
- D10 Test Quality — measured, with a gap in what it reached — Watchdog measured this, but not all of it. What it did not reach is a gap on our side — a collector, parser or image we have not built yet — so the numbers on that dimension cover less than the repository, and the part left out is not evidence that it would have passed. The 175 test(s) behind this row are the ones the C# collector could read, and this repository also carries at least 247 test source file(s) (.java, .ts) that it cannot: it parses C# syntax and matches C# test attributes, so a vitest/jest/JUnit/pytest-style suite is invisible to it. Skipped tests, zero-assertion tests and the other quality signals on this row are UNMEASURED in that suite — their absence from the counts above is a gap in this analyzer's language coverage, not a finding that those tests are sound.
- D11 Test Reliability — not measured this run — Watchdog could not measure this here. That is a gap on our side — a collector, parser or image we have not built yet — and it is neither a defect in this repository nor evidence that the check would have passed. Test reliability NOT MEASURED: this repository's test suite spans .NET and JavaScript/TypeScript, and the JavaScript/TypeScript half could not be re-run — unit: measured (0 flaky); JavaScript/TypeScript (cypress component specs (e2e specs need the repository's own dev server and were not re-run; run in the analyzer image's Cypress, not the declared version) via `npm ci --ignore-scripts` in JPPhotoManagerWeb/frontend/): not included — the cypress run in JPPhotoManagerWeb/frontend/ produced no per-test report (TSError: ⨯ Unable to compile TypeScript:). No partial figure is published as if it were the whole: reliability is excluded from the score rather than counted as a near-zero.
- D11 Test Reliability — not measured this run — Watchdog could not measure this here. That is a gap on our side — a collector, parser or image we have not built yet — and it is neither a defect in this repository nor evidence that the check would have passed. Test reliability for the cypress suite in JPPhotoManagerWeb/frontend/ was NOT MEASURED: the cypress run in JPPhotoManagerWeb/frontend/ produced no per-test report (TSError: ⨯ Unable to compile TypeScript:). This is OUR limitation, not a defect in the repository, and the suite is excluded from the measurement rather than counted against it.
- D12 Dependency Hygiene — not measured this run — Watchdog could not measure this here. That is a gap on our side — a collector, parser or image we have not built yet — and it is neither a defect in this repository nor evidence that the check would have passed. `dotnet list package` did not return usable output (restore or query failed); no outdated/vulnerable/deprecated data to assess. The tool said: `dotnet list package` exited 1 with no output.
- D17 Explicit Debt — measured, with a gap in what it reached — Watchdog measured this, but not all of it. What it did not reach is a gap on our side — a collector, parser or image we have not built yet — so the numbers on that dimension cover less than the repository, and the part left out is not evidence that it would have passed. The 34 deducted marker(s) and the 1.6/KLoC density on this row were taken over this repository's .NET projects ALONE: .java (11,953 lines, 53% of production source), .ts (4,699 lines, 21% of production source) went unread, because every marker collector on this path is reached through a C# workspace. D17's marker collectors need a compiler we do not have for that language, so none of its nine marker kinds were read there. The debt in that source is UNMEASURED — its absence from the score above is a gap in this analyzer's language coverage, not a finding that the code carries none.
- D22 Internal API Consistency — not measured this run — This is a true statement about the repository that carries nothing for its owner to act on, so it is reported here rather than as a defect in their code. The loaded project set declares no packable project and no `.Contracts` project, so there is no intentionally-exposed surface for API consistency to be judged over.
- D23 Boundary Type-Coupling — not measured this run — Watchdog could not measure this here. That is a gap on our side — a collector, parser or image we have not built yet — and it is neither a defect in this repository nor evidence that the check would have passed. Large codebase (22,593 production LoC in the .NET projects) with no declared bounded contexts — cross-boundary type coupling is unassessed Bounded contexts cannot be inferred from a codebase that is not physically organised by them (D-321), so with none declared there are no boundaries for the coupling pass to measure across. You can widen what we reach: name this codebase's bounded contexts (≥2 module groups, e.g. per subsystem) so cross-boundary type coupling can be assessed. Declare them in `.codehealth/config.yaml` at the repository root (create it if absent), mapping each context name to the module-path or namespace prefixes that belong to it — e.g. `architecture:` → `contexts:` → `Billing: ["src/billing", "Acme.Billing"]`, `Catalog: ["src/catalog", "Acme.Catalog"]`.
- D27 Navigability — not measured this run — Watchdog could not measure this here. That is a gap on our side — a collector, parser or image we have not built yet — and it is neither a defect in this repository nor evidence that the check would have passed. Navigability is taken over call sites whose callee resolved. For C# that population includes calls into referenced assemblies; for this language only calls declared inside the repository count, so the abstention threshold reads the repository's use of its standard library as a resolution failure. That is a limit of this analyzer, not a build problem in this repository.
- D28 Secrets (history) — measured, with a gap in what it reached — Watchdog measured this, but not all of it. What it did not reach is a gap on our side — a collector, parser or image we have not built yet — so the numbers on that dimension cover less than the repository, and the part left out is not evidence that it would have passed. D28's config-credential rule (WD-SECRET-0002) parses each committed `.json` config as a document and reads credential-named values; `JPPhotoManager/JPPhotoManager.UI/appsettings.json` did not parse (JSON5, a template, several concatenated documents), so a credential bound there is UNMEASURED by that rule. gitleaks still scanned the same files as text.
- D30 Dependency Vulnerabilities — measured, with a gap in what it reached — This is a true statement about the repository that carries nothing for its owner to act on, so it is reported here rather than as a defect in their code. The solution did not restore on the analyzer's .NET SDK (an SDK/target-framework/restore mismatch, common for an older codebase), so there was no restored dependency graph to scan. 2 of 3 declared ecosystem(s) (npm,osv) WERE scanned and every vulnerability they reported is included in this result; nuget was not, so this dimension's score covers less than the dependency surface this repository declares, and nothing here is evidence that nuget is free of known-vulnerable dependencies.
- D34 Knowledge Freshness — not measured this run — Watchdog could not measure this here. That is a gap on our side — a collector, parser or image we have not built yet — and it is neither a defect in this repository nor evidence that the check would have passed. File-level freshness contradicts repo activity: 31 commits in the last 90 days, yet 26 of 26 significant files carry no living knowledge. Those two readings cannot both be true, so the per-file recency signal is treated as unreliable here and freshness is not scored for this run.
- D39 IL Efficiency — not measured this run — Watchdog could not measure this here. That is a gap on our side — a collector, parser or image we have not built yet — and it is neither a defect in this repository nor evidence that the check would have passed. IL NOT MEASURED: the analyzer's own build of this repository failed for an ENVIRONMENT reason (exit 1) — MSBuild's engine or the CLR gave up, or our image does not carry the SDK band/targeting pack this repository needs. This is OUR limitation, not a defect in the repo, and it is not a statement that this repository fails to build. D18 owns the question of whether this repository builds; it was not answered here.
- AXR1 Runtime accessibility — not measured this run — Watchdog could not measure this here. That is a gap on our side — a collector, parser or image we have not built yet — and it is neither a defect in this repository nor evidence that the check would have passed. Render strategy: boot via DockerCompose (REDACTED). compose up failed (exit 15 — the compose project is invalid) — error while interpolating services.backend.environment.JWT_SECRET: required variable JWT_SECRET is missing a value: Set JWT_SECRET in .env - run: openssl rand -base64 32; runtime evidence skipped.
- ED5 Idempotency — not measured this run — Watchdog could not measure this here. That is a gap on our side — a collector, parser or image we have not built yet — and it is neither a defect in this repository nor evidence that the check would have passed. This check decides whether a handler's mutation is safe to re-run by recognising its persistence writes (a database save, a repository write, an event publish) and its guards. Those markers are .NET member names, so in this repository's language a write such as `repository.save(order)` is not recognised and a same-named call on an unrelated library type could be. The handlers were found; their idempotency was neither confirmed nor ruled out.
- M3 Folder & project structure — measured, with a gap in what it reached — Watchdog measured this, but not all of it. What it did not reach is a gap on our side — a collector, parser or image we have not built yet — so the numbers on that dimension cover less than the repository, and the part left out is not evidence that it would have passed. Whether the tests sit apart from production code is not visible here, because the suite is not in a form this pass reads. The test-separation credit is granted rather than withheld: this is a gap in the analyzer's language coverage, not a finding about the repository's tests. You can widen what we reach: keep the test surface somewhere a reader can find it without opening a binary — an exported/checked-in test source tree beside the production code makes the suite reviewable, diffable and discoverable by tooling.
Limitations & what we did not check
Watchdog assesses the repository exactly as committed, and only the repository. By design it does not reach outside the source tree: the live cloud account, the running CI/CD pipeline, the host's branch-protection and approval rules, the production configuration, or a restore actually exercised against a backup are all out of scope. That boundary is a feature, not a gap — a repo-relative, deterministic scan re-runs identically on any commit and every finding opens at a real file and line, where a live audit can neither be reproduced nor traced. The visible consequence is that controls which leave no in-repo evidence are reported as "not evidenced" and excluded from the score rather than awarded a number a static scan cannot justify.
Per-dimension blind spots
- D1 Cyclomatic Complexity: Cyclomatic complexity counts branches statically — it cannot tell an essential decision tree from accidental tangle, nor see complexity that lives in data or configuration (large switch-case token tables, DSL lexers/parsers, data-as-code rule tables) rather than control flow: a tokenizer's many single-character cases read as high complexity though each branch is trivial.
- D2 Cognitive Complexity: Cognitive-complexity heuristics approximate how hard code is to follow; genuine domain difficulty and well-named intent that eases reading are not captured.
- D3 God Classes: "God class" is sized by members and responsibilities visible in the type — a deliberately broad facade over a coherent subsystem can read the same as an accidental grab-bag. For front-end JS the file-length check is cohesion-aware (a single-responsibility module — one class/IIFE — earns a 3× threshold), but cohesion is approximated from top-level declarations, not true dependency structure.
- D4 Code Duplication: Duplication is token-similarity — an in-process token-stream comparison over sliding windows, with type-aware normalization — so it finds copy-paste, not semantic duplication expressed differently. Committed machine-written code (scaffolded migrations, designer/codegen output, protobuf/OpenAPI stubs, model snapshots) is EXCLUDED — its repetition is the tool's, not the team's — so the score reflects hand-written duplication only.
- D5 Coupling: Coupling is measured between projects/assemblies — runtime coupling through DI, reflection, messaging or shared databases is invisible to a static reference graph.
- D6 Cohesion (LCOM4): LCOM4 cohesion is syntactic — it infers connectivity from which methods touch which fields/methods by name, not from real runtime behaviour or intent.
- D9 Test Distribution: The test-pyramid shape is inferred from project/folder naming and references, with a single test host bucketed per-file by its path tier and content signals — a suite that names tiers unconventionally and gives no per-file signal can still be mis-bucketed.
- D10 Test Quality: Assertion density is structural — it cannot tell a meaningful behavioural assertion from a trivial one, only that an assertion is present.
- D13 Secret Scanning: Secret detection is signature- and entropy-based on the current tree — a secret that does not match a known pattern, or one already rotated, will not be flagged (a clean scan is "nothing matched", not "no secrets exist").
- D14 License Compliance: License compatibility is checked against declared package metadata and a policy — mislabelled or missing license metadata, and obligations that depend on how you distribute, are not resolved here.
- D15 Churn × Complexity Hotspots: Churn hotspots come from git history — a freshly imported or squashed repository has no churn signal, and recent rewrites can mask a historically risky file.
- D17 Explicit Debt: Acknowledged-debt signals (TODO/FIXME, suppressions, dead code) are textual — undocumented debt that nobody marked, and debt that lives in design rather than annotations, is invisible. Committed machine-written code (scaffolded migrations, designer/codegen output, generated stubs) is excluded — it is never the team's dead code to delete.
- D19 Documentation Quality: Documentation quality is judged by an LLM over a bounded sample of docs — it reads what is written, not whether the docs match the running system, and it is advisory, not a measurement. Its critique rows are drawn from a closed category vocabulary and each row means the same thing in every run, so two scans can be compared row by row; the SET that fires is still a sample, and does not repeat exactly. Measured on one frozen input, six scans at one engine SHA: 2-5 critique rows per scan, 8 distinct rows across the six, 3 of those 8 seen in only one scan. So a D19 row is evidence about the documentation, but a COUNT of D19 rows is not a quantity — never read a change in it as an improvement or a regression.
- D20 ADR Quality: ADR quality is an LLM read of the decision records present — it cannot know about decisions made and never recorded, and its verdict is sampled and advisory.
- D21 Naming Consistency: Naming quality is an LLM judgement over a bounded sample — it assesses clarity/consistency of the names it sees, not domain-correctness, and is advisory.
- D24 Comment Value: Comment value (WHY vs WHAT) is an LLM judgement over a bounded sample — it is advisory and cannot weigh a comment against the precise code change it was written to explain.
- D26 Project Cohesion: Project focus is sized from members/namespaces per project — a project that is broad by deliberate design reads the same as one that has sprawled.
- D28 Secrets (history): Secret-history scanning sweeps the git log for known patterns — a secret that predates the available history, or never matched a signature, is not found (clean means "nothing matched in the history we can see").
- D29 Static Analysis (SAST): SAST findings are pattern-based (semgrep) — it finds classes of bug it has rules for; logic flaws, auth/authorization gaps and issues needing runtime context are out of reach (and clean means "no rule matched").
- D30 Dependency Vulnerabilities: CVE matching depends on accurate package/version metadata and on the advisory databases — a vulnerability with no published advisory, or in code not declared as a dependency, is not seen. Coverage needs a RESOLVED graph: an unpinned requirements.txt, or a pom without a resolved build, yields partial coverage rather than a clean verdict. An ecosystem the analyzer cannot scan is reported as unmeasured, never as clean.
- D31 IaC & Container Security: IaC scanning checks Dockerfiles/Terraform/Kubernetes against best-practice rules — it cannot see the live cloud account, runtime configuration, or drift between the committed config and what is actually deployed.
- D35 Change Coupling: Change coupling is co-change in COMMITS — files split across separate commits, or coupled only through a shared config/build step, read as uncoupled, and a sweeping commit (rename/format) is excluded so it doesn't couple everything. It shows that files change together, not WHY: a high coupling can be a healthy cohesive pair as readily as a hidden leak.
- D40 Network Egress Confinement: Egress confinement is read from committed Kubernetes manifests — a policy applied out-of-band (cluster-default deny, a service mesh, or a cloud firewall/security group off-repo) is invisible, and a present NetworkPolicy is declared config, not proof the cluster admission-controller actually enforces it at runtime.
- D41 Kernel & Syscall Confinement: Syscall/MAC confinement is read from committed manifests — a profile applied by a cluster-wide PodSecurity default or a mutating webhook off-repo isn't seen, and a declared seccomp/AppArmor profile is config presence, not proof the node's kernel actually loaded and enforced it.
- D43 Malicious Dependencies: Only packages some vulnerability database has already NAMED as malicious are seen — a compromise published in the last hours, or never reported at all, is invisible here, and this dimension reading 10 is not evidence that a dependency is trustworthy. There is no typosquat or dependency-confusion analysis: a package nobody has reported is simply absent from the feeds. Coverage is the dependency scan's: an ecosystem that could not be scanned is disclosed as unmeasured, never as clean.
- D44 Platform End-of-Life: The support table is FROZEN, so it goes out of date by losing RECALL: a release that ended support after the table was written is missed until the table is refreshed, and this dimension reading 10 is not evidence that a platform is current. Only platforms the repository DECLARES in a place this pass reads are seen — a runtime named only in a REDACTED (D31's subject), in a CI workflow (D29's), or in a file this pass does not parse (go.mod, a Gemfile ruby directive) is invisible here, which is why a repository declaring none of them abstains rather than scoring. Only frameworks with a PUBLISHED support policy are tracked: React, Flask and Express publish none, so their age cannot be judged and their absence from a report is not a statement that they are supported.
- AX10 Code composition: Role is inferred from namespace/folder convention, not semantics — a domain concept living in a folder named "Services" reads as application, and the split is lines-of-code, not business value. The business-logic-share score is a SOFT, FLOORED signal: it contributes to the Architecture lens but is floored at the Critical gate, so an infrastructure-heavy design (a gateway, an ETL, a driver) is legitimately low without being nuked to zero.
- DM6 Domain ↔ infrastructure boundary: Infrastructure reached through a hand-rolled wrapper, a domain-named facade, reflection, or a string-keyed service locator resolves to a non-infra type and isn't seen; the body scan is symbol resolution over syntax, not full dataflow. A clean result means "no resolved infra reference in a domain body", not a proof of purity.
- M4 Documentation accuracy: Onboarding quality is an LLM read of the docs/setup present — it cannot run the onboarding or measure how long a real new joiner takes; the verdict is sampled and advisory.
- P4 Deployment & Rollback: Approval/branch-protection rules live in repository settings the scan cannot see — only their in-repo evidence (config files, workflows) is checked, so a control enforced purely in the host's settings reads as "not evidenced".
- P5 DR & Backup: Backup/restore and disaster-recovery readiness is judged from in-repo evidence — a config that exists is not a tested restore, so the absence of positive evidence is reported as "not evidenced", never scored as present.
- P6 Release Hygiene: Rollback/observability controls are inferred from repo artefacts (pipelines, dashboards-as-code) — controls configured in external tooling, with no in-repo trace, cannot be credited.
The LLM boundary
Dimensions
D1 · Cyclomatic Complexity
5 method(s) exceeded the cyclomatic complexity threshold of 15; the worst was StorageServiceAdapter.getExifMetadata at 32. A further 2 method(s) were over the threshold but excluded as flat dispatchers (a long switch/match over independent cases: many branches, almost no nesting), the largest being Asset.IdentifySupportedTags at 35 — they are counted neither in the figure above nor in this dimension's score. 2 files carry no cyclomatic complexity row at all for this reason — every one of their over-threshold methods was excluded, so the exclusion is disclosed nowhere in the file itself: JPPhotoManager/JPPhotoManager.Domain/Entities/Asset.cs (Asset.IdentifySupportedTags at 35), JPPhotoManagerWeb/frontend/scripts/cyclomatic-complexity.js (cyclomatic-complexity.computeComplexity::visit at 16). They are named here because the per-file figures other dimensions report are taken BEFORE this exclusion, so such a file can show a high maximum complexity elsewhere in this report and nothing here, with nothing to reconcile the two.
What to do
- Bring the 5 bodies over 15 down to 15 or less in Cyclomatic Complexity — start with StorageServiceAdapter.getExifMetadata (cyclomatic 32), SocialMediaCropComponent.getHitArea (cyclomatic 21), MoveAssetsService.MoveAssets (cyclomatic 17). — This score is capped by its worst body, so a finding fixed alone moves it by almost nothing — the next one down takes its place. Refactoring these 5 together lifts Cyclomatic Complexity from 8.8 to about 10.0/10, projected with the scoring formula itself and assuming each lands exactly at 15.
- Enforce Cyclomatic Complexity in CI to reach Verified (currently Documented). — Hardens enforcement from Documented toward Prevented — provenance only; does not change the score.
D2 · Cognitive Complexity
9 method(s) exceeded the cognitive complexity threshold of 15; the worst was a11y-report.main at 34.
What to do
- Bring the 9 bodies over 15 down to 15 or less in Cognitive Complexity — start with a11y-report.main (cognitive 34), AssetRepository.GetAssets (cognitive 32), StorageServiceAdapter.getExifMetadata (cognitive 32). — This score is capped by its worst body, so a finding fixed alone moves it by almost nothing — the next one down takes its place. Refactoring these 9 together lifts Cognitive Complexity from 8.4 to about 10.0/10, projected with the scoring formula itself and assuming each lands exactly at 15.
- Enforce Cognitive Complexity in CI to reach Verified (currently Documented). — Hardens enforcement from Documented toward Prevented — provenance only; does not change the score.
D3 · God Classes
6 god class(es) detected.
What to do
- Resolve the 4 TooManyMethods finding(s) in God Classes — start with gallery.component.ts, AssetRepositoryImpl.java, MainWindow.xaml.cs. — One of this dimension's main actionable groups (4 warning-level).
- Resolve the 1 ClassTooLong finding(s) in God Classes — start with gallery.component.ts. — One of this dimension's main actionable groups (1 warning-level).
- Resolve the 1 FileTooLong finding(s) in God Classes — start with gallery.component.ts. — One of this dimension's main actionable groups (1 warning-level).
- Enforce God Classes in CI to reach Verified (currently Documented). — Hardens enforcement from Documented toward Prevented — provenance only; does not change the score.
D4 · Code Duplication
42 duplicated block group(s) detected. A further 2 rows report members as variants of one another; they aggregate block groups already counted above and are not themselves counted. Measured on part of this repository only: .ts (21% of production source) was not exposed to THIS dimension's token comparison and is not in this count; duplication there is measured by R10 Code Duplication, the frontend lens's card running the same clone algorithm over the JS/TS token stream.
What to do
- Resolve the 8 Duplicated block (9 lines × 2) finding(s) in Code Duplication — start with ConvertAssetsWindow.xaml.cs (3), GetAlbumSummaryUseCaseImpl.java, ConvertAssetsUseCaseImpl.java. — One of this dimension's main actionable groups (8 warning-level).
- Resolve the 6 Duplicated block (7 lines × 2) finding(s) in Code Duplication — start with CatalogAssetsService.cs, BulkAddTagUseCaseImpl.java, CatalogAssetItemProcessor.java. — One of this dimension's main actionable groups (6 warning-level).
- Resolve the 5 Duplicated block (5 lines × 2) finding(s) in Code Duplication — start with AuthController.java, ConvertAssetsConfiguration.cs, RevokeSessionUseCaseImpl.java. — One of this dimension's main actionable groups (5 warning-level).
- Enforce Code Duplication in CI to reach Verified (currently Documented). — Hardens enforcement from Documented toward Verified — provenance only; does not change the score.
D5 · Coupling
6 projects, 0 dependency cycle(s), 0 unstable depended-on project(s).
D6 · Cohesion (LCOM4)
3 of 82 classes have LCOM4 above 3.
What to do
- Resolve the 3 Low cohesion finding(s) in Cohesion (LCOM4) — start with StorageServiceAdapter.java, AppConfig.java, AssetController.java. — One of this dimension's main actionable groups (3 warning-level).
- Enforce Cohesion (LCOM4) in CI to reach Verified (currently Documented). — Hardens enforcement from Documented toward Verified — provenance only; does not change the score.
D9 · Test Distribution
1969 test methods: 1268 unit, 0 integration, 0 BDD, 701 e2e. The JavaScript/TypeScript suite contributes 701 `it`/`test` case(s) across 68 test file(s) declaring at least one beside 175 .NET test method(s); its tier split is read from package names and paths only. The java suite(s) contribute 1093 test method(s), read from the language model's own test census — every XCTest `test…` method on an XCTestCase, every swift-testing `@Test` and every JUnit/TestNG `@Test`-annotated method, which is those frameworks' own discovery rule. Their tier split is INFERRED from the test target's name and path only, not declared.
What to do
- Improve Test Distribution — currently 5.4/10. — 1969 test methods: 1268 unit, 0 integration, 0 BDD, 701 e2e. The JavaScript/TypeScript suite contributes 701 `it`/`test` case(s) across 68 test file(s) declaring at least one beside 175 .NET test method(s); its tier split is read from package names and paths only. The java suite(s) contribute 1093 test method(s), read from the language model's own test census — every XCTest `test…` method on an XCTestCase, every swift-testing `@Test` and every JUnit/TestNG `@Test`-annotated method, which is those frameworks' own discovery rule. Their tier split is INFERRED from the test target's name and path only, not declared.
D10 · Test Quality
1 skipped (1 with a documented reason), 0 zero-assertion, no mocking-framework packages referenced (hand-written doubles or no mocking) across 175 tests. Measured on the C# suite only — at least 247 test source file(s) (.java, .ts) went unread, so its test quality is unmeasured and is not in these counts.
D13 · Secret Scanning
Secret scan ran and found no leaked secrets.
D14 · License Compliance
0 of 213 packages use a banned license. ★ DEPTH: this repository's MSBuild projects declare 17 direct `PackageReference`(s), and 191 further package(s) were reached beyond them by closing the graph over nuget.org's own nuspec dependency graph — so a banned licence pulled in only by a dependency's OWN dependencies is inside this verdict. A package whose licence nuget.org could not be asked for is not graded, and version ranges are taken at their lower bound, so this is the closure as that graph states it rather than a restored consumer's exact resolution.
D15 · Churn × Complexity Hotspots
Top hotspots: JPPhotoManagerWeb/backend/src/main/java/com/jpablodrexler/photomanager/infrastructure/service/StorageServiceAdapter.java (8×32=256) Repeated repair below the complexity floor: JPPhotoManagerWeb/backend/src/main/java/com/jpablodrexler/photomanager/application/usecase/asset/MoveAssetsUseCaseImpl.java (3 of 5 changes were fixes); JPPhotoManagerWeb/backend/src/main/java/com/jpablodrexler/photomanager/application/usecase/recycle/PurgeAssetsUseCaseImpl.java (3 of 4 changes were fixes); JPPhotoManagerWeb/backend/src/main/java/com/jpablodrexler/photomanager/application/usecase/asset/RenameAssetsUseCaseImpl.java (3 of 3 changes were fixes)
What to do
- Resolve the 3 Repeated repair finding(s) in Churn × Complexity Hotspots — start with MoveAssetsUseCaseImpl.java, PurgeAssetsUseCaseImpl.java, RenameAssetsUseCaseImpl.java. — One of this dimension's main actionable groups (3 warning-level).
- Resolve the 1 Hotspot finding(s) in Churn × Complexity Hotspots — start with StorageServiceAdapter.java. — One of this dimension's main actionable groups (1 warning-level).
D17 · Explicit Debt
34 deducted debt markers + 4 dead symbols across 5855 LoC in the .NET projects (1.6/KLoC) → score 6.7. Measured on the .NET source only: .java, .ts (74% of production source) was not read, and carries at least 0 uncounted task marker(s) in 0 file(s).
What to do
- Resolve the 5 WriteOnlyPrivateField finding(s) in Explicit Debt — start with ConvertAssetsService.cs (2), CatalogAssetsService.cs, SyncAssetsService.cs. — One of this dimension's main actionable groups (5 issue-level).
- Resolve the 19 TodoComment finding(s) in Explicit Debt — start with FolderNavigationControl.xaml.cs (4), MoveAssetsService.cs (3), CatalogAssetsService.cs (2). — One of this dimension's main actionable groups (19 warning-level).
- Resolve the 10 CoverageExclusion finding(s) in Explicit Debt — start with App.xaml.cs, FolderNavigationControl.xaml.cs, ThumbnailsUserControl.xaml.cs. — One of this dimension's main actionable groups (10 warning-level).
- Enforce Explicit Debt in CI to reach Verified (currently Documented). — Hardens enforcement from Documented toward Prevented — provenance only; does not change the score.
D19 · Documentation Quality
The repository's documentation is comprehensive: the READMEs for each tier are well written with usage examples, the architecture/Docs markdown files cover design decisions in depth, and XML-doc coverage across [JPPhotoManager.Domain](https://github.com/JPPhotoManagerWeb/docs/blob/main/XML-doc-coverage.md) is 1/155 (0.6%). The curl reference, Docker Compose setup, frontend technologies table, Kubernetes manifests, and backlog documents all serve their purpose without gaps in the outline. This is a top-quality architecture-design documentation set: the hexagonal-architecture spec documents exactly what it promises with structural invariants (domain/purity INV-1 through port/out/INV-10), goals/non-goals, and a detailed migration plan for each phase; there are no gaps in the outline shown by the clip. The visible content is exemplary of its scope — an architecture specification — and the absence of any clipped section means none of the outlined sections are omitted. (14 of 25 sampled documents could not be assessed: 1 of 3 evaluation groups failed.)
D20 · ADR Quality
No architecture decision records were found.
What to do
- Resolve the 1 No ADRs found finding(s) in ADR Quality. — One of this dimension's main actionable groups (1 recommendation-level).
D21 · Naming Consistency
0 naming inconsistencies across 200 sampled symbols.
D24 · Comment Value
26 valuable / 0 redundant across 58 sampled comments.
D26 · Project Cohesion
0 of 6 projects flagged as possibly oversized/incoherent.
D28 · Secrets (history)
1 finding(s): 0 critical, 1 high, 0 medium, 0 low. Remediation for historically-committed secrets is credential rotation — they remain in history regardless of later deletion.
What to do
- Resolve the 1 High secret finding(s) in Secrets (history) — start with REDACTED. — One of this dimension's main actionable groups (1 issue-level).
- Resolve the 1 Rotate the exposed credentials finding(s) in Secrets (history). — One of this dimension's main actionable groups (1 recommendation-level).
D29 · Static Analysis (SAST)
37 finding(s): 0 critical, 26 high, 11 medium, 0 low. 23 unpinned-GitHub-Actions row(s) are reported here but scored by D36 (supply-chain provenance), which measures that posture as `pinned_actions` — one pinning decision is charged once, not once per lens. semgrep hit a parse error in 2 file(s) — `JPPhotoManagerWeb/backend/scripts/license-report.sh` (lines 70–73), `JPPhotoManagerWeb/scripts/port-forward-k8s.sh` (line 61) — so no absence of findings in the named regions is evidence of anything; rows reported elsewhere in those files are real. Fix the syntax error (or exclude the file deliberately) and re-scan to cover them. Separately, one or more rules could not re-parse an embedded snippet in 2 file(s) (e.g. a workflow `run:` block read as shell). Those files WERE scanned and their other rows are unaffected; only those rules' view of those snippets is missing.
What to do
- Resolve the 2 REDACTED finding(s) in Static Analysis (SAST) — start with REDACTED, REDACTED. — One of this dimension's main actionable groups (2 issue-level).
- Resolve the 1 REDACTED finding(s) in Static Analysis (SAST) — start with REDACTED. — One of this dimension's main actionable groups (1 issue-level).
- No action in Static Analysis (SAST) — all 23 REDACTED finding(s) are reported here at file:line but scored by D36 (supply-chain provenance), so none is charged to this dimension. — One of this dimension's main actionable groups (23 issue-level, 0 of them charged here).
D30 · Dependency Vulnerabilities
33 finding(s): 3 critical, 22 high, 8 medium, 0 low. Partial dependency scan: 2 of 3 declared ecosystem(s) were scanned (npm,osv), and the findings above are real and complete for them. nuget was not scanned (nuget: the solution did not restore on the analyzer's .NET SDK (an SDK/target-framework/restore mismatch, common for an older codebase), so there was no restored dependency graph to scan), so this is not the whole dependency surface and the result is reported at reduced confidence.
What to do
- Resolve the 22 High CVE finding(s) in Dependency Vulnerabilities — start with REDACTED (22). — One of this dimension's main actionable groups (22 issue-level).
- Resolve the 7 Medium CVE finding(s) in Dependency Vulnerabilities — start with REDACTED (7). — One of this dimension's main actionable groups (7 warning-level).
- Resolve the 3 Critical CVE finding(s) in Dependency Vulnerabilities — start with REDACTED (3). — One of this dimension's main actionable groups (3 issue-level).
D31 · IaC & Container Security
244 finding(s): 0 critical, 11 high, 191 medium, 42 low.
What to do
- Resolve the 191 Medium IaC finding(s) in IaC & Container Security — start with REDACTED (24), REDACTED (24), REDACTED (24). — One of this dimension's main actionable groups (191 warning-level).
- Resolve the 11 High IaC finding(s) in IaC & Container Security — start with REDACTED (2), REDACTED, REDACTED. — One of this dimension's main actionable groups (11 issue-level).
- Resolve the 42 Low IaC finding(s) in IaC & Container Security — start with REDACTED (5), REDACTED (5), REDACTED (5). — One of this dimension's main actionable groups (42 recommendation-level).
D35 · Change Coupling
Strongest change-coupling: AssetController.java↔asset.service.ts 80%
What to do
- Resolve the 1 Change coupling finding(s) in Change Coupling — start with AssetController.java. — One of this dimension's main actionable groups (1 warning-level).
D36 · Supply-chain Provenance & Signing
0/4 supply-chain integrity signals present (provenance, signing, SBOM, pinned actions).
What to do
- Resolve the 4 REDACTED finding(s) in Supply-chain Provenance & Signing — start with REDACTED, REDACTED, REDACTED. — One of this dimension's main actionable groups (4 warning-level).
- Resolve the 1 REDACTED finding(s) in Supply-chain Provenance & Signing. — One of this dimension's main actionable groups (1 warning-level).
- Resolve the 1 REDACTED finding(s) in Supply-chain Provenance & Signing. — One of this dimension's main actionable groups (1 recommendation-level).
D40 · Network Egress Confinement
0/2 network-egress controls present (network policy, egress restriction).
What to do
- Resolve the 1 No network policy finding(s) in Network Egress Confinement. — One of this dimension's main actionable groups (1 recommendation-level).
D41 · Kernel & Syscall Confinement
0/8 workload(s) run every container under a seccomp profile; 0/8 declare an AppArmor/SELinux profile.
What to do
- Resolve the 8 No seccomp profile finding(s) in Kernel & Syscall Confinement — start with REDACTED, REDACTED, REDACTED. — One of this dimension's main actionable groups (8 recommendation-level).
D43 · Malicious Dependencies
No dependency in any ecosystem this repository declares is published as malicious.
D44 · Platform End-of-Life
0 end-of-life runtime(s) and 0 end-of-life framework(s), read from 7 platform declaration(s) and 14 dependency declaration(s). This dimension reads what the repository says about ITSELF — a pinned target framework, a version file, a capped requires-python, a Rust toolchain pin, a framework major a constraint cannot move off. A FLOOR is deliberately never charged: `requires-python = ">=3.8"` states what the package SUPPORTS, not what it runs on, and a well-maintained library declares exactly that while running its own CI on a current release. The end-of-life facts are FROZEN and dated, so this dimension needs no network and answers identically inside a closed scan fence; as the table ages it loses recall and never precision, because a statement about support that ended in the past cannot become false. The OS layer of a container image is D31's question and the toolchain a CI workflow installs is D29's; this row is neither.
Frontend & cross-cutting dimensions
AX1 · Captive dependencies
- `FolderRepository` is registered as a SINGLETON but its constructor takes `AppDbContext appDbContext`, which is registered as Scoped. The singleton captures one instance of the scoped dependency forever — defeating its lifetime (a per-request DbContext shared across all requests is a classic data-corruption/threading bug). Make the singleton resolve `AppDbContext` per-use (inject `IServiceScopeFactory` or a factory func), or align the lifetimes. — JPPhotoManager/JPPhotoManager.Infrastructure/Repositories/FolderRepository.cs:11
- `AssetRepository` is registered as a SINGLETON but its constructor takes `AppDbContext appDbContext`, which is registered as Scoped. The singleton captures one instance of the scoped dependency forever — defeating its lifetime (a per-request DbContext shared across all requests is a classic data-corruption/threading bug). Make the singleton resolve `AppDbContext` per-use (inject `IServiceScopeFactory` or a factory func), or align the lifetimes. — JPPhotoManager/JPPhotoManager.Infrastructure/Repositories/AssetRepository.cs:28
- `RecentTargetPathRepository` is registered as a SINGLETON but its constructor takes `AppDbContext appDbContext`, which is registered as Scoped. The singleton captures one instance of the scoped dependency forever — defeating its lifetime (a per-request DbContext shared across all requests is a classic data-corruption/threading bug). Make the singleton resolve `AppDbContext` per-use (inject `IServiceScopeFactory` or a factory func), or align the lifetimes. — JPPhotoManager/JPPhotoManager.Infrastructure/Repositories/RecentTargetPathRepository.cs:11
- `SyncAssetsConfigurationRepository` is registered as a SINGLETON but its constructor takes `AppDbContext appDbContext`, which is registered as Scoped. The singleton captures one instance of the scoped dependency forever — defeating its lifetime (a per-request DbContext shared across all requests is a classic data-corruption/threading bug). Make the singleton resolve `AppDbContext` per-use (inject `IServiceScopeFactory` or a factory func), or align the lifetimes. — JPPhotoManager/JPPhotoManager.Infrastructure/Repositories/SyncAssetsConfigurationRepository.cs:11
- `ConvertAssetsConfigurationRepository` is registered as a SINGLETON but its constructor takes `AppDbContext appDbContext`, which is registered as Scoped. The singleton captures one instance of the scoped dependency forever — defeating its lifetime (a per-request DbContext shared across all requests is a classic data-corruption/threading bug). Make the singleton resolve `AppDbContext` per-use (inject `IServiceScopeFactory` or a factory func), or align the lifetimes. — JPPhotoManager/JPPhotoManager.Infrastructure/Repositories/ConvertAssetsConfigurationRepository.cs:11
What to do
- Don't inject scoped/transient services into singletons; resolve them per-use via IServiceScopeFactory or a factory delegate, or align the lifetimes.
AX10 · Code composition
AX2 · Stateful singletons
- `CatalogAssetsService` is a singleton (one shared instance) but mutates instance state outside any lock (_currentFolderPath; e.g. `_currentFolderPath` at line 96). — JPPhotoManager/JPPhotoManager.Domain/Services/CatalogAssetsService.cs:11
- `Application` is a singleton (one shared instance) but mutates instance state outside any lock (_recentThumbnailsQueue; e.g. `_recentThumbnailsQueue` at line 88). — JPPhotoManager/JPPhotoManager.Application/Application.cs:10
- `MainWindow` is a singleton (one shared instance) but mutates instance state outside any lock (_catalogTask; e.g. `_catalogTask` at line 483). This type is a UI view, so it is thread-CONFINED rather than locked: if every one of those mutations is reached only from the UI thread — directly, or marshalled back through the dispatcher — the confinement IS the synchronisation and there is nothing to add (do not take a lock on a view; that is how the UI thread deadlocks). Check the ones that are not: a handler for a background event that mutates before it marshals is a real race. — JPPhotoManager/JPPhotoManager.UI/Windows/MainWindow.xaml.cs:29
- `ApplicationViewModel` is a singleton (one shared instance) but mutates instance state outside any lock (_appMode, _sortCriteria, _viewerZoom, _viewerPosition, _selectedAssets, _currentFolder; e.g. `_appMode` at line 64). — JPPhotoManager/JPPhotoManager.UI/ViewModels/ApplicationViewModel.cs:27
- `CatalogAssetItemWriter` is a singleton (@Bean: the container shares one instance across every request thread) but mutates instance state outside any lock (cachedFolder; e.g. `cachedFolder` in `ensureFolderExists` at line 143). — JPPhotoManagerWeb/backend/src/main/java/com/jpablodrexler/photomanager/infrastructure/batch/CatalogAssetItemWriter.java:35
What to do
- Keep singletons stateless or back their state with thread-safe types (Concurrent*/Immutable*); otherwise concurrent callers race.
- Java/Kotlin: keep container singletons stateless — move per-request data into locals or a request-scoped bean — or back the state with java.util.concurrent types (ConcurrentHashMap, AtomicInteger/AtomicReference), guard it with synchronized / a Lock (Kotlin: withLock), or mark a flag that is only ever overwritten volatile (@Volatile).
AX3 · Project dependency cycles
- The namespaces JPPhotoManager.Domain ↔ JPPhotoManager.Domain.Entities ↔ JPPhotoManager.Domain.Interfaces.Services depend on each other. The lightest dependency in the cycle is JPPhotoManager.Domain.Entities → JPPhotoManager.Domain.Interfaces.Services (JPPhotoManager.Domain.Entities.Asset → JPPhotoManager.Domain.Interfaces.Services.IStorageService, 1 type pair(s)); cut that one first, e.g. by moving the shared type to a namespace both can use or inverting it behind an interface. — JPPhotoManager/JPPhotoManager.Domain/Entities/Asset.cs:1
- The namespaces JPPhotoManager.UI.Controls ↔ JPPhotoManager.UI.Windows depend on each other. The lightest dependency in the cycle is JPPhotoManager.UI.Controls → JPPhotoManager.UI.Windows (JPPhotoManager.UI.Controls.ThumbnailsUserControl → JPPhotoManager.UI.Windows.ThumbnailSelectedEventHandler, 2 type pair(s)); cut that one first, e.g. by moving the shared type to a namespace both can use or inverting it behind an interface. — JPPhotoManager/JPPhotoManager.UI/Controls/ThumbnailsUserControl.xaml.cs:6
What to do
- Break namespace cycles inside a project by moving the shared type to a namespace both sides can use, or by inverting the back edge behind an interface.
AX4 · Dependency direction
AX5 · Architecture & structure
AX6 · Interface segregation
- `IStorageService` declares 29 members: `GetParentDirectory`, `GetSubDirectories`, `GetRecursiveSubDirectories`, `ResolveDataDirectory`, `CreateDirectory`, `ReadObjectFromJsonFile`, `WriteObjectToJsonFile`, `DeleteFile`, `GetFileNames`, `GetFileNames`, `GetFileBytes`, `LoadBitmapImage`, `LoadBitmapImage`, `LoadBitmapImage`, `GetExifOrientation`, `GetImageRotation`, `HasSameContent`, `LoadBitmapImage`, `GetJpegBitmapImage`, `GetPngBitmapImage`, `GetDrives`, `FileExists`, `FileExists`, `FolderExists`, `CopyImage`, `MoveImage`, `GetFileInformation`, `InitializeDatabaseDirectory`, `InitializeBinaryFilesDirectory`. Counted as the author wrote them — a property is ONE member and its get/set accessors are not counted separately, and an event counts once. Those 29 declarations carry 24 distinct name(s), so part of the width is overloading rather than separate responsibilities — but 24 operations clears the >15 bar on its own, so the row is about responsibilities, not signatures. A wide interface forces every implementer and caller to depend on methods they don't use (the Interface-Segregation 'I' in SOLID). Split it into focused role-interfaces. — JPPhotoManager/JPPhotoManager.Domain/Interfaces/Services/IStorageService.cs:7
- `IApplication` declares 25 members: `GetAssets`, `LoadThumbnail`, `GetSyncAssetsConfiguration`, `SetSyncAssetsConfiguration`, `SyncAssetsAsync`, `GetConvertAssetsConfiguration`, `SetConvertAssetsConfiguration`, `ConvertAssetsAsync`, `CatalogAssetsAsync`, `SetAsWallpaper`, `GetDuplicatedAssets`, `DeleteAssets`, `GetAboutInformation`, `GetDrives`, `GetSubFolders`, `GetInitialFolder`, `GetCatalogCooldownMinutes`, `MoveAssets`, `LoadBitmapImage`, `FileExists`, `GetRecentTargetPaths`, `GetRootCatalogFolders`, `IsAlreadyRunning`, `CheckNewReleaseAsyc`, `ShrinkDatabase`. Counted as the author wrote them — a property is ONE member and its get/set accessors are not counted separately, and an event counts once. A wide interface forces every implementer and caller to depend on methods they don't use (the Interface-Segregation 'I' in SOLID). Split it into focused role-interfaces. — JPPhotoManager/JPPhotoManager.Application/IApplication.cs:8
- `AssetRepository` declares 34 abstract methods: `addTagToAsset`, `completeIfAllStagesFinished`, `count`, `countByCreationMonth`, `countByExtension`, `countByRating`, `countDeleted`, `countDuplicates`, `countTotal`, `deleteById`, `existsById`, `findAll`, `findAllById`, `findAllDeleted`, `findAllFilteredSortedByDateDesc`, `findByFileName`, `findByFolder`, `findByFolderAndFileName`, `findById`, `findDeleted`, `findDeletedBefore`, `findFiltered`, `findNotDeleted`, `findRecentAssets`, `findTopFoldersByAssetCount`, `hasTag`, `removeTagFromAsset`, `save`, `sumFileSize`, `sumFileSizeByFolder`, `updateExifCompletedAt`, `updateHash`, `updateProcessingStatus`, `updateThumbnail`. Counted over its ABSTRACT methods, once per signature; `default`, `static` and `private` methods and constants are not counted, because no implementer is forced to write them. A wide interface forces every implementer and caller to depend on methods they don't use (the Interface-Segregation 'I' in SOLID). Split it into focused role-interfaces. — JPPhotoManagerWeb/backend/src/main/java/com/jpablodrexler/photomanager/domain/port/out/AssetRepository.java:18
- `StoragePort` declares 20 abstract methods: `computeHash`, `convertPngToJpeg`, `copyFile`, `createDirectory`, `deleteFile`, `directoryExists`, `fileExists`, `generateThumbnail`, `getExifMetadata`, `getFileCreationDateTime`, `getFileModificationDateTime`, `getFileSize`, `getImageRotation`, `isAudioFile`, `isPlaylistFile`, `isVideoFile`, `listFiles`, `listSubDirectories`, `moveFile`, `readFileBytes`. Counted over its ABSTRACT methods, once per signature; `default`, `static` and `private` methods and constants are not counted, because no implementer is forced to write them. A wide interface forces every implementer and caller to depend on methods they don't use (the Interface-Segregation 'I' in SOLID). Split it into focused role-interfaces. — JPPhotoManagerWeb/backend/src/main/java/com/jpablodrexler/photomanager/domain/port/out/StoragePort.java:10
- `JpaAssetRepository` declares 32 abstract methods: `addTagToAsset`, `completeIfAllStagesFinished`, `countByCreationMonth`, `countByDeletedAtIsNotNull`, `countByDeletedAtIsNull`, `countByExtension`, `countByRating`, `countDuplicates`, `deleteByFolderAndFileName`, `existsByFolderAndFileName`, `findAllByIdWithFolder`, `findAllWithFolder`, `findByAlbumId`, `findByDeletedAtBefore`, `findByFileNameNotDeleted`, `findByFolder`, `findByFolderAndFileName`, `findByHashNotDeleted`, `findByIdWithFolder`, `findDeletedOrderByDeletedAtDesc`, `findDuplicateHashes`, `findNotDeleted`, `findRecentAssets`, `findTopFoldersByAssetCount`, `hasTag`, `removeTagFromAsset`, `sumFileSize`, `sumFileSizeByFolder`, `updateExifCompletedAt`, `updateHash`, `updateProcessingStatus`, `updateThumbnail`. Counted over its ABSTRACT methods, once per signature; `default`, `static` and `private` methods and constants are not counted, because no implementer is forced to write them. A wide interface forces every implementer and caller to depend on methods they don't use (the Interface-Segregation 'I' in SOLID). Split it into focused role-interfaces. — JPPhotoManagerWeb/backend/src/main/java/com/jpablodrexler/photomanager/infrastructure/persistence/jpa/JpaAssetRepository.java:28
What to do
- Split fat interfaces into focused role-interfaces so clients depend only on what they use.
AX8 · Test isolation
DM10 · One transaction, one aggregate
- `MoveAssetsUseCaseImpl.execute` saves `folderRepository`, `assetRepository` in a single operation. Each is its own consistency boundary, so committing them together makes the second's invariants depend on the first's transaction, holds a lock across both for the whole operation, and means the pair can no longer be separated — into different services, or different databases. Mutate one aggregate here and let the others follow from a domain event. — JPPhotoManagerWeb/backend/src/main/java/com/jpablodrexler/photomanager/application/usecase/asset/MoveAssetsUseCaseImpl.java:45
- `CatalogAssetItemWriter.write` saves `Asset`, `AssetExif`, `AssetAudio` in a single operation. Each is its own consistency boundary, so committing them together makes the second's invariants depend on the first's transaction, holds a lock across both for the whole operation, and means the pair can no longer be separated — into different services, or different databases. Mutate one aggregate here and let the others follow from a domain event. — JPPhotoManagerWeb/backend/src/main/java/com/jpablodrexler/photomanager/infrastructure/batch/CatalogAssetItemWriter.java:76
What to do
- Mutate one aggregate per operation and let the others follow from a domain event — the second aggregate reaching consistency a moment later is the design, not a compromise.
DM11 · Constructible invalid state
- `RecentTargetPathEntity`'s public constructor takes `path` as raw primitives, and neither of the two things that would make that safe was found. What was searched, so you can tell an absence from a miss: for VALIDATION, the constructor body was scanned for `throw`, `Guard.`, `Ensure.`, `ArgumentNullException`, `ArgumentException`, `CheckRule` or `Requires.` — a guard reached through a helper method those tokens do not name is not seen; for a FACTORY, only this type's OWN static members were read, and only names beginning `Create`, `Of`, `From`, `New` or `Build` — one inherited from a base type, one on a companion builder, or one called `Parse`, `Make` or `Rehydrate` is not seen. If either exists, this row is wrong. If neither does, a caller can build a `RecentTargetPathEntity` that breaks the rules it exists to enforce, and every rule downstream then has to cope with a state the model said was impossible. Guard in the constructor, take value objects that validate themselves, or make the constructor private behind a `Create` that can refuse. — JPPhotoManagerWeb/backend/src/main/java/com/jpablodrexler/photomanager/infrastructure/persistence/entity/RecentTargetPathEntity.java:20
What to do
- Give each aggregate one way in that can refuse — a guarded constructor, value-object parameters that validate themselves, or a private constructor behind a factory that returns a failure.
DM12 · Ambient inputs in the domain
- `CatalogAssetsService` reads `DateTime.Now` inside `CreateAsset`. The rule this feeds is not a function of its inputs: it cannot be tested at the instant that matters without moving the machine clock, and two reads inside one operation can observe different times. Pass the instant in as a parameter, or inject `TimeProvider`. — JPPhotoManager/JPPhotoManager.Domain/Services/CatalogAssetsService.cs:345
What to do
- Pass the instant into the domain method that needs it, or inject `TimeProvider` (BCL, .NET 8+) and read it there — then a test can choose the moment a rule is evaluated at.
DM5 · Encapsulated state
DM6 · Domain ↔ infrastructure boundary
- `Asset` (domain layer) names `KeyAttribute` from `System.ComponentModel.DataAnnotations` — a persistence type (as an attribute). The domain should own a port and let an infrastructure adapter implement it. — JPPhotoManager/JPPhotoManager.Domain/Entities/Asset.cs:14
- `Asset` (domain layer) names `NotMappedAttribute` from `System.ComponentModel.DataAnnotations.Schema` — a persistence type (as an attribute). The domain should own a port and let an infrastructure adapter implement it. (×2) — JPPhotoManager/JPPhotoManager.Domain/Entities/Asset.cs:28, JPPhotoManager/JPPhotoManager.Domain/Entities/Asset.cs:31
- `ConvertAssetsDirectoriesDefinition` (domain layer) names `KeyAttribute` from `System.ComponentModel.DataAnnotations` — a persistence type (as an attribute). The domain should own a port and let an infrastructure adapter implement it. — JPPhotoManager/JPPhotoManager.Domain/Entities/ConvertAssetsDirectoriesDefinition.cs:11
- `Folder` (domain layer) names `KeyAttribute` from `System.ComponentModel.DataAnnotations` — a persistence type (as an attribute). The domain should own a port and let an infrastructure adapter implement it. — JPPhotoManager/JPPhotoManager.Domain/Entities/Folder.cs:8
- `Folder` (domain layer) names `NotMappedAttribute` from `System.ComponentModel.DataAnnotations.Schema` — a persistence type (as an attribute). The domain should own a port and let an infrastructure adapter implement it. (×2) — JPPhotoManager/JPPhotoManager.Domain/Entities/Folder.cs:12, JPPhotoManager/JPPhotoManager.Domain/Entities/Folder.cs:24
- `RecentTargetPath` (domain layer) names `KeyAttribute` from `System.ComponentModel.DataAnnotations` — a persistence type (as an attribute). The domain should own a port and let an infrastructure adapter implement it. — JPPhotoManager/JPPhotoManager.Domain/Entities/RecentTargetPath.cs:7
- `SyncAssetsDirectoriesDefinition` (domain layer) names `KeyAttribute` from `System.ComponentModel.DataAnnotations` — a persistence type (as an attribute). The domain should own a port and let an infrastructure adapter implement it. — JPPhotoManager/JPPhotoManager.Domain/Entities/SyncAssetsDirectoriesDefinition.cs:11
What to do
- Invert domain→infrastructure dependencies: declare interfaces in the domain, implement them in infrastructure (Dependency Inversion).
DM7 · Repository granularity
DM8 · Value-object opportunities
DM9 · Scattered domain decisions
GD1 · Unfinished & placeholder code
- A shipped member still throws NotImplementedException — generated scaffolding that was never completed. Implement it or remove the dead surface. (×3) — JPPhotoManager/JPPhotoManager.UI/Converters/FileSizeConverter.cs:56, JPPhotoManager/JPPhotoManager.UI/Converters/PixelSizeConverter.cs:22, JPPhotoManager/JPPhotoManager.UI/Converters/VisibilityConverter.cs:15
What to do
- Finish or delete NotImplementedException stubs and replace placeholder literals before shipping.
IC1 · Incompleteness & stubs
- A test is skipped ("GitHub API integration test") — coverage that looks present but never runs in any gate. If it's an opt-in suite, document how it runs; otherwise re-enable or delete it. — JPPhotoManager/JPPhotoManager.Tests/Integration/ReleaseAvailabilityServiceTests.cs:35
- A line of code has been commented out rather than removed — dead weight that rots and confuses. Delete it (version control remembers). — JPPhotoManager/JPPhotoManager.UI/Windows/FolderNavigationWindow.xaml.cs:71
What to do
- Clear the softer debt: remove commented-out code and dead branches, re-enable or delete skipped tests, and replace blanket warning suppressions with targeted ones.
M1 · Documentation (README)
What to do
- Explain in the README how to run the tests. Add a section called Testing to the README in the repository's top folder, saying how to run the test suite.
- Add an 'Architecture' / 'How it works' section to the root README — the high-level shape.
- Add a README to the 1 of 6 project(s) that lack one — worth up to 0.3 pts.
M2 · Architecture documentation
- No Architecture Decision Records found — no conventional ADR directory, no numbered `NNNN-title` documents in any markup this check reads, and nothing ADR-shaped by content. Design rationale recorded elsewhere (a design-notes tree, a mailing list, pull-request discussion) is not visible to this check and is not re-findable per decision, so a future maintainer cannot ask why one choice was made and get an answer.
What to do
- Record your significant design decisions. Write one short document per decision, giving its date, the situation, the decision and its consequences, and keep them together with your other design documents. A docs/adr folder with each file named by number and title is the easiest place to find them.
M3 · Folder & project structure
- Production code isn't grouped under a src/ folder — it's spread across several top-level directories, so there's no one place that says 'this is the product'.
What to do
- Group production code under src/ (or split deliberately, e.g. backend/ + frontend/) so production and tooling code aren't mixed at the root.
M4 · Documentation accuracy
- JPPhotoManagerWeb/README.md runs `bash scripts/complexity-report.sh`, but `scripts/complexity-report.sh` does not exist. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents' own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong. — JPPhotoManagerWeb/README.md:38
- JPPhotoManagerWeb/README.md runs `bash scripts/dead-code-report.sh`, but `scripts/dead-code-report.sh` does not exist. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents' own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong. — JPPhotoManagerWeb/README.md:39
- JPPhotoManagerWeb/README.md runs `bash scripts/auth-coverage-report.sh`, but `scripts/auth-coverage-report.sh` does not exist. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents' own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong. — JPPhotoManagerWeb/README.md:41
- JPPhotoManagerWeb/README.md runs `bash scripts/coverage-report.sh`, but `scripts/coverage-report.sh` does not exist. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents' own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong. — JPPhotoManagerWeb/README.md:44
- JPPhotoManagerWeb/README.md runs `bash scripts/mutation-report.sh`, but `scripts/mutation-report.sh` does not exist. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents' own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong. — JPPhotoManagerWeb/README.md:48
- JPPhotoManagerWeb/README.md runs `bash scripts/license-report.sh`, but `scripts/license-report.sh` does not exist. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents' own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong. — JPPhotoManagerWeb/README.md:50
- JPPhotoManagerWeb/README.md runs `bash scripts/sca-report.sh`, but `scripts/sca-report.sh` does not exist. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents' own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong. — JPPhotoManagerWeb/README.md:51
- JPPhotoManagerWeb/README.md names `SKILL.md`, but no file or folder `SKILL.md` exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents' own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong. — JPPhotoManagerWeb/README.md:57
- docs/windows-dev-setup.md names Node.js 24, but the repository declares pinned 22. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents' own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong. — docs/windows-dev-setup.md:164
- JPPhotoManagerWeb/docs/authentication.md names `.env`, but no file or folder `.env` exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents' own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong. — JPPhotoManagerWeb/docs/authentication.md:176
- JPPhotoManagerWeb/docs/authentication.md documents the environment variable `HOST_IMAGE_DIR_N`, but no code, script or configuration file names it. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents' own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong. — JPPhotoManagerWeb/docs/authentication.md:222
- JPPhotoManagerWeb/docs/backend.md names `application/service/PasswordValidationService`, but no file or folder `application/service/PasswordValidationService` exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents' own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong. — JPPhotoManagerWeb/docs/backend.md:307
- JPPhotoManagerWeb/docs/docker-compose.md names `.env`, but no file or folder `.env` exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents' own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong. — JPPhotoManagerWeb/docs/docker-compose.md:20
- JPPhotoManagerWeb/docs/docker-compose.md documents the environment variable `HOST_IMAGE_DIR_N`, but no code, script or configuration file names it. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents' own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong. — JPPhotoManagerWeb/docs/docker-compose.md:25
- JPPhotoManagerWeb/docs/docker-compose.md names `grafana/grafana`, but no file or folder `grafana/grafana` exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents' own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong. — JPPhotoManagerWeb/docs/docker-compose.md:85
- JPPhotoManagerWeb/docs/kubernetes.md names `k8s/catalog-volumes.yaml`, but no file or folder `k8s/catalog-volumes.yaml` exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents' own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong. — JPPhotoManagerWeb/docs/kubernetes.md:13
- JPPhotoManagerWeb/docs/kubernetes.md runs `./scripts/build-and-deploy-k8s.sh`, but `scripts/build-and-deploy-k8s.sh` does not exist. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents' own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong. — JPPhotoManagerWeb/docs/kubernetes.md:46
What to do
- Reconcile the README with reality: JPPhotoManagerWeb/README.md runs `bash scripts/complexity-report.sh`, but `scripts/complexity-report.sh` does not exist; JPPhotoManagerWeb/README.md runs `bash scripts/dead-code-report.sh`, but `scripts/dead-code-report.sh` does not exist; JPPhotoManagerWeb/README.md runs `bash scripts/auth-coverage-report.sh`, but `scripts/auth-coverage-report.sh` does not exist; JPPhotoManagerWeb/README.md runs `bash scripts/coverage-report.sh`, but `scripts/coverage-report.sh` does not exist; JPPhotoManagerWeb/README.md runs `bash scripts/mutation-report.sh`, but `scripts/mutation-report.sh` does not exist.
P1 · CI/CD gates
P2 · Observability
P3 · Security & performance tooling
What to do
- The .NET analyzers are running but not blocking — tighten them (set <AnalysisMode>All</AnalysisMode>, or treat analyzer warnings as errors on CI) so a security/quality regression fails the build rather than scrolling past as a warning.
- Enable Dependabot/Renovate or a dependency-review gate.
- Add gitleaks/trufflehog in CI to block PRs that introduce committed secrets.
P4 · Deployment & Rollback
What to do
- Add an approval/environment gate (required reviewers / protection rules) before production promotion.
P5 · DR & Backup
What to do
- Document RTO/RPO and a tested restore procedure (a backup config alone isn't disaster recovery).
P6 · Release Hygiene
- The changelog this check read carries 2 versioned entries, against a bar of 3. Counted as either the distinct `x.y.z` versions it names (a link's target is not counted) or its version-shaped section headings (`## [1.2.0]`, `## V14.x.x`, `## Updates in 8.0.x`), whichever is the larger — so a log sectioned by minor series counts its sections, not its individual patch numbers. Entries recorded somewhere this check does not read — release notes generated at tag time from a generator config it did not recognise, or a log kept outside the repository — are not counted here, and this row is about what is re-findable in the tree rather than about how often you release.
What to do
- Keep the changelog current — add a versioned entry (Keep-a-Changelog ## [x.y.z]) for each release so the history isn't a stub.
P8 · Schema migrations
PF3 · Async & latency hygiene
- `fs.readFileSync` in `main` blocks the event loop until it finishes — a blocking call inside async code stalls the event loop — every other request waits for as long as it runs. — JPPhotoManagerWeb/frontend/scripts/lighthouse-report.mjs:111
- `fs.existsSync` in `main` blocks the event loop until it finishes — a blocking call inside async code stalls the event loop — every other request waits for as long as it runs. (×2) — JPPhotoManagerWeb/frontend/scripts/lighthouse-report.mjs:116, JPPhotoManagerWeb/frontend/scripts/lighthouse-report.mjs:121
- `execSync` in `main` blocks the event loop until it finishes — a blocking call inside async code stalls the event loop — every other request waits for as long as it runs. (×2) — JPPhotoManagerWeb/frontend/scripts/lighthouse-report.mjs:119, JPPhotoManagerWeb/frontend/scripts/lighthouse-report.mjs:143
- `fs.mkdirSync` in `main` blocks the event loop until it finishes — a blocking call inside async code stalls the event loop — every other request waits for as long as it runs. — JPPhotoManagerWeb/frontend/scripts/lighthouse-report.mjs:184
- `fs.writeFileSync` in `main` blocks the event loop until it finishes — a blocking call inside async code stalls the event loop — every other request waits for as long as it runs. — JPPhotoManagerWeb/frontend/scripts/lighthouse-report.mjs:186
What to do
- TypeScript/JavaScript: use the promise APIs (fs/promises, a promisified child_process.execFile, the async zlib/crypto functions) and await them instead of the *Sync variants.
R1 · Type Safety
What to do
- Migrate the remaining .js/.jsx files to TypeScript.
R10 · Code Duplication
- 5 duplicated blocks under JPPhotoManagerWeb/frontend/src/app/features/ have copies in at least two of the sibling directories admin, albums, convert, gallery, profile, recycle-bin (+1 more sibling(s) not listed) — 3 of them are reported below, and 2 are counted here but not reported individually: those copies match on shape but no longer clear R10's bar for an individually reported row — either they kept neither their own names nor their values, or what was copied is too small to stand on its own (it reports near-exact duplication only, and only of substantial extent). What this row states is the concentration, which the detector measured over all 5 and which does not depend on how exactly each block's copies still match. That concentration is one structural fact, not 5 local ones: the siblings replicate behaviour none of them owns, which is the shape of a missing shared module — a common library every sibling imports — rather than 5 separate extractions. Check first whether the siblings are deliberately standalone deliverables (scaffold templates, demo apps that must stay copy-pasteable); where they are, the duplication is the design and the per-block rows are the ones to act on. — JPPhotoManagerWeb/frontend/src/app/features/convert/convert.component.ts:1
- JPPhotoManagerWeb/frontend/src/app/features/convert/convert.component.ts:1 · JPPhotoManagerWeb/frontend/src/app/features/sync/sync.component.ts:1 — these 2 files are line-for-line copies of one another — 77 lines are identical, in the same order, in every one of them — so this is one fact about the file set, not a block to extract. An edit made to one file and not the others changes behaviour silently, which is the failure a wholesale copy guarantees. Pick one file as the single source and derive the others from it (re-export it, spread it into the local overrides each variant genuinely needs, or generate the copies at build time) — the few lines that differ between the files are exactly the part each variant should still own. Check first whether the copies are deliberately standalone deliverables (a translation file seeded from its sibling and waiting to be translated); where they are, the duplication is the design, and the honest move is to mark the seeded file as untranslated rather than to let it pass as done. — JPPhotoManagerWeb/frontend/src/app/features/convert/convert.component.ts:1
- JPPhotoManagerWeb/frontend/scripts/dead-code-report.js:21 · JPPhotoManagerWeb/frontend/scripts/type-coverage-report.js:19 — the two spans are one implementation copied and then locally edited — 296 tokens are still identical, in the same order in both files, with only local edits between them. The copies have already begun to drift, which is this row's finding: an edit made to one and not the other changes behaviour silently. Diff the two spans first to learn what genuinely differs, then extract the shared core into one module both sites use, passing the differences in as parameters — or, if one copy exists only because the other could not be imported from its context, make one of them the single source the other is generated or re-exported from. If one copy is no longer reachable, delete it rather than letting it shadow the live one. — JPPhotoManagerWeb/frontend/scripts/dead-code-report.js:21
- JPPhotoManagerWeb/frontend/scripts/license-compliance-report.js:21 · JPPhotoManagerWeb/frontend/scripts/sca-report.js:22 — the 2 copies sit in sibling files in one directory, so check first whether one of them (or an existing module there) already owns this behaviour and the others should call it; otherwise extract it into one module in that directory and have each site call it. — JPPhotoManagerWeb/frontend/scripts/license-compliance-report.js:21
- JPPhotoManagerWeb/frontend/scripts/code-coverage-report.js:71 · JPPhotoManagerWeb/frontend/scripts/complexity-report.js:39 · JPPhotoManagerWeb/frontend/scripts/dead-code-report.js:53 · JPPhotoManagerWeb/frontend/scripts/type-coverage-report.js:46 — the 4 copies sit in sibling files in one directory, so check first whether one of them (or an existing module there) already owns this behaviour and the others should call it; otherwise extract it into one module in that directory and have each site call it. There is one copy in each of 4 separate files rather than several in one place, so check first whether these are sibling modules that each declare their own version of one shape — one per entity, per provider, per language. Where they are, no single extracted module collapses them: each module still has to be written, and what recurs is the TEMPLATE. The moves that do collapse a template are to generate these modules from the set they enumerate, or to replace the repeated construction with one factory each site calls with its own values — and where the set is the point, each module pinning one distinct thing, the repetition IS the enumeration and there is nothing to delete. — JPPhotoManagerWeb/frontend/scripts/code-coverage-report.js:71
- JPPhotoManagerWeb/frontend/src/app/features/gallery/exif-panel/exif-panel.component.ts:59 · JPPhotoManagerWeb/frontend/src/app/features/gallery/gallery.component.ts:159 — the two spans are one implementation copied and then locally edited — 118 tokens are still identical, in the same order in both files, with only local edits between them. The copies have already begun to drift, which is this row's finding: an edit made to one and not the other changes behaviour silently. Diff the two spans first to learn what genuinely differs, then extract the shared core into one module both sites use, passing the differences in as parameters — or, if one copy exists only because the other could not be imported from its context, make one of them the single source the other is generated or re-exported from. If one copy is no longer reachable, delete it rather than letting it shadow the live one. — JPPhotoManagerWeb/frontend/src/app/features/gallery/exif-panel/exif-panel.component.ts:59
- JPPhotoManagerWeb/frontend/scripts/lighthouse-report.mjs:139 · JPPhotoManagerWeb/frontend/scripts/mutation-report.js:119 — the two spans are one implementation copied and then locally edited — 116 tokens are still identical, in the same order in both files, with only local edits between them. The copies have already begun to drift, which is this row's finding: an edit made to one and not the other changes behaviour silently. Diff the two spans first to learn what genuinely differs, then extract the shared core into one module both sites use, passing the differences in as parameters — or, if one copy exists only because the other could not be imported from its context, make one of them the single source the other is generated or re-exported from. If one copy is no longer reachable, delete it rather than letting it shadow the live one. — JPPhotoManagerWeb/frontend/scripts/lighthouse-report.mjs:139
- JPPhotoManagerWeb/frontend/scripts/a11y-report.js:95 · JPPhotoManagerWeb/frontend/scripts/code-coverage-report.js:77 · JPPhotoManagerWeb/frontend/scripts/complexity-report.js:45 · JPPhotoManagerWeb/frontend/scripts/dead-code-report.js:59 · +2 more site(s) not listed — the 6 copies are spread across 6 files, and the CITED SPAN is not a self-contained block — it runs from inside one construct into the next (the tail of a branch plus the head of the following one, a run of switch arms, the end of a declaration plus the list that follows it) rather than covering a whole unit. So do not lift these lines literally: no call can be substituted for a half-open construct. Extract the enclosing repeated UNIT instead — the whole function, component or branch these lines sit in — and where the repetition IS the construct (a run of switch arms, a stack of near-identical declarations) replace it with one table or registry looked up by key rather than a helper each arm calls. The copies still drift apart the first time only one of them is edited, which is why this is reported. — JPPhotoManagerWeb/frontend/scripts/a11y-report.js:95
- JPPhotoManagerWeb/frontend/scripts/bundle-size-report.js:122 · JPPhotoManagerWeb/frontend/scripts/dependency-staleness-report.js:109 — the 2 copies are spread across 2 files, and the CITED SPAN is not a self-contained block — it runs from inside one construct into the next (the tail of a branch plus the head of the following one, a run of switch arms, the end of a declaration plus the list that follows it) rather than covering a whole unit. So do not lift these lines literally: no call can be substituted for a half-open construct. Extract the enclosing repeated UNIT instead — the whole function, component or branch these lines sit in — and where the repetition IS the construct (a run of switch arms, a stack of near-identical declarations) replace it with one table or registry looked up by key rather than a helper each arm calls. The copies still drift apart the first time only one of them is edited, which is why this is reported. — JPPhotoManagerWeb/frontend/scripts/bundle-size-report.js:122
- JPPhotoManagerWeb/frontend/src/app/features/gallery/bulk-tag-dialog/bulk-tag-dialog.component.ts:89 · JPPhotoManagerWeb/frontend/src/app/features/gallery/bulk-tag-dialog/bulk-tag-dialog.component.ts:109 — all 2 copies are in the same file, and the CITED SPAN is not a self-contained block — it runs from inside one construct into the next (the tail of a branch plus the head of the following one, a run of switch arms, the end of a declaration plus the list that follows it) rather than covering a whole unit. So do not lift these lines literally: no call can be substituted for a half-open construct. Extract the enclosing repeated UNIT instead — the whole function, component or branch these lines sit in — and where the repetition IS the construct (a run of switch arms, a stack of near-identical declarations) replace it with one table or registry looked up by key rather than a helper each arm calls. The copies still drift apart the first time only one of them is edited, which is why this is reported. — JPPhotoManagerWeb/frontend/src/app/features/gallery/bulk-tag-dialog/bulk-tag-dialog.component.ts:89
- JPPhotoManagerWeb/frontend/scripts/complexity-report.js:49 · JPPhotoManagerWeb/frontend/scripts/dead-code-report.js:63 · JPPhotoManagerWeb/frontend/scripts/license-compliance-report.js:68 · JPPhotoManagerWeb/frontend/scripts/sca-report.js:71 · +1 more site(s) not listed — the 5 copies sit in sibling files in one directory, so check first whether one of them (or an existing module there) already owns this behaviour and the others should call it; otherwise extract it into one module in that directory and have each site call it. There is one copy in each of 5 separate files rather than several in one place, so check first whether these are sibling modules that each declare their own version of one shape — one per entity, per provider, per language. Where they are, no single extracted module collapses them: each module still has to be written, and what recurs is the TEMPLATE. The moves that do collapse a template are to generate these modules from the set they enumerate, or to replace the repeated construction with one factory each site calls with its own values — and where the set is the point, each module pinning one distinct thing, the repetition IS the enumeration and there is nothing to delete. — JPPhotoManagerWeb/frontend/scripts/complexity-report.js:49
- JPPhotoManagerWeb/frontend/src/app/core/services/convert.service.ts:6 · JPPhotoManagerWeb/frontend/src/app/core/services/sync.service.ts:6 — the 2 copies are spread across 2 files, and the SHAPE of this repetition could not be determined. It is not a run of declarations, a listing, a declaration header, a type body or a slice through a construct — and it was not measured as a run of executable statements either, so this row cannot tell you whether a function can stand where these lines are. Read the two spans before acting, because the move is opposite in the two cases. Where they are statements, the ordinary answer holds: give the shared part one home and call it from each site. Where they turn out to be declarations, a literal's entries, or the cases of an enumeration, there is no call site to call anything from, and collapsing them would delete what each copy pins — a shared base type, a generated set, or one exported constant each site refers to is the move instead, and sometimes the honest answer is that there is nothing to extract at all. Reported because the copies drift apart the first time only one of them is edited, which is true whichever of those they are. — JPPhotoManagerWeb/frontend/src/app/core/services/convert.service.ts:6
- JPPhotoManagerWeb/frontend/src/app/features/gallery/exif-panel/exif-panel.component.ts:116 · JPPhotoManagerWeb/frontend/src/app/features/gallery/exif-panel/exif-panel.component.ts:130 — both copies are in the same file, so extract the block into one function there and call it from each site — the copies drift apart the first time only one of them is edited. — JPPhotoManagerWeb/frontend/src/app/features/gallery/exif-panel/exif-panel.component.ts:116
- JPPhotoManagerWeb/frontend/src/app/features/audio-player/audio-player.component.ts:15 · JPPhotoManagerWeb/frontend/src/app/shared/components/media-fullscreen-overlay/media-fullscreen-overlay.component.ts:25 — the 2 copies are spread across 2 directories, so the shared home is a decision rather than an obvious spot: check first whether one of them already owns this behaviour, and otherwise put the extracted module somewhere all of the sites already reach rather than making one of them depend on another. — JPPhotoManagerWeb/frontend/src/app/features/audio-player/audio-player.component.ts:15
- JPPhotoManagerWeb/frontend/src/app/core/services/album.service.ts:6 · JPPhotoManagerWeb/frontend/src/app/core/services/search-preset.service.ts:6 — the 2 copies are spread across 2 files, and the CITED SPAN is not a self-contained block — it runs from inside one construct into the next (the tail of a branch plus the head of the following one, a run of switch arms, the end of a declaration plus the list that follows it) rather than covering a whole unit. So do not lift these lines literally: no call can be substituted for a half-open construct. Extract the enclosing repeated UNIT instead — the whole function, component or branch these lines sit in — and where the repetition IS the construct (a run of switch arms, a stack of near-identical declarations) replace it with one table or registry looked up by key rather than a helper each arm calls. The copies still drift apart the first time only one of them is edited, which is why this is reported. — JPPhotoManagerWeb/frontend/src/app/core/services/album.service.ts:6
- JPPhotoManagerWeb/frontend/src/app/features/gallery/gallery.component.ts:238 · JPPhotoManagerWeb/frontend/src/app/features/gallery/gallery.component.ts:430 — all 2 copies are in the same file, and the CITED SPAN is not a self-contained block — it runs from inside one construct into the next (the tail of a branch plus the head of the following one, a run of switch arms, the end of a declaration plus the list that follows it) rather than covering a whole unit. So do not lift these lines literally: no call can be substituted for a half-open construct. Extract the enclosing repeated UNIT instead — the whole function, component or branch these lines sit in — and where the repetition IS the construct (a run of switch arms, a stack of near-identical declarations) replace it with one table or registry looked up by key rather than a helper each arm calls. The copies still drift apart the first time only one of them is edited, which is why this is reported. — JPPhotoManagerWeb/frontend/src/app/features/gallery/gallery.component.ts:238
- JPPhotoManagerWeb/frontend/src/app/features/gallery/gallery.component.ts:441 · JPPhotoManagerWeb/frontend/src/app/features/recycle-bin/recycle-bin.component.ts:53 — the 2 copies are spread across 2 directories, so the shared home is a decision rather than an obvious spot: check first whether one of them already owns this behaviour, and otherwise put the extracted module somewhere all of the sites already reach rather than making one of them depend on another. — JPPhotoManagerWeb/frontend/src/app/features/gallery/gallery.component.ts:441
- JPPhotoManagerWeb/frontend/src/app/features/gallery/gallery.component.ts:949 · JPPhotoManagerWeb/frontend/src/app/features/gallery/gallery.component.ts:966 — both copies are in the same file, so extract the block into one function there and call it from each site — the copies drift apart the first time only one of them is edited. — JPPhotoManagerWeb/frontend/src/app/features/gallery/gallery.component.ts:949
- JPPhotoManagerWeb/frontend/scripts/license-compliance-report.js:95 · JPPhotoManagerWeb/frontend/scripts/sca-report.js:99 · JPPhotoManagerWeb/frontend/scripts/secrets-scan-report.js:108 — the 3 copies are spread across 3 files, and the CITED SPAN is not a self-contained block — it runs from inside one construct into the next (the tail of a branch plus the head of the following one, a run of switch arms, the end of a declaration plus the list that follows it) rather than covering a whole unit. So do not lift these lines literally: no call can be substituted for a half-open construct. Extract the enclosing repeated UNIT instead — the whole function, component or branch these lines sit in — and where the repetition IS the construct (a run of switch arms, a stack of near-identical declarations) replace it with one table or registry looked up by key rather than a helper each arm calls. The copies still drift apart the first time only one of them is edited, which is why this is reported. — JPPhotoManagerWeb/frontend/scripts/license-compliance-report.js:95
- JPPhotoManagerWeb/frontend/src/app/core/services/asset.service.ts:20 · JPPhotoManagerWeb/frontend/src/app/core/services/asset.service.ts:35 — the two spans are one implementation copied and then locally edited — 85 tokens are still identical, in the same order in both spans, with only local edits between them. The copies have already begun to drift, which is this row's finding: an edit made to one and not the other changes behaviour silently. Diff the two spans first to learn what genuinely differs, then extract the shared core into one module both sites use, passing the differences in as parameters — or, if one copy exists only because the other could not be imported from its context, make one of them the single source the other is generated or re-exported from. If one copy is no longer reachable, delete it rather than letting it shadow the live one. — JPPhotoManagerWeb/frontend/src/app/core/services/asset.service.ts:20
- JPPhotoManagerWeb/frontend/src/app/features/albums/albums.component.ts:53 · JPPhotoManagerWeb/frontend/src/app/features/convert/convert.component.ts:50 · JPPhotoManagerWeb/frontend/src/app/features/sync/sync.component.ts:50 — the 3 copies are spread across 3 files, and the CITED SPAN is not a self-contained block — it runs from inside one construct into the next (the tail of a branch plus the head of the following one, a run of switch arms, the end of a declaration plus the list that follows it) rather than covering a whole unit. So do not lift these lines literally: no call can be substituted for a half-open construct. Extract the enclosing repeated UNIT instead — the whole function, component or branch these lines sit in — and where the repetition IS the construct (a run of switch arms, a stack of near-identical declarations) replace it with one table or registry looked up by key rather than a helper each arm calls. The copies still drift apart the first time only one of them is edited, which is why this is reported. — JPPhotoManagerWeb/frontend/src/app/features/albums/albums.component.ts:53
- JPPhotoManagerWeb/frontend/src/app/features/audio-player/audio-player.component.ts:17 · JPPhotoManagerWeb/frontend/src/app/features/gallery/video-player/video-player.component.ts:27 · JPPhotoManagerWeb/frontend/src/app/shared/components/media-fullscreen-overlay/media-fullscreen-overlay.component.ts:27 — the 3 copies are spread across 3 directories, so the shared home is a decision rather than an obvious spot: check first whether one of them already owns this behaviour, and otherwise put the extracted module somewhere all of the sites already reach rather than making one of them depend on another. There is one copy in each of 3 separate files rather than several in one place, so check first whether these are sibling modules that each declare their own version of one shape — one per entity, per provider, per language. Where they are, no single extracted module collapses them: each module still has to be written, and what recurs is the TEMPLATE. The moves that do collapse a template are to generate these modules from the set they enumerate, or to replace the repeated construction with one factory each site calls with its own values — and where the set is the point, each module pinning one distinct thing, the repetition IS the enumeration and there is nothing to delete. — JPPhotoManagerWeb/frontend/src/app/features/audio-player/audio-player.component.ts:17
- JPPhotoManagerWeb/frontend/src/app/features/recycle-bin/recycle-bin.component.ts:69 · JPPhotoManagerWeb/frontend/src/app/features/recycle-bin/recycle-bin.component.ts:81 — all 2 copies are in the same file, and the CITED SPAN is not a self-contained block — it runs from inside one construct into the next (the tail of a branch plus the head of the following one, a run of switch arms, the end of a declaration plus the list that follows it) rather than covering a whole unit. So do not lift these lines literally: no call can be substituted for a half-open construct. Extract the enclosing repeated UNIT instead — the whole function, component or branch these lines sit in — and where the repetition IS the construct (a run of switch arms, a stack of near-identical declarations) replace it with one table or registry looked up by key rather than a helper each arm calls. The copies still drift apart the first time only one of them is edited, which is why this is reported. — JPPhotoManagerWeb/frontend/src/app/features/recycle-bin/recycle-bin.component.ts:69
- JPPhotoManagerWeb/frontend/src/app/core/services/convert.service.ts:1 · JPPhotoManagerWeb/frontend/src/app/core/services/recycle-bin.service.ts:2 · JPPhotoManagerWeb/frontend/src/app/core/services/sync.service.ts:1 — the 3 copies are spread across 3 files, and the SHAPE of this repetition could not be determined. It is not a run of declarations, a listing, a declaration header, a type body or a slice through a construct — and it was not measured as a run of executable statements either, so this row cannot tell you whether a function can stand where these lines are. Read the two spans before acting, because the move is opposite in the two cases. Where they are statements, the ordinary answer holds: give the shared part one home and call it from each site. Where they turn out to be declarations, a literal's entries, or the cases of an enumeration, there is no call site to call anything from, and collapsing them would delete what each copy pins — a shared base type, a generated set, or one exported constant each site refers to is the move instead, and sometimes the honest answer is that there is nothing to extract at all. Reported because the copies drift apart the first time only one of them is edited, which is true whichever of those they are. — JPPhotoManagerWeb/frontend/src/app/core/services/convert.service.ts:1
- JPPhotoManagerWeb/frontend/src/app/core/services/media-player.service.ts:88 · JPPhotoManagerWeb/frontend/src/app/core/services/media-player.service.ts:161 — the two spans are one implementation copied and then locally edited — 59 tokens are still identical, in the same order in both spans, with only local edits between them. The copies have already begun to drift, which is this row's finding: an edit made to one and not the other changes behaviour silently. Diff the two spans first to learn what genuinely differs, then extract the shared core into one module both sites use, passing the differences in as parameters — or, if one copy exists only because the other could not be imported from its context, make one of them the single source the other is generated or re-exported from. If one copy is no longer reachable, delete it rather than letting it shadow the live one. — JPPhotoManagerWeb/frontend/src/app/core/services/media-player.service.ts:88
- JPPhotoManagerWeb/frontend/src/app/features/albums/album-detail/album-detail.component.ts:65 · JPPhotoManagerWeb/frontend/src/app/features/albums/albums.component.ts:69 — the 2 copies are spread across 2 directories, so the shared home is a decision rather than an obvious spot: check first whether one of them already owns this behaviour, and otherwise put the extracted module somewhere all of the sites already reach rather than making one of them depend on another. — JPPhotoManagerWeb/frontend/src/app/features/albums/album-detail/album-detail.component.ts:65
- JPPhotoManagerWeb/frontend/src/app/features/gallery/gallery.component.ts:821 · JPPhotoManagerWeb/frontend/src/app/features/gallery/gallery.component.ts:831 — both copies are in the same file, so extract the block into one function there and call it from each site — the copies drift apart the first time only one of them is edited. — JPPhotoManagerWeb/frontend/src/app/features/gallery/gallery.component.ts:821
- JPPhotoManagerWeb/frontend/scripts/dead-code-report.js:110 · JPPhotoManagerWeb/frontend/scripts/dead-code-report.js:119 — all 2 copies are in the same file, and the CITED SPAN is not a self-contained block — it runs from inside one construct into the next (the tail of a branch plus the head of the following one, a run of switch arms, the end of a declaration plus the list that follows it) rather than covering a whole unit. So do not lift these lines literally: no call can be substituted for a half-open construct. Extract the enclosing repeated UNIT instead — the whole function, component or branch these lines sit in — and where the repetition IS the construct (a run of switch arms, a stack of near-identical declarations) replace it with one table or registry looked up by key rather than a helper each arm calls. The copies still drift apart the first time only one of them is edited, which is why this is reported. — JPPhotoManagerWeb/frontend/scripts/dead-code-report.js:110
- JPPhotoManagerWeb/frontend/scripts/dependency-staleness-report.js:80 · JPPhotoManagerWeb/frontend/scripts/e2e-run-report.js:62 · JPPhotoManagerWeb/frontend/scripts/license-compliance-report.js:66 · JPPhotoManagerWeb/frontend/scripts/route-coverage-report.js:94 · +1 more site(s) not listed — the 5 copies are spread across 5 files, and the CITED SPAN is not a self-contained block — it runs from inside one construct into the next (the tail of a branch plus the head of the following one, a run of switch arms, the end of a declaration plus the list that follows it) rather than covering a whole unit. So do not lift these lines literally: no call can be substituted for a half-open construct. Extract the enclosing repeated UNIT instead — the whole function, component or branch these lines sit in — and where the repetition IS the construct (a run of switch arms, a stack of near-identical declarations) replace it with one table or registry looked up by key rather than a helper each arm calls. The copies still drift apart the first time only one of them is edited, which is why this is reported. — JPPhotoManagerWeb/frontend/scripts/dependency-staleness-report.js:80
- JPPhotoManagerWeb/frontend/scripts/a11y-report.js:166 · JPPhotoManagerWeb/frontend/scripts/bundle-size-report.js:131 · JPPhotoManagerWeb/frontend/scripts/dependency-staleness-report.js:118 — the 3 copies are spread across 3 files, and the CITED SPAN is not a self-contained block — it runs from inside one construct into the next (the tail of a branch plus the head of the following one, a run of switch arms, the end of a declaration plus the list that follows it) rather than covering a whole unit. So do not lift these lines literally: no call can be substituted for a half-open construct. Extract the enclosing repeated UNIT instead — the whole function, component or branch these lines sit in — and where the repetition IS the construct (a run of switch arms, a stack of near-identical declarations) replace it with one table or registry looked up by key rather than a helper each arm calls. The copies still drift apart the first time only one of them is edited, which is why this is reported. — JPPhotoManagerWeb/frontend/scripts/a11y-report.js:166
- JPPhotoManagerWeb/frontend/scripts/complexity-report.js:69 · JPPhotoManagerWeb/frontend/scripts/complexity-report.js:77 — both copies are in the same file, so extract the block into one function there and call it from each site — the copies drift apart the first time only one of them is edited. — JPPhotoManagerWeb/frontend/scripts/complexity-report.js:69
- JPPhotoManagerWeb/frontend/scripts/dependency-staleness-report.js:100 · JPPhotoManagerWeb/frontend/scripts/sca-report.js:89 — the 2 copies are spread across 2 files, and the CITED SPAN is not a self-contained block — it runs from inside one construct into the next (the tail of a branch plus the head of the following one, a run of switch arms, the end of a declaration plus the list that follows it) rather than covering a whole unit. So do not lift these lines literally: no call can be substituted for a half-open construct. Extract the enclosing repeated UNIT instead — the whole function, component or branch these lines sit in — and where the repetition IS the construct (a run of switch arms, a stack of near-identical declarations) replace it with one table or registry looked up by key rather than a helper each arm calls. The copies still drift apart the first time only one of them is edited, which is why this is reported. — JPPhotoManagerWeb/frontend/scripts/dependency-staleness-report.js:100
- JPPhotoManagerWeb/frontend/src/app/features/gallery/gallery.component.ts:294 · JPPhotoManagerWeb/frontend/src/app/features/gallery/gallery.component.ts:423 — both copies are in the same file, so extract the block into one function there and call it from each site — the copies drift apart the first time only one of them is edited. — JPPhotoManagerWeb/frontend/src/app/features/gallery/gallery.component.ts:294
- JPPhotoManagerWeb/frontend/src/app/features/profile/sessions/sessions.component.ts:46 · JPPhotoManagerWeb/frontend/src/app/features/profile/sessions/sessions.component.ts:69 — all 2 copies are in the same file, and the CITED SPAN is not a self-contained block — it runs from inside one construct into the next (the tail of a branch plus the head of the following one, a run of switch arms, the end of a declaration plus the list that follows it) rather than covering a whole unit. So do not lift these lines literally: no call can be substituted for a half-open construct. Extract the enclosing repeated UNIT instead — the whole function, component or branch these lines sit in — and where the repetition IS the construct (a run of switch arms, a stack of near-identical declarations) replace it with one table or registry looked up by key rather than a helper each arm calls. The copies still drift apart the first time only one of them is edited, which is why this is reported. — JPPhotoManagerWeb/frontend/src/app/features/profile/sessions/sessions.component.ts:46
- JPPhotoManagerWeb/frontend/scripts/bundle-size-report.js:59 · JPPhotoManagerWeb/frontend/scripts/cyclomatic-complexity.js:22 — the 2 copies are spread across 2 files, and the CITED SPAN is not a self-contained block — it runs from inside one construct into the next (the tail of a branch plus the head of the following one, a run of switch arms, the end of a declaration plus the list that follows it) rather than covering a whole unit. So do not lift these lines literally: no call can be substituted for a half-open construct. Extract the enclosing repeated UNIT instead — the whole function, component or branch these lines sit in — and where the repetition IS the construct (a run of switch arms, a stack of near-identical declarations) replace it with one table or registry looked up by key rather than a helper each arm calls. The copies still drift apart the first time only one of them is edited, which is why this is reported. — JPPhotoManagerWeb/frontend/scripts/bundle-size-report.js:59
- JPPhotoManagerWeb/frontend/src/app/core/services/album.service.ts:22 · JPPhotoManagerWeb/frontend/src/app/core/services/asset.service.ts:116 — the 2 copies are spread across 2 files, and the CITED SPAN is not a self-contained block — it runs from inside one construct into the next (the tail of a branch plus the head of the following one, a run of switch arms, the end of a declaration plus the list that follows it) rather than covering a whole unit. So do not lift these lines literally: no call can be substituted for a half-open construct. Extract the enclosing repeated UNIT instead — the whole function, component or branch these lines sit in — and where the repetition IS the construct (a run of switch arms, a stack of near-identical declarations) replace it with one table or registry looked up by key rather than a helper each arm calls. The copies still drift apart the first time only one of them is edited, which is why this is reported. — JPPhotoManagerWeb/frontend/src/app/core/services/album.service.ts:22
- JPPhotoManagerWeb/frontend/src/app/features/gallery/gallery.component.ts:303 · JPPhotoManagerWeb/frontend/src/app/features/gallery/gallery.component.ts:370 — all 2 copies are in the same file, and the CITED SPAN is not a self-contained block — it runs from inside one construct into the next (the tail of a branch plus the head of the following one, a run of switch arms, the end of a declaration plus the list that follows it) rather than covering a whole unit. So do not lift these lines literally: no call can be substituted for a half-open construct. Extract the enclosing repeated UNIT instead — the whole function, component or branch these lines sit in — and where the repetition IS the construct (a run of switch arms, a stack of near-identical declarations) replace it with one table or registry looked up by key rather than a helper each arm calls. The copies still drift apart the first time only one of them is edited, which is why this is reported. — JPPhotoManagerWeb/frontend/src/app/features/gallery/gallery.component.ts:303
- JPPhotoManagerWeb/frontend/scripts/bundle-size-report.js:24 · JPPhotoManagerWeb/frontend/scripts/lighthouse-report.mjs:111 — the 2 copies are spread across 2 files, and the SHAPE of this repetition could not be determined. It is not a run of declarations, a listing, a declaration header, a type body or a slice through a construct — and it was not measured as a run of executable statements either, so this row cannot tell you whether a function can stand where these lines are. Read the two spans before acting, because the move is opposite in the two cases. Where they are statements, the ordinary answer holds: give the shared part one home and call it from each site. Where they turn out to be declarations, a literal's entries, or the cases of an enumeration, there is no call site to call anything from, and collapsing them would delete what each copy pins — a shared base type, a generated set, or one exported constant each site refers to is the move instead, and sometimes the honest answer is that there is nothing to extract at all. Reported because the copies drift apart the first time only one of them is edited, which is true whichever of those they are. — JPPhotoManagerWeb/frontend/scripts/bundle-size-report.js:24
What to do
- Act on each finding's own remediation rather than one rule: the move depends on what recurs. Where the copies are executable blocks, give the shared part one home and call it from each site; where they are declarations, a listing, a specialisation already delegating to its base, or one shape repeated per entity, there is no call site and the move is a shared type, a generated set or a factory — sometimes there is nothing to extract.
R2 · Cyclomatic Complexity
- getHitArea has cyclomatic complexity 21 and cognitive complexity 10; this row is raised above a cyclomatic bar of 10. The two numbers answer different questions and the gap between them is what decides whether to act: cyclomatic counts the independent arms through the body, cognitive counts what it costs to hold them in your head, so nesting and mixed boolean chains raise it while a flat run of independent arms does not. Cognitive sits below cyclomatic here, so much of the count is breadth — arms side by side rather than stacked — and splitting per arm would leave a function per arm; group the work between the checks into named steps instead. Measured by this repository's own parse of the file, so a body assembled at runtime, or generated, is counted as written rather than as it executes. — JPPhotoManagerWeb/frontend/src/app/features/gallery/social-media-crop/social-media-crop.component.ts:234
- main has cyclomatic complexity 17 and cognitive complexity 39; this row is raised above a cyclomatic bar of 10. The two numbers answer different questions and the gap between them is what decides whether to act: cyclomatic counts the independent arms through the body, cognitive counts what it costs to hold them in your head, so nesting and mixed boolean chains raise it while a flat run of independent arms does not. Cognitive is at or above cyclomatic here, so the branching is nested or entangled rather than laid out side by side — extracting each decision into its own named function is the change that pays. Measured by this repository's own parse of the file, so a body assembled at runtime, or generated, is counted as written rather than as it executes. — JPPhotoManagerWeb/frontend/scripts/a11y-report.js:83
- resizeFromCorner has cyclomatic complexity 13 and cognitive complexity 12; this row is raised above a cyclomatic bar of 10. The two numbers answer different questions and the gap between them is what decides whether to act: cyclomatic counts the independent arms through the body, cognitive counts what it costs to hold them in your head, so nesting and mixed boolean chains raise it while a flat run of independent arms does not. Cognitive sits below cyclomatic here, so much of the count is breadth — arms side by side rather than stacked — and splitting per arm would leave a function per arm; group the work between the checks into named steps instead. Measured by this repository's own parse of the file, so a body assembled at runtime, or generated, is counted as written rather than as it executes. — JPPhotoManagerWeb/frontend/src/app/features/gallery/social-media-crop/social-media-crop.component.ts:190
- functionName has cyclomatic complexity 12 and cognitive complexity 15; this row is raised above a cyclomatic bar of 10. The two numbers answer different questions and the gap between them is what decides whether to act: cyclomatic counts the independent arms through the body, cognitive counts what it costs to hold them in your head, so nesting and mixed boolean chains raise it while a flat run of independent arms does not. Cognitive is at or above cyclomatic here, so the branching is nested or entangled rather than laid out side by side — extracting each decision into its own named function is the change that pays. Measured by this repository's own parse of the file, so a body assembled at runtime, or generated, is counted as written rather than as it executes. — JPPhotoManagerWeb/frontend/scripts/cyclomatic-complexity.js:49
- main has cyclomatic complexity 12 and cognitive complexity 15; this row is raised above a cyclomatic bar of 10. The two numbers answer different questions and the gap between them is what decides whether to act: cyclomatic counts the independent arms through the body, cognitive counts what it costs to hold them in your head, so nesting and mixed boolean chains raise it while a flat run of independent arms does not. Cognitive is at or above cyclomatic here, so the branching is nested or entangled rather than laid out side by side — extracting each decision into its own named function is the change that pays. Measured by this repository's own parse of the file, so a body assembled at runtime, or generated, is counted as written rather than as it executes. — JPPhotoManagerWeb/frontend/scripts/lighthouse-report.mjs:109
- createAlbum has cyclomatic complexity 11 and cognitive complexity 13; this row is raised above a cyclomatic bar of 10. The two numbers answer different questions and the gap between them is what decides whether to act: cyclomatic counts the independent arms through the body, cognitive counts what it costs to hold them in your head, so nesting and mixed boolean chains raise it while a flat run of independent arms does not. Cognitive is at or above cyclomatic here, so the branching is nested or entangled rather than laid out side by side — extracting each decision into its own named function is the change that pays. Measured by this repository's own parse of the file, so a body assembled at runtime, or generated, is counted as written rather than as it executes. — JPPhotoManagerWeb/frontend/src/app/features/albums/albums.component.ts:78
What to do
- Break down the listed branch-heavy functions; aim P95 cyclomatic ≤ 5.
R3 · Large Files
- JPPhotoManagerWeb/frontend/src/app/features/gallery/gallery.component.ts has 907 significant lines (blank lines excluded), over the 400-line bar, and contains logic — a file this long is usually several responsibilities in one module. — JPPhotoManagerWeb/frontend/src/app/features/gallery/gallery.component.ts:1
What to do
- Split each oversized file along the responsibilities already in it, into smaller focused modules in the same package.
R4 · Test Coverage
- No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL — if neither does, no test reaches this one. (×19) — JPPhotoManagerWeb/frontend/scripts/lighthouse-report.mjs:1, JPPhotoManagerWeb/frontend/scripts/mutation-report.js:1, JPPhotoManagerWeb/frontend/scripts/a11y-report.js:1, …
What to do
- Add tests that import the unreached modules (directly or through their public entry).
R5 · Dependency Freshness
- 38 outdated package(s); JS/npm CVEs scored in D30
What to do
- Bump outdated dependencies to current versions to limit upgrade debt.
R6 · Tooling
R7 · Dead Code
- Unreachable from the 39 application, 21 tooling and 73 test entry point(s) detected in this repo. Gate removals on `npm run build` — an undetected custom entry would make these reachable.
- no import path from any entry point (39 application, 21 tooling, 73 test roots considered), and no other file in the scanned tree imports it — nothing in-repo names this module at all, which is the strongest form of this claim the import graph can make (×2) — JPPhotoManagerWeb/frontend/src/app/core/models/audio-metadata.model.ts, JPPhotoManagerWeb/frontend/src/app/core/models/tag.model.ts
- Nothing imports this binding — it is safe to review for removal. (×3) — JPPhotoManagerWeb/frontend/src/app/core/models/album.model.ts:41, JPPhotoManagerWeb/frontend/src/app/core/models/analytics.model.ts:33, JPPhotoManagerWeb/frontend/src/app/core/models/asset.model.ts:40
What to do
- Delete the dead files and unused exports — every line is maintenance cost and rebuild-estimate inflation with zero runtime value.
R8 · Dependency Hygiene
R9 · Circular Imports
X1 · Async correctness
X12 · Unreachable branch
X13 · Undrained process stream
X14 · Bypassable address classification
X15 · Unvalidated length from an untrusted reader
X16 · Unfloored truncation loop
X17 · Uncapped recursion over a caller-supplied document
X18 · Disposal-pattern correctness
X19 · Unrestored process-global state
X2 · Cancellation propagation
- Only 0/21 async methods accept a CancellationToken, so in-flight work can't be stopped early when the caller gives up — whatever ends it in your host (shutdown signal, timeout, abandoned request, user cancel). Thread a token through the call chain and honour it at each await and loop; where a method genuinely cannot be interrupted, omitting it is a deliberate choice — judge against your hosting model.
- No CancellationToken parameter — this work can't be stopped early once started. (×21) — JPPhotoManager/JPPhotoManager.Domain/Services/CatalogAssetsService.cs:40, JPPhotoManager/JPPhotoManager.Domain/Services/ConvertAssetsService.cs:30, JPPhotoManager/JPPhotoManager.Domain/Services/NewReleaseNotificationService.cs:21, …
What to do
- Thread a CancellationToken through async methods so work stops promptly on cancellation.
X20 · Mistyped argument guard
- The guard on line 32 rejects `assets` and line 34 reports that rejection as `ArgumentNullException` — but the condition's own test `assets.Length == 0` is true of a value that is NOT null: it is satisfied by an EMPTY `assets`, and on that path `assets` was already proven non-null by the very expression that decided it (`||` short-circuits, so the null test to its left had to be false to get here). So a caller who passes a valid empty argument is told a parameter was null. That is not a wording problem: the exception type is the contract. A caller catching `ArgumentNullException` to handle a real null swallows the empty case with it, and whoever reads the stack trace later is told a failure the source disproves. .NET separates the two on purpose — `ArgumentNullException.ThrowIfNull` and `ArgumentException.ThrowIfNullOrEmpty` are two helpers because they are two failures. Throw `ArgumentException` for the empty case, or split the guard and throw each on its own condition. — JPPhotoManager/JPPhotoManager.Domain/Services/MoveAssetsService.cs:34
- The guard on line 129 rejects `assets` and line 131 reports that rejection as `ArgumentNullException` — but the condition's own test `assets.Length == 0` is true of a value that is NOT null: it is satisfied by an EMPTY `assets`, and on that path `assets` was already proven non-null by the very expression that decided it (`||` short-circuits, so the null test to its left had to be false to get here). So a caller who passes a valid empty argument is told a parameter was null. That is not a wording problem: the exception type is the contract. A caller catching `ArgumentNullException` to handle a real null swallows the empty case with it, and whoever reads the stack trace later is told a failure the source disproves. .NET separates the two on purpose — `ArgumentNullException.ThrowIfNull` and `ArgumentException.ThrowIfNullOrEmpty` are two helpers because they are two failures. Throw `ArgumentException` for the empty case, or split the guard and throw each on its own condition. — JPPhotoManager/JPPhotoManager.Domain/Services/MoveAssetsService.cs:131
What to do
- Each finding names the throw and the test in its own condition that is true of a NON-null value. Confirm from the two, then throw the exception that describes what was actually wrong: `ArgumentException` for a value that arrived empty, or the .NET 8 helpers that spell the whole guard in one line and pick the type for you — `ArgumentException.ThrowIfNullOrEmpty(s)` / `ThrowIfNullOrWhiteSpace(s)` for strings, `ArgumentNullException.ThrowIfNull(x)` followed by `ArgumentOutOfRangeException.ThrowIfZero(x.Count)` for a collection. Splitting the two conditions is usually clearer than picking one exception for both: they are different failures and the caller may want to handle them differently.
X21 · Side-effecting pattern guard
X22 · Contradicted release guard
X23 · Unguarded diagnostic materialisation
X24 · Document value interpolated into markup unescaped
X25 · Inert configuration knob
X26 · Unsynchronised callback handoff
X27 · Collection changed while being enumerated
X28 · Index access outside its own emptiness guard
X29 · Per-element action decided by a fixed element
X3 · Exception handling
X30 · Support guard that admits what it rejects
X32 · Type resolved by simple name across every loaded assembly
X4 · Structured logging
X5 · Nullable reference types
- 4/5 NRT-eligible project(s) enable <Nullable>enable</Nullable> (projects targeting a pre-C#-8 framework are excluded — NRTs aren't available there). NRTs catch a whole class of null-deref bugs at compile time.
What to do
- Enable <Nullable>enable</Nullable> across all projects and resolve warnings rather than suppressing with `!`.
Reference — by lens
| Lens | Score | Rating | Impact |
|---|---|---|---|
| Code Health | 71% | Strong | Solid. |
| Architecture | 83% | Strong | Solid. |
| Maturity | 49% | Weak — gated by M4 | Capped at Fair by a Critical contributor — resolve it before relying on this lens. |
| Readiness | 64% | Adequate — gated by P3 | Capped at Fair by a Critical contributor — resolve it before relying on this lens. |
| Security | 51% | Adequate — gated by D29, D30, D31, D36 | Capped at Fair by a Critical contributor — resolve it before relying on this lens. |
| Domain Modelling | 88% | Strong | Strongest area. |
| Performance | 60% | Adequate | Acceptable, with room to improve. |
Unscored — 3 check(s) recorded observations but carry no score
- SC1 Supply-chain hygiene — 1 observation(s) recorded · Advisory — this card reports evidence and never carries a score, so there is nothing missing here.
- X10 Duplicated predicate — 2 observation(s) recorded · Advisory — this card reports evidence and never carries a score.
- X7 Silent fallback defaults — 1 observation(s) recorded · Advisory — this card reports evidence and never carries a score.
Not included — 47 check(s) not relevant to this codebase
- AC1 Text alternatives — No user-facing web UI (the repo is a library/CLI/worker/headless service) — accessibility is not applicable.
- AC2 Forms & labels — No user-facing web UI (the repo is a library/CLI/worker/headless service) — accessibility is not applicable.
- AC3 Page structure — No user-facing web UI (the repo is a library/CLI/worker/headless service) — accessibility is not applicable.
- AC4 Keyboard semantics — No user-facing web UI (the repo is a library/CLI/worker/headless service) — accessibility is not applicable.
- AC5 ARIA correctness — No user-facing web UI (the repo is a library/CLI/worker/headless service) — accessibility is not applicable.
- AC6 Visual & motion safety — No user-facing web UI (the repo is a library/CLI/worker/headless service) — accessibility is not applicable.
- AC7 A11y enforcement — No user-facing web UI (the repo is a library/CLI/worker/headless service) — accessibility is not applicable.
- AX7 Slice cohesion — not applicable — not a vertical-slice architecture
- AX9 CQS / query purity — no CQRS query handlers detected — query purity is not applicable to this codebase
- AXB2 Runtime readiness — Advisory — this card reports evidence and never carries a score, so there is nothing missing here.
- AXR1 Runtime accessibility — compose up failed (exit 15 — the compose project is invalid) — error while interpolating services.backend.environment.JWT_SECRET: required variable JWT_SECRET is missing a value: Set JWT_SECRET in .env - run: openssl rand -base64 32; runtime evidence skipped This is a statement about this run, not a statement about your application: nothing here says the surface is inaccessible, only that it was never rendered.
- C1 Data Protection — No personal data detected in the analyzed source — no PII-typed entity/column names (Email, FirstName, DateOfBirth, …), no ASP.NET Identity / user-account model, and no stored user credentials. GDPR data-protection controls are therefore N/A here. If this is intentional, record the no-PII posture in an ADR; if the app does process personal data, name those fields conventionally so this dimension activates.
- C2 Access Controls — No access-control surface detected in the analyzed source — no web/app surface to authorize (no HTTP API or web-UI project) and no authorization code at all (no [Authorize]/policies, no imperative guard methods). Access control is therefore N/A here — this is a library/CLI, which is authorized by its CALLER, not by itself. If this codebase grows request handlers, the dimension reactivates and a default-deny posture is expected then.
- C3 Audit Trail — No personal data detected in the analyzed source — no PII-typed entity/column names (Email, FirstName, DateOfBirth, …), no ASP.NET Identity / user-account model, and no stored user credentials. GDPR data-protection controls are therefore N/A here. If this is intentional, record the no-PII posture in an ADR; if the app does process personal data, name those fields conventionally so this dimension activates.
- C4 Data Retention — No personal data detected in the analyzed source — no PII-typed entity/column names (Email, FirstName, DateOfBirth, …), no ASP.NET Identity / user-account model, and no stored user credentials. GDPR data-protection controls are therefore N/A here. If this is intentional, record the no-PII posture in an ADR; if the app does process personal data, name those fields conventionally so this dimension activates.
- C5 Data-Subject Rights — No personal data detected in the analyzed source — no PII-typed entity/column names (Email, FirstName, DateOfBirth, …), no ASP.NET Identity / user-account model, and no stored user credentials. GDPR data-protection controls are therefore N/A here. If this is intentional, record the no-PII posture in an ADR; if the app does process personal data, name those fields conventionally so this dimension activates.
- D11 Test Reliability — Test reliability not measured — polyglot suite, one half not re-run
- D12 Dependency Hygiene — Dependency hygiene not measured
- D16 Bus Factor — bus factor 1 — one contributor carries this repository
- D18 Solution Shape — D18 scores the shape of a C#/VB .NET solution, but this repository's production source is mostly .java, .ts, which the C#/VB workspace does not load — the projects that loaded are an immaterial minority, so solution shape was not assessed for this repository. Not scored — this is a gap in the analyzer's reach, not a verdict about this repository.
- D22 Internal API Consistency — No intentionally-exposed public API to evaluate for consistency.
- D23 Boundary Type-Coupling — Cross-context type coupling could not be assessed — this codebase's bounded contexts are neither declared nor inferable.
- D25 ADR Conformance — no ADRs to check
- D27 Navigability — D27 counts a call into the standard library or a dependency as unresolved for this repository's language (.java), so too few call sites counted as resolved to assess navigability. Not scored: this is a gap in the analyzer, not a verdict about this repository.
- D32 Data Compliance (PII/GDPR) — No personal data was found crossing a boundary the PII/GDPR ruleset checks — nothing written to a log or console sink, placed in a URL or query string, or persisted to browser storage. That is a clean result for the LEAK surface only: this ruleset detects personal data escaping, it does not inventory the personal data a repository holds, so it is not evidence that this repository has no personal-data surface. The personal-data map (Appendix C) and the C1-C5 compliance cards are what speak to that.
- D34 Knowledge Freshness — knowledge concentrated in recent work — freshness signal contradicted by repo activity
- D37 Vulnerability-disclosure Policy — No vulnerability-disclosure policy file found (SECURITY.md/.markdown/.rst/.txt at root or under .github/.forgejo/.gitea/docs, .well-known/security.txt). A coordinated-disclosure policy may live off-repo, so this is not evidenced rather than failed.
- D39 IL Efficiency — IL not measured — the analyzer's build of the target did not succeed
- D42 Runtime Threat Enforcement — The repository ships application workloads but no cluster-governance resources (CRDs, admission webhooks, or a committed policy engine). Runtime threat-detection (Falco/Tetragon) and admission control (Kyverno/OPA-Gatekeeper/PodSecurity) are cluster-OPERATOR controls owned by the platform, not shipped by an application repo/chart — nothing for this repo to assess.
- D7 Architectural Integrity — no checkable ADRs and no dependency cycles — architectural integrity not assessed
- D8 Code Coverage — Coverage not measured — .NET and JavaScript/TypeScript suite
- DM1 Aggregate boundaries — no aggregates detected — aggregate-boundary check not applicable
- DM2 Strongly-typed ids — no id-bearing domain types detected — strongly-typed-id adoption not assessable
- DM3 Integration-event coupling — no integration events detected — coupling check not applicable
- DM4 Rich vs anemic model — no data-bearing entities detected — rich-vs-anemic model not assessable
- ED1 Event-Driven — not scored — this repository shows only 1 of the 3 signals this lens looks for (2 event handler(s))
- ED5 Idempotency — Not assessed, and this one is on us: 2 command handler(s) or message consumer(s) were found here, but this check does not yet recognise persistence writes in this repository's language. Idempotency was neither confirmed nor ruled out — this is a limit of the analyzer, not a finding about your code.
- ES1 Event Sourcing — not scored — this repository shows only 1 of the 3 signals this lens looks for (an Axon event-sourcing framework (@Aggregate/@CommandHandler/@EventSourcingHandler annotations))
- P12 CI test-gate honesty — Reported, not scored — this card publishes what the CI gate does with the test inventory rather than grading it. The findings above are its output.
- P7 Outbound HTTP resilience — not applicable — this isn't a service/API/worker
- P9 Domain vs controller coverage — no coverage report found on disk — produce a coverage report in a standard format (JaCoCo XML — `mvn jacoco:report` or the Gradle `jacocoTestReport` task) and commit it — a hosted scan measures a clone of the repository, so a report that exists only in a working tree, a CI runner's or your own, never reaches it; the artefact is commonly gitignored, so `git add -f` that one file (or un-ignore its path) and commit it alongside the code it measures, or wire coverage collection into CI, to enable this cross-layer check
- PF1 Benchmark discipline — Performance is assessed only for perf-relevant repos — a packaged library, one that ships benchmarks, or one already using allocation-aware APIs. This repo isn't one, so the Performance lens is not applicable and is excluded from the score.
- PF2 Allocation hygiene — Performance is assessed only for perf-relevant repos — a packaged library, one that ships benchmarks, or one already using allocation-aware APIs. This repo isn't one, so the Performance lens is not applicable and is excluded from the score.
- R11 Import Boundaries — No recognizable feature-sliced/layered src layout — boundary rules not applicable.
- S1 Web-Security Posture — No web surface detected in the analyzed source — no HTTP API or web-UI project (no controllers/minimal-API endpoints, no Razor/Blazor views) and no web middleware (HTTPS redirection, HSTS, security headers, cookies). Transport security, security headers, secure cookies, CSRF/input-validation and middleware-order controls are therefore N/A here — this is a library/CLI/worker, not a web app. Crypto hygiene was still checked and found nothing to flag. If this codebase becomes web-facing, the dimension reactivates automatically.
- X6 Hand-rolled structured-format parsing — Advisory — this card reports evidence and never carries a score, so there is nothing missing here.
- X9 Subsumed condition operand — Advisory — this card reports evidence and never carries a score, so there is nothing missing here.
Appendix A — Findings (grouped)
Critical — 84 finding(s)
- REDACTED
- REDACTED
- REDACTED
- REDACTED
- REDACTED
- REDACTED
- REDACTED
- REDACTED
- REDACTED
- REDACTED
- REDACTED
- REDACTED
- REDACTED
- REDACTED
- REDACTED
- REDACTED
- REDACTED
- REDACTED
- REDACTED
- REDACTED
- REDACTED
- REDACTED
- REDACTED
- REDACTED
- REDACTED
- REDACTED
- REDACTED
- REDACTED
- REDACTED
- REDACTED
- REDACTED
- REDACTED
- REDACTED
- REDACTED
- REDACTED
- REDACTED
- REDACTED
- REDACTED
- REDACTED
- REDACTED
- REDACTED
- REDACTED
- REDACTED
- REDACTED
- REDACTED
- REDACTED
- REDACTED
- REDACTED
- REDACTED
- REDACTED
- REDACTED
- REDACTED
- REDACTED
- REDACTED
- REDACTED
- REDACTED
- Domain depends on infrastructure: Asset JPPhotoManager/JPPhotoManager.Domain/Entities/Asset.cs:14
- Domain depends on infrastructure: Asset JPPhotoManager/JPPhotoManager.Domain/Entities/Asset.cs:28
- Domain depends on infrastructure: Asset JPPhotoManager/JPPhotoManager.Domain/Entities/Asset.cs:31
- Domain depends on infrastructure: ConvertAssetsDirectoriesDefinition JPPhotoManager/JPPhotoManager.Domain/Entities/ConvertAssetsDirectoriesDefinition.cs:11
- Domain depends on infrastructure: Folder JPPhotoManager/JPPhotoManager.Domain/Entities/Folder.cs:8
- Domain depends on infrastructure: Folder JPPhotoManager/JPPhotoManager.Domain/Entities/Folder.cs:12
- Domain depends on infrastructure: Folder JPPhotoManager/JPPhotoManager.Domain/Entities/Folder.cs:24
- Domain depends on infrastructure: RecentTargetPath JPPhotoManager/JPPhotoManager.Domain/Entities/RecentTargetPath.cs:7
- Domain depends on infrastructure: SyncAssetsDirectoriesDefinition JPPhotoManager/JPPhotoManager.Domain/Entities/SyncAssetsDirectoriesDefinition.cs:11
- Captive dependency: singleton FolderRepository captures scoped AppDbContext JPPhotoManager/JPPhotoManager.Infrastructure/Repositories/FolderRepository.cs:11
- Captive dependency: singleton AssetRepository captures scoped AppDbContext JPPhotoManager/JPPhotoManager.Infrastructure/Repositories/AssetRepository.cs:28
- Captive dependency: singleton RecentTargetPathRepository captures scoped AppDbContext JPPhotoManager/JPPhotoManager.Infrastructure/Repositories/RecentTargetPathRepository.cs:11
- Captive dependency: singleton SyncAssetsConfigurationRepository captures scoped AppDbContext JPPhotoManager/JPPhotoManager.Infrastructure/Repositories/SyncAssetsConfigurationRepository.cs:11
- Captive dependency: singleton ConvertAssetsConfigurationRepository captures scoped AppDbContext JPPhotoManager/JPPhotoManager.Infrastructure/Repositories/ConvertAssetsConfigurationRepository.cs:11
- WriteOnlyPrivateField JPPhotoManager/JPPhotoManager.Domain/Services/CatalogAssetsService.cs:22
- WriteOnlyPrivateField JPPhotoManager/JPPhotoManager.Domain/Services/ConvertAssetsService.cs:10
- WriteOnlyPrivateField JPPhotoManager/JPPhotoManager.Domain/Services/SyncAssetsService.cs:9
- WriteOnlyPrivateField JPPhotoManager/JPPhotoManager.Domain/Services/ConvertAssetsService.cs:14
- WriteOnlyPrivateField JPPhotoManager/JPPhotoManager.UI/ViewModels/FindDuplicatedAssetsViewModel.cs:13
- REDACTED
- REDACTED
- REDACTED
- Namespace dependency cycle JPPhotoManager/JPPhotoManager.Domain/Entities/Asset.cs:1
- Namespace dependency cycle JPPhotoManager/JPPhotoManager.UI/Controls/ThumbnailsUserControl.xaml.cs:6
- REDACTED
- REDACTED
- REDACTED
- REDACTED
Serious — 431 finding(s)
- REDACTED
- REDACTED
- REDACTED
- REDACTED
- REDACTED
- REDACTED
- REDACTED
- REDACTED
- REDACTED
- REDACTED
- REDACTED
- REDACTED
- REDACTED
- REDACTED
- REDACTED
- REDACTED
- REDACTED
- REDACTED
- REDACTED
- REDACTED
- REDACTED
- REDACTED
- REDACTED
- REDACTED
- REDACTED
- Async method without CancellationToken: CatalogAssetsAsync JPPhotoManager/JPPhotoManager.Domain/Services/CatalogAssetsService.cs:40
- Async method without CancellationToken: ExecuteAsync JPPhotoManager/JPPhotoManager.Domain/Services/ConvertAssetsService.cs:30
- Async method without CancellationToken: CheckNewReleaseAsync JPPhotoManager/JPPhotoManager.Domain/Services/NewReleaseNotificationService.cs:21
- Async method without CancellationToken: ExecuteAsync JPPhotoManager/JPPhotoManager.Domain/Services/SyncAssetsService.cs:26
- Async method without CancellationToken: SyncAssetsAsync JPPhotoManager/JPPhotoManager.Application/Application.cs:122
- Async method without CancellationToken: ConvertAssetsAsync JPPhotoManager/JPPhotoManager.Application/Application.cs:136
- Async method without CancellationToken: CatalogAssetsAsync JPPhotoManager/JPPhotoManager.Application/Application.cs:138
- Async method without CancellationToken: CheckNewReleaseAsyc JPPhotoManager/JPPhotoManager.Application/Application.cs:195
- Async method without CancellationToken: GoToFolder JPPhotoManager/JPPhotoManager.UI/Controls/ThumbnailsUserControl.xaml.cs:44
- Async method without CancellationToken: LoadAssetsWithPagination JPPhotoManager/JPPhotoManager.UI/Controls/ThumbnailsUserControl.xaml.cs:64
- Async method without CancellationToken: GetAssets JPPhotoManager/JPPhotoManager.UI/Controls/ThumbnailsUserControl.xaml.cs:96
- Async method without CancellationToken: CatalogAssets JPPhotoManager/JPPhotoManager.UI/ViewModels/ApplicationViewModel.cs:540
- Async method without CancellationToken: RunProcessAsync JPPhotoManager/JPPhotoManager.UI/ViewModels/ConvertAssetsViewModel.cs:61
- Async method without CancellationToken: RunProcessAsync JPPhotoManager/JPPhotoManager.UI/ViewModels/SyncAssetsViewModel.cs:61
- Async method without CancellationToken: RunButton_MouseLeftButtonDown JPPhotoManager/JPPhotoManager.UI/Windows/ConvertAssetsWindow.xaml.cs:124
- Async method without CancellationToken: RunProcess JPPhotoManager/JPPhotoManager.UI/Windows/ConvertAssetsWindow.xaml.cs:188
- Async method without CancellationToken: Window_Loaded JPPhotoManager/JPPhotoManager.UI/Windows/MainWindow.xaml.cs:59
- Async method without CancellationToken: DoBackgroundWork JPPhotoManager/JPPhotoManager.UI/Windows/MainWindow.xaml.cs:474
- Async method without CancellationToken: CheckNewRelease JPPhotoManager/JPPhotoManager.UI/Windows/MainWindow.xaml.cs:495
- Async method without CancellationToken: RunButton_MouseLeftButtonDown JPPhotoManager/JPPhotoManager.UI/Windows/SyncAssetsWindow.xaml.cs:124
- Async method without CancellationToken: RunProcess JPPhotoManager/JPPhotoManager.UI/Windows/SyncAssetsWindow.xaml.cs:188
- TodoComment JPPhotoManager/JPPhotoManager.Common/BitmapHelper.cs:47
- TodoComment JPPhotoManager/JPPhotoManager.Domain/Services/CatalogAssetsService.cs:51
- TodoComment JPPhotoManager/JPPhotoManager.Domain/Services/CatalogAssetsService.cs:183
- TodoComment JPPhotoManager/JPPhotoManager.Domain/Services/ConvertAssetsService.cs:89
- TodoComment JPPhotoManager/JPPhotoManager.Domain/Services/MoveAssetsService.cs:61
- TodoComment JPPhotoManager/JPPhotoManager.Domain/Services/MoveAssetsService.cs:77
- TodoComment JPPhotoManager/JPPhotoManager.Domain/Services/MoveAssetsService.cs:111
- TodoComment JPPhotoManager/JPPhotoManager.Domain/Services/SyncAssetsService.cs:91
- TodoComment JPPhotoManager/JPPhotoManager.Infrastructure/Services/UserConfigurationService.cs:204
- TodoComment JPPhotoManager/JPPhotoManager.UI/App.xaml.cs:29
- TodoComment JPPhotoManager/JPPhotoManager.UI/Controls/FolderNavigationControl.xaml.cs:190
- TodoComment JPPhotoManager/JPPhotoManager.UI/Controls/FolderNavigationControl.xaml.cs:200
- TodoComment JPPhotoManager/JPPhotoManager.UI/Controls/FolderNavigationControl.xaml.cs:204
- TodoComment JPPhotoManager/JPPhotoManager.UI/Controls/FolderNavigationControl.xaml.cs:241
- TodoComment JPPhotoManager/JPPhotoManager.UI/ViewModels/FindDuplicatedAssetsViewModel.cs:141
- TodoComment JPPhotoManager/JPPhotoManager.UI/ViewModels/FindDuplicatedAssetsViewModel.cs:176
- TodoComment JPPhotoManager/JPPhotoManager.UI/Windows/FindDuplicatedAssetsWindow.xaml.cs:47
- TodoComment JPPhotoManager/JPPhotoManager.UI/Windows/FindDuplicatedAssetsWindow.xaml.cs:49
- TodoComment JPPhotoManager/JPPhotoManager.UI/Windows/FolderNavigationWindow.xaml.cs:70
- No test reaches this file JPPhotoManagerWeb/frontend/scripts/lighthouse-report.mjs:1
- No test reaches this file JPPhotoManagerWeb/frontend/scripts/mutation-report.js:1
- No test reaches this file JPPhotoManagerWeb/frontend/scripts/a11y-report.js:1
- No test reaches this file JPPhotoManagerWeb/frontend/scripts/cyclomatic-complexity.js:1
- No test reaches this file JPPhotoManagerWeb/frontend/scripts/dead-code-report.js:1
- No test reaches this file JPPhotoManagerWeb/frontend/scripts/bundle-size-report.js:1
- No test reaches this file JPPhotoManagerWeb/frontend/scripts/route-coverage-report.js:1
- No test reaches this file JPPhotoManagerWeb/frontend/scripts/code-coverage-report.js:1
- No test reaches this file JPPhotoManagerWeb/frontend/scripts/dependency-staleness-report.js:1
- No test reaches this file JPPhotoManagerWeb/frontend/scripts/secrets-scan-report.js:1
- No test reaches this file JPPhotoManagerWeb/frontend/scripts/e2e-run-report.js:1
- No test reaches this file JPPhotoManagerWeb/frontend/scripts/sca-report.js:1
- No test reaches this file JPPhotoManagerWeb/frontend/scripts/license-compliance-report.js:1
- No test reaches this file JPPhotoManagerWeb/frontend/scripts/type-coverage-report.js:1
- No test reaches this file JPPhotoManagerWeb/frontend/scripts/run-all-quality-reports.js:1
- No test reaches this file JPPhotoManagerWeb/frontend/scripts/complexity-report.js:1
- No test reaches this file JPPhotoManagerWeb/frontend/src/app/app.routes.ts:1
- No test reaches this file JPPhotoManagerWeb/frontend/src/app/core/guards/auth.guard.ts:1
- No test reaches this file JPPhotoManagerWeb/frontend/src/main.ts:1
- CoverageExclusion JPPhotoManager/JPPhotoManager.UI/App.xaml.cs:24
- CoverageExclusion JPPhotoManager/JPPhotoManager.UI/Controls/FolderNavigationControl.xaml.cs:17
- CoverageExclusion JPPhotoManager/JPPhotoManager.UI/Controls/ThumbnailsUserControl.xaml.cs:21
- CoverageExclusion JPPhotoManager/JPPhotoManager.UI/Controls/ViewerUserControl.xaml.cs:17
- CoverageExclusion JPPhotoManager/JPPhotoManager.UI/Windows/AboutWindow.xaml.cs:13
- CoverageExclusion JPPhotoManager/JPPhotoManager.UI/Windows/ConvertAssetsWindow.xaml.cs:17
- CoverageExclusion JPPhotoManager/JPPhotoManager.UI/Windows/FindDuplicatedAssetsWindow.xaml.cs:15
- CoverageExclusion JPPhotoManager/JPPhotoManager.UI/Windows/FolderNavigationWindow.xaml.cs:14
- CoverageExclusion JPPhotoManager/JPPhotoManager.UI/Windows/MainWindow.xaml.cs:29
- CoverageExclusion JPPhotoManager/JPPhotoManager.UI/Windows/SyncAssetsWindow.xaml.cs:17
- REDACTED
- REDACTED
- REDACTED
- REDACTED
- REDACTED
- REDACTED
- REDACTED
- REDACTED
- Duplicated block (9 lines × 2) JPPhotoManagerWeb/backend/src/main/java/com/jpablodrexler/photomanager/application/usecase/album/GetAlbumSummaryUseCaseImpl.java:26
- Duplicated block (9 lines × 2) JPPhotoManagerWeb/backend/src/main/java/com/jpablodrexler/photomanager/application/usecase/convert/ConvertAssetsUseCaseImpl.java:56
- Duplicated block (9 lines × 2) JPPhotoManagerWeb/backend/src/main/java/com/jpablodrexler/photomanager/infrastructure/batch/CatalogAssetItemProcessor.java:139
- Duplicated block (9 lines × 2) JPPhotoManagerWeb/backend/src/main/java/com/jpablodrexler/photomanager/infrastructure/kafka/AssetHashProcessor.java:53
- Duplicated block (9 lines × 2) JPPhotoManager/JPPhotoManager.UI/Windows/ConvertAssetsWindow.xaml.cs:73
- Duplicated block (9 lines × 2) JPPhotoManager/JPPhotoManager.UI/Windows/ConvertAssetsWindow.xaml.cs:85
- Duplicated block (9 lines × 2) JPPhotoManager/JPPhotoManager.UI/Windows/ConvertAssetsWindow.xaml.cs:97
- Duplicated block (9 lines × 2) JPPhotoManagerWeb/backend/src/main/java/com/jpablodrexler/photomanager/application/usecase/convert/SaveConvertConfigUseCaseImpl.java:20
- REDACTED
- REDACTED
- REDACTED
- REDACTED
- REDACTED
- REDACTED
- REDACTED
- Sync-over-async blocking JPPhotoManagerWeb/frontend/scripts/lighthouse-report.mjs:111
- Sync-over-async blocking JPPhotoManagerWeb/frontend/scripts/lighthouse-report.mjs:116
- Sync-over-async blocking JPPhotoManagerWeb/frontend/scripts/lighthouse-report.mjs:119
- Sync-over-async blocking JPPhotoManagerWeb/frontend/scripts/lighthouse-report.mjs:121
- Sync-over-async blocking JPPhotoManagerWeb/frontend/scripts/lighthouse-report.mjs:143
- Sync-over-async blocking JPPhotoManagerWeb/frontend/scripts/lighthouse-report.mjs:184
- Sync-over-async blocking JPPhotoManagerWeb/frontend/scripts/lighthouse-report.mjs:186
- Duplicated block (7 lines × 2) JPPhotoManager/JPPhotoManager.Domain/Services/CatalogAssetsService.cs:354
- Duplicated block (7 lines × 2) JPPhotoManagerWeb/backend/src/main/java/com/jpablodrexler/photomanager/application/usecase/tag/BulkAddTagUseCaseImpl.java:52
- Duplicated block (7 lines × 2) JPPhotoManagerWeb/backend/src/main/java/com/jpablodrexler/photomanager/infrastructure/batch/CatalogAssetItemProcessor.java:102
- Duplicated block (7 lines × 2) JPPhotoManagerWeb/backend/src/main/java/com/jpablodrexler/photomanager/infrastructure/web/controller/ConvertController.java:67
- Duplicated block (7 lines × 2) JPPhotoManagerWeb/backend/src/main/java/com/jpablodrexler/photomanager/infrastructure/web/dto/request/CreateAlbumRequestDto.java:13
- Duplicated block (7 lines × 2) JPPhotoManagerWeb/backend/src/main/java/com/jpablodrexler/photomanager/infrastructure/persistence/adapter/ConvertConfigRepositoryImpl.java:29
- Stateful singleton: CatalogAssetsService JPPhotoManager/JPPhotoManager.Domain/Services/CatalogAssetsService.cs:11
- Stateful singleton: Application JPPhotoManager/JPPhotoManager.Application/Application.cs:10
- Stateful singleton: MainWindow JPPhotoManager/JPPhotoManager.UI/Windows/MainWindow.xaml.cs:29
- Stateful singleton: ApplicationViewModel JPPhotoManager/JPPhotoManager.UI/ViewModels/ApplicationViewModel.cs:27
- Stateful singleton: CatalogAssetItemWriter JPPhotoManagerWeb/backend/src/main/java/com/jpablodrexler/photomanager/infrastructure/batch/CatalogAssetItemWriter.java:35
- Duplicated block (5 lines × 2) JPPhotoManagerWeb/backend/src/main/java/com/jpablodrexler/photomanager/infrastructure/web/controller/AuthController.java:84
- Duplicated block (5 lines × 2) JPPhotoManager/JPPhotoManager.Domain/Entities/ConvertAssetsConfiguration.cs:13
- Duplicated block (5 lines × 2) JPPhotoManagerWeb/backend/src/main/java/com/jpablodrexler/photomanager/application/usecase/auth/RevokeSessionUseCaseImpl.java:57
- Duplicated block (5 lines × 2) JPPhotoManagerWeb/backend/src/main/java/com/jpablodrexler/photomanager/application/usecase/album/DeleteAlbumUseCaseImpl.java:20
- Duplicated block (5 lines × 2) JPPhotoManagerWeb/backend/src/main/java/com/jpablodrexler/photomanager/infrastructure/persistence/adapter/AssetRepositoryImpl.java:89
- Dead code: HasSameContent JPPhotoManager/JPPhotoManager.Domain/Interfaces/Services/IStorageService.cs:25
- Dead code: ReadFolders JPPhotoManager/JPPhotoManager.Infrastructure/Repositories/AssetRepository.cs:37
- Dead code: ReadAssets JPPhotoManager/JPPhotoManager.Infrastructure/Repositories/AssetRepository.cs:49
- Dead code: GetFolderById JPPhotoManager/JPPhotoManager.Infrastructure/Repositories/FolderRepository.cs:66
- TooManyMethods: GalleryComponent JPPhotoManagerWeb/frontend/src/app/features/gallery/gallery.component.ts:61
- TooManyMethods: AssetRepositoryImpl JPPhotoManagerWeb/backend/src/main/java/com/jpablodrexler/photomanager/infrastructure/persistence/adapter/AssetRepositoryImpl.java:37
- TooManyMethods: MainWindow JPPhotoManager/JPPhotoManager.UI/Windows/MainWindow.xaml.cs
- TooManyMethods: StorageService JPPhotoManager/JPPhotoManager.Infrastructure/Services/StorageService.cs
- REDACTED
- REDACTED
- REDACTED
- REDACTED
- Duplicated block (11 lines × 2) JPPhotoManager/JPPhotoManager.Domain/Entities/ConvertAssetsDirectoriesDefinition.cs:8
- Duplicated block (11 lines × 2) JPPhotoManagerWeb/backend/src/main/java/com/jpablodrexler/photomanager/application/usecase/tag/AddTagToAssetUseCaseImpl.java:61
- Duplicated block (11 lines × 2) JPPhotoManagerWeb/backend/src/main/java/com/jpablodrexler/photomanager/application/usecase/tag/BulkRemoveTagUseCaseImpl.java:77
- Duplicated block (11 lines × 2) JPPhotoManagerWeb/backend/src/main/java/com/jpablodrexler/photomanager/infrastructure/service/M3uPlaylistParserServiceAdapter.java:39
- Duplicated block (11 lines × 2 locations) JPPhotoManagerWeb/frontend/src/app/core/services/album.service.ts:6
- Duplicated block (11 lines × 2 locations) JPPhotoManagerWeb/frontend/src/app/features/gallery/gallery.component.ts:238
- Duplicated block (11 lines × 2 locations) JPPhotoManagerWeb/frontend/src/app/features/gallery/gallery.component.ts:441
- Duplicated block (11 lines × 2 locations) JPPhotoManagerWeb/frontend/src/app/features/gallery/gallery.component.ts:949
- Duplicated block (7 lines × 2 locations) JPPhotoManagerWeb/frontend/scripts/complexity-report.js:69
- Duplicated block (7 lines × 2 locations) JPPhotoManagerWeb/frontend/scripts/dependency-staleness-report.js:100
- Duplicated block (7 lines × 2 locations) JPPhotoManagerWeb/frontend/src/app/features/gallery/gallery.component.ts:294
- Duplicated block (7 lines × 2 locations) JPPhotoManagerWeb/frontend/src/app/features/profile/sessions/sessions.component.ts:46
- Repeated repair: JPPhotoManagerWeb/backend/src/main/java/com/jpablodrexler/photomanager/application/usecase/asset/MoveAssetsUseCaseImpl.java JPPhotoManagerWeb/backend/src/main/java/com/jpablodrexler/photomanager/application/usecase/asset/MoveAssetsUseCaseImpl.java:45
- Repeated repair: JPPhotoManagerWeb/backend/src/main/java/com/jpablodrexler/photomanager/application/usecase/recycle/PurgeAssetsUseCaseImpl.java JPPhotoManagerWeb/backend/src/main/java/com/jpablodrexler/photomanager/application/usecase/recycle/PurgeAssetsUseCaseImpl.java:31
- Repeated repair: JPPhotoManagerWeb/backend/src/main/java/com/jpablodrexler/photomanager/application/usecase/asset/RenameAssetsUseCaseImpl.java JPPhotoManagerWeb/backend/src/main/java/com/jpablodrexler/photomanager/application/usecase/asset/RenameAssetsUseCaseImpl.java:145
- Low cohesion: StorageServiceAdapter (LCOM4 11) JPPhotoManagerWeb/backend/src/main/java/com/jpablodrexler/photomanager/infrastructure/service/StorageServiceAdapter.java:46
- Low cohesion: AppConfig (LCOM4 7) JPPhotoManagerWeb/backend/src/main/java/com/jpablodrexler/photomanager/config/AppConfig.java:56
- Low cohesion: AssetController (LCOM4 7) JPPhotoManagerWeb/backend/src/main/java/com/jpablodrexler/photomanager/infrastructure/web/controller/AssetController.java:83
- Unfinished stub — throws NotImplementedException JPPhotoManager/JPPhotoManager.UI/Converters/FileSizeConverter.cs:56
- Unfinished stub — throws NotImplementedException JPPhotoManager/JPPhotoManager.UI/Converters/PixelSizeConverter.cs:22
- Unfinished stub — throws NotImplementedException JPPhotoManager/JPPhotoManager.UI/Converters/VisibilityConverter.cs:15
- Duplicated block (10 lines × 3 locations) JPPhotoManagerWeb/frontend/scripts/license-compliance-report.js:95
- Duplicated block (10 lines × 3 locations) JPPhotoManagerWeb/frontend/src/app/features/albums/albums.component.ts:53
- Duplicated block (10 lines × 3 locations) JPPhotoManagerWeb/frontend/src/app/features/audio-player/audio-player.component.ts:17
- Duplicated block (6 lines × 2 locations) JPPhotoManagerWeb/frontend/scripts/bundle-size-report.js:59
- Duplicated block (6 lines × 2 locations) JPPhotoManagerWeb/frontend/src/app/core/services/album.service.ts:22
- Duplicated block (6 lines × 2 locations) JPPhotoManagerWeb/frontend/src/app/features/gallery/gallery.component.ts:303
- REDACTED
- REDACTED
- Duplicated block (10 lines × 2) JPPhotoManager/JPPhotoManager.Domain/Entities/ConvertAssetsDirectoriesDefinition.cs:40
- Duplicated block (10 lines × 2) JPPhotoManager/JPPhotoManager.UI/ViewModels/ApplicationViewModel.cs:453
- Duplicated block (8 lines × 3) JPPhotoManagerWeb/backend/src/main/java/com/jpablodrexler/photomanager/infrastructure/service/CatalogFolderServiceAdapter.java:74
- Duplicated block (8 lines × 3) JPPhotoManagerWeb/backend/src/main/java/com/jpablodrexler/photomanager/infrastructure/web/controller/AssetController.java:470
- Duplicated block (14 lines × 2) JPPhotoManager/JPPhotoManager.UI/Windows/ConvertAssetsWindow.xaml.cs:56
- Duplicated block (14 lines × 2) JPPhotoManager/JPPhotoManager.UI/Windows/ConvertAssetsWindow.xaml.cs:109
- Duplicated block (16 lines × 2 locations) JPPhotoManagerWeb/frontend/scripts/bundle-size-report.js:122
- Duplicated block (16 lines × 2 locations) JPPhotoManagerWeb/frontend/src/app/features/gallery/bulk-tag-dialog/bulk-tag-dialog.component.ts:89
- Duplicated block (9 lines × 2 locations) JPPhotoManagerWeb/frontend/src/app/features/albums/album-detail/album-detail.component.ts:65
- Duplicated block (9 lines × 2 locations) JPPhotoManagerWeb/frontend/src/app/features/gallery/gallery.component.ts:821
- Argument guard throws the exception its own condition disproves JPPhotoManager/JPPhotoManager.Domain/Services/MoveAssetsService.cs:34
- Argument guard throws the exception its own condition disproves JPPhotoManager/JPPhotoManager.Domain/Services/MoveAssetsService.cs:131
- StorageServiceAdapter.getExifMetadata (cyclomatic 32) JPPhotoManagerWeb/backend/src/main/java/com/jpablodrexler/photomanager/infrastructure/service/StorageServiceAdapter.java:305
- SocialMediaCropComponent.getHitArea (cyclomatic 21) JPPhotoManagerWeb/frontend/src/app/features/gallery/social-media-crop/social-media-crop.component.ts:234
- MoveAssetsService.MoveAssets (cyclomatic 17) JPPhotoManager/JPPhotoManager.Domain/Services/MoveAssetsService.cs:28
- a11y-report.main (cyclomatic 17) JPPhotoManagerWeb/frontend/scripts/a11y-report.js:83
- MainWindow.Window_KeyDown (cyclomatic 16) JPPhotoManager/JPPhotoManager.UI/Windows/MainWindow.xaml.cs:78
- Hotspot: JPPhotoManagerWeb/backend/src/main/java/com/jpablodrexler/photomanager/infrastructure/service/StorageServiceAdapter.java JPPhotoManagerWeb/backend/src/main/java/com/jpablodrexler/photomanager/infrastructure/service/StorageServiceAdapter.java:305
- bus factor 1 — one contributor carries this repository
- a11y-report.main (cognitive 34) JPPhotoManagerWeb/frontend/scripts/a11y-report.js:83
- AssetRepository.GetAssets (cognitive 32) JPPhotoManager/JPPhotoManager.Infrastructure/Repositories/AssetRepository.cs:102
- StorageServiceAdapter.getExifMetadata (cognitive 32) JPPhotoManagerWeb/backend/src/main/java/com/jpablodrexler/photomanager/infrastructure/service/StorageServiceAdapter.java:305
- SyncAssetsService.Execute (cognitive 29) JPPhotoManager/JPPhotoManager.Domain/Services/SyncAssetsService.cs:47
- ConvertAssetsService.Execute (cognitive 27) JPPhotoManager/JPPhotoManager.Domain/Services/ConvertAssetsService.cs:51
- MoveAssetsService.MoveAssets (cognitive 26) JPPhotoManager/JPPhotoManager.Domain/Services/MoveAssetsService.cs:28
- ApplicationViewModel.NotifyCatalogChange (cognitive 17) JPPhotoManager/JPPhotoManager.UI/ViewModels/ApplicationViewModel.cs:446
- MainWindow.MoveAssets (cognitive 17) JPPhotoManager/JPPhotoManager.UI/Windows/MainWindow.xaml.cs:340
- RenameAssetsUseCaseImpl.checkFolderCollisions (cognitive 16) JPPhotoManagerWeb/backend/src/main/java/com/jpablodrexler/photomanager/application/usecase/asset/RenameAssetsUseCaseImpl.java:145
- REDACTED
- ClassTooLong: GalleryComponent JPPhotoManagerWeb/frontend/src/app/features/gallery/gallery.component.ts:61
- FileTooLong: gallery/gallery.component.ts JPPhotoManagerWeb/frontend/src/app/features/gallery/gallery.component.ts
- REDACTED
- Change coupling: AssetController.java ↔ asset.service.ts JPPhotoManagerWeb/backend/src/main/java/com/jpablodrexler/photomanager/infrastructure/web/controller/AssetController.java:1
- REDACTED
- Near-duplicate member family (4 members, 15 shared lines) JPPhotoManagerWeb/backend/src/main/java/com/jpablodrexler/photomanager/application/usecase/tag/AddTagToAssetUseCaseImpl.java:58
- Members sharing a duplicated core (4 members, 50+ identical tokens) JPPhotoManagerWeb/backend/src/main/java/com/jpablodrexler/photomanager/infrastructure/batch/CatalogAssetItemProcessor.java:149
- Duplicated block (26–27 lines × 2) JPPhotoManager/JPPhotoManager.UI/Controls/FolderNavigationControl.xaml.cs:49
- Duplicated block (27 lines × 2) JPPhotoManagerWeb/backend/src/main/java/com/jpablodrexler/photomanager/infrastructure/kafka/KafkaProgressListener.java:75
- Duplicated block (20 lines × 2) JPPhotoManager/JPPhotoManager.Domain/Services/ConvertAssetsService.cs:130
- Duplicated block (13 lines × 2) JPPhotoManagerWeb/backend/src/main/java/com/jpablodrexler/photomanager/application/usecase/asset/CropAssetUseCaseImpl.java:108
- Duplicated block (12 lines × 3) JPPhotoManagerWeb/backend/src/main/java/com/jpablodrexler/photomanager/infrastructure/batch/CatalogAssetItemProcessor.java:117
- Duplicated block (11–12 lines × 2) JPPhotoManager/JPPhotoManager.Infrastructure/AppDbContext.cs:32
- Duplicated block (9 lines × 4) JPPhotoManagerWeb/backend/src/main/java/com/jpablodrexler/photomanager/application/usecase/tag/AddTagToAssetUseCaseImpl.java:66
- Duplicated block (7 lines × 4) JPPhotoManagerWeb/backend/src/main/java/com/jpablodrexler/photomanager/infrastructure/batch/CatalogAssetItemProcessor.java:155
- Duplicated block (7 lines × 3) JPPhotoManagerWeb/backend/src/main/java/com/jpablodrexler/photomanager/infrastructure/batch/CatalogAssetItemProcessor.java:55
- Duplicated block (6 lines × 4) JPPhotoManagerWeb/backend/src/main/java/com/jpablodrexler/photomanager/application/usecase/tag/AddTagToAssetUseCaseImpl.java:59
- Duplicated block (15 lines × 2) JPPhotoManager/JPPhotoManager.UI/Windows/ConvertAssetsWindow.xaml.cs:126
- Duplicated block (6 lines × 2) JPPhotoManagerWeb/backend/src/main/java/com/jpablodrexler/photomanager/infrastructure/persistence/mapper/AlbumEntityMapper.java:26
- Duplicated block (8 lines × 2) JPPhotoManagerWeb/backend/src/main/java/com/jpablodrexler/photomanager/application/usecase/album/AddAssetsToAlbumUseCaseImpl.java:22
- One operation mutates 2 aggregates: MoveAssetsUseCaseImpl.execute JPPhotoManagerWeb/backend/src/main/java/com/jpablodrexler/photomanager/application/usecase/asset/MoveAssetsUseCaseImpl.java:45
- One operation mutates 3 aggregates: CatalogAssetItemWriter.write JPPhotoManagerWeb/backend/src/main/java/com/jpablodrexler/photomanager/infrastructure/batch/CatalogAssetItemWriter.java:76
- Constructible in an invalid state: RecentTargetPathEntity JPPhotoManagerWeb/backend/src/main/java/com/jpablodrexler/photomanager/infrastructure/persistence/entity/RecentTargetPathEntity.java:20
- Domain type reads the wall clock: CatalogAssetsService JPPhotoManager/JPPhotoManager.Domain/Services/CatalogAssetsService.cs:345
- Duplication concentrated across 7 sibling directories (5 clone groups) JPPhotoManagerWeb/frontend/src/app/features/convert/convert.component.ts:1
- Wholesale file copy (77 identical lines × 2 files) JPPhotoManagerWeb/frontend/src/app/features/convert/convert.component.ts:1
- Duplicated block with local edits (44 matched lines × 2 locations) JPPhotoManagerWeb/frontend/scripts/dead-code-report.js:21
- Duplicated block (28 lines × 2 locations) JPPhotoManagerWeb/frontend/scripts/license-compliance-report.js:21
- Duplicated block (22 lines × 4 locations) JPPhotoManagerWeb/frontend/scripts/code-coverage-report.js:71
- Duplicated block with local edits (19 matched lines × 2 locations) JPPhotoManagerWeb/frontend/src/app/features/gallery/exif-panel/exif-panel.component.ts:59
- Duplicated block with local edits (17 matched lines × 2 locations) JPPhotoManagerWeb/frontend/scripts/lighthouse-report.mjs:139
- Duplicated block (16 lines × 6 locations) JPPhotoManagerWeb/frontend/scripts/a11y-report.js:95
- Duplicated block (15 lines × 5 locations) JPPhotoManagerWeb/frontend/scripts/complexity-report.js:49
- Duplicated block (14 lines × 2 locations) JPPhotoManagerWeb/frontend/src/app/core/services/convert.service.ts:6
- Duplicated block (13 lines × 2 locations) JPPhotoManagerWeb/frontend/src/app/features/gallery/exif-panel/exif-panel.component.ts:116
- Duplicated block (12 lines × 2 locations) JPPhotoManagerWeb/frontend/src/app/features/audio-player/audio-player.component.ts:15
- Duplicated block with local edits (10 matched lines × 2 locations) JPPhotoManagerWeb/frontend/src/app/core/services/asset.service.ts:20
- Duplicated block (10 lines × 2 locations) JPPhotoManagerWeb/frontend/src/app/features/recycle-bin/recycle-bin.component.ts:69
- Duplicated block (9 lines × 3 locations) JPPhotoManagerWeb/frontend/src/app/core/services/convert.service.ts:1
- Duplicated block with local edits (9 matched lines × 2 locations) JPPhotoManagerWeb/frontend/src/app/core/services/media-player.service.ts:88
- Duplicated block (8 lines × 2 locations) JPPhotoManagerWeb/frontend/scripts/dead-code-report.js:110
- Duplicated block (8 lines × 5 locations) JPPhotoManagerWeb/frontend/scripts/dependency-staleness-report.js:80
- Duplicated block (7 lines × 3 locations) JPPhotoManagerWeb/frontend/scripts/a11y-report.js:166
- Duplicated block (5 lines × 2 locations) JPPhotoManagerWeb/frontend/scripts/bundle-size-report.js:24
- Complex function getHitArea (cyclomatic 21, cognitive 10) JPPhotoManagerWeb/frontend/src/app/features/gallery/social-media-crop/social-media-crop.component.ts:234
- Complex function main (cyclomatic 17, cognitive 39) JPPhotoManagerWeb/frontend/scripts/a11y-report.js:83
- Complex function resizeFromCorner (cyclomatic 13, cognitive 12) JPPhotoManagerWeb/frontend/src/app/features/gallery/social-media-crop/social-media-crop.component.ts:190
- Complex function functionName (cyclomatic 12, cognitive 15) JPPhotoManagerWeb/frontend/scripts/cyclomatic-complexity.js:49
- Complex function main (cyclomatic 12, cognitive 15) JPPhotoManagerWeb/frontend/scripts/lighthouse-report.mjs:109
- Complex function createAlbum (cyclomatic 11, cognitive 13) JPPhotoManagerWeb/frontend/src/app/features/albums/albums.component.ts:78
- JPPhotoManagerWeb/frontend/src/app/features/gallery/gallery.component.ts: 907 lines of code JPPhotoManagerWeb/frontend/src/app/features/gallery/gallery.component.ts:1
- Dependency Freshness
- Dead file (~8 LoC) JPPhotoManagerWeb/frontend/src/app/core/models/audio-metadata.model.ts
- Dead file (~3 LoC) JPPhotoManagerWeb/frontend/src/app/core/models/tag.model.ts
- NuGet dependencies are not locked
Minor — 92 finding(s)
- REDACTED
- REDACTED
- REDACTED
- REDACTED
- REDACTED
- REDACTED
- REDACTED
- REDACTED
- REDACTED
- REDACTED
- REDACTED
- REDACTED
- REDACTED
- REDACTED
- REDACTED
- REDACTED
- REDACTED
- REDACTED
- REDACTED
- REDACTED
- REDACTED
- REDACTED
- REDACTED
- REDACTED
- REDACTED
- README/code drift JPPhotoManagerWeb/README.md:38
- README/code drift JPPhotoManagerWeb/README.md:39
- README/code drift JPPhotoManagerWeb/README.md:41
- README/code drift JPPhotoManagerWeb/README.md:44
- README/code drift JPPhotoManagerWeb/README.md:48
- README/code drift JPPhotoManagerWeb/README.md:50
- README/code drift JPPhotoManagerWeb/README.md:51
- README/code drift JPPhotoManagerWeb/README.md:57
- README/code drift docs/windows-dev-setup.md:164
- README/code drift JPPhotoManagerWeb/docs/authentication.md:176
- README/code drift JPPhotoManagerWeb/docs/authentication.md:222
- README/code drift JPPhotoManagerWeb/docs/backend.md:307
- README/code drift JPPhotoManagerWeb/docs/docker-compose.md:20
- README/code drift JPPhotoManagerWeb/docs/docker-compose.md:25
- README/code drift JPPhotoManagerWeb/docs/docker-compose.md:85
- README/code drift JPPhotoManagerWeb/docs/kubernetes.md:13
- README/code drift JPPhotoManagerWeb/docs/kubernetes.md:46
- No seccomp profile REDACTED:50
- No seccomp profile REDACTED:24
- No seccomp profile REDACTED:34
- No seccomp profile REDACTED:39
- No seccomp profile REDACTED:22
- No seccomp profile REDACTED:23
- No seccomp profile REDACTED:20
- No seccomp profile REDACTED:20
- Fat interface: IStorageService (29 members) JPPhotoManager/JPPhotoManager.Domain/Interfaces/Services/IStorageService.cs:7
- Fat interface: IApplication (25 members) JPPhotoManager/JPPhotoManager.Application/IApplication.cs:8
- Fat interface: AssetRepository (34 abstract methods) JPPhotoManagerWeb/backend/src/main/java/com/jpablodrexler/photomanager/domain/port/out/AssetRepository.java:18
- Fat interface: StoragePort (20 abstract methods) JPPhotoManagerWeb/backend/src/main/java/com/jpablodrexler/photomanager/domain/port/out/StoragePort.java:10
- Fat interface: JpaAssetRepository (32 abstract methods) JPPhotoManagerWeb/backend/src/main/java/com/jpablodrexler/photomanager/infrastructure/persistence/jpa/JpaAssetRepository.java:28
- Duplicated predicate JPPhotoManager/JPPhotoManager.Domain/Entities/ConvertAssetsDirectoriesDefinition.cs:22
- Duplicated predicate JPPhotoManagerWeb/backend/src/main/java/com/jpablodrexler/photomanager/infrastructure/web/dto/request/CreateAlbumRequestDto.java:14
- No ADRs found
- REDACTED
- REDACTED
- REDACTED
- REDACTED
- REDACTED
- No network policy
- Disabled test JPPhotoManager/JPPhotoManager.Tests/Integration/ReleaseAvailabilityServiceTests.cs:35
- Commented-out code JPPhotoManager/JPPhotoManager.UI/Windows/FolderNavigationWindow.xaml.cs:71
- No ADRs
- No src/ separation
- Changelog looks stale/thin
- Unused export 'AlbumAssetIdsRequest' JPPhotoManagerWeb/frontend/src/app/core/models/album.model.ts:41
- Unused export 'ChartSeries' JPPhotoManagerWeb/frontend/src/app/core/models/analytics.model.ts:33
- Unused export 'RenameAssetsRequest' JPPhotoManagerWeb/frontend/src/app/core/models/asset.model.ts:40
- Not all async methods take a CancellationToken
- Nullable reference types not enabled everywhere
- Silent fallback default in catch JPPhotoManagerWeb/frontend/src/app/core/services/auth.service.ts:122
Minor — 7 finding(s)
- XML-doc coverage: JPPhotoManager.Domain JPPhotoManager/JPPhotoManager.Domain/JPPhotoManager.Domain.csproj
- XML-doc coverage: JPPhotoManager.Infrastructure JPPhotoManager/JPPhotoManager.Infrastructure/JPPhotoManager.Infrastructure.csproj
- XML-doc coverage: JPPhotoManager.Application JPPhotoManager/JPPhotoManager.Application/JPPhotoManager.Application.csproj
- XML-doc coverage: JPPhotoManager.UI JPPhotoManager/JPPhotoManager.UI/JPPhotoManager.UI.csproj
- XML-doc coverage: JPPhotoManager.Common JPPhotoManager/JPPhotoManager.Common/JPPhotoManager.Common.csproj
- Skipped (documented): GetLatestRelease_ReturnReleaseData JPPhotoManager/JPPhotoManager.Tests/Integration/ReleaseAvailabilityServiceTests.cs:35
- Off the main sequence: JPPhotoManager.Common JPPhotoManager/JPPhotoManager.Common/JPPhotoManager.Common.csproj:1
Appendix B — Reproduction & audit trail
| Dimension | Tool | Version | Command | Findings | Raw output |
|---|---|---|---|---|---|
| D28 · Secrets (history) | gitleaks | — | gitleaks detect --no-banner --config /opt/gitleaks-rules/watchdog-gitleaks.toml --report-format json --report-path /tmp/watchdog-gitleaks-fb9eed23d3d2437b87272bb839b88565/history.json --exit-code 0 --source . | 0 | artifacts/raw/gitleaks-history.json |
| D28 · Secrets (history) | gitleaks | — | gitleaks detect --no-git --no-banner --config /opt/gitleaks-rules/watchdog-gitleaks.toml --report-format json --report-path /tmp/watchdog-gitleaks-fb9eed23d3d2437b87272bb839b88565/tree.json --exit-code 0 --source . | 0 | artifacts/raw/gitleaks-tree.json |
| D29 · Static Analysis (SAST) | semgrep | — | semgrep --config /opt/semgrep-rules/security-audit.yml --config /opt/semgrep-rules/owasp-top-ten.yml --config /opt/semgrep-rules/watchdog-sast.yml --json --quiet --timeout 10 --timeout-threshold 3 --metrics off . | 37 | artifacts/raw/semgrep.json |
| D30 · Dependency Vulnerabilities | nuget | — | nuget: not applicable — nuget: the solution did not restore on the analyzer's .NET SDK (an SDK/target-framework/restore mismatch, common for an older codebase), so there was no restored dependency graph to scan | 0 | — |
| D30 · Dependency Vulnerabilities | trivy | — | trivy fs --scanners vuln --format json --quiet --severity CRITICAL,HIGH,MEDIUM,LOW --skip-dirs **/bin/** --skip-dirs **/obj/** . --skip-db-update | 33 | artifacts/raw/trivy-fs.json |
| D31 · IaC & Container Security | trivy | — | trivy config --format json --quiet . | 244 | artifacts/raw/trivy-config.json |
| D32 · Data Compliance (PII/GDPR) | semgrep | — | semgrep: not applicable — No personal data was found crossing a boundary the PII/GDPR ruleset checks — nothing written to a log or console sink, placed in a URL or query string, or persisted to browser storage. That is a clean result for the LEAK surface only: this ruleset detects personal data escaping, it does not inventory the personal data a repository holds, so it is not evidence that this repository has no personal-data surface. The personal-data map (Appendix C) and the C1-C5 compliance cards are what speak to that. | 0 | — |
| D37 · Vulnerability-disclosure Policy | disclosure | — | disclosure: not applicable — No vulnerability-disclosure policy file found (SECURITY.md/.markdown/.rst/.txt at root or under .github/.forgejo/.gitea/docs, .well-known/security.txt). A coordinated-disclosure policy may live off-repo, so this is not evidenced rather than failed. | 0 | — |
| D42 · Runtime Threat Enforcement | runtime-hardening | — | runtime-hardening: not applicable — The repository ships application workloads but no cluster-governance resources (CRDs, admission webhooks, or a committed policy engine). Runtime threat-detection (Falco/Tetragon) and admission control (Kyverno/OPA-Gatekeeper/PodSecurity) are cluster-OPERATOR controls owned by the platform, not shipped by an application repo/chart — nothing for this repo to assess. | 0 | — |
| D43 · Malicious Dependencies | trivy | — | trivy fs --scanners vuln --format json --quiet --severity CRITICAL,HIGH,MEDIUM,LOW --skip-dirs **/bin/** --skip-dirs **/obj/** . --skip-db-update | 0 | artifacts/raw/trivy-fs.json |