feat: Flutter app scaffold with dependencies and clean starting point #22

Merged
bjoern merged 3 commits from feat/flutter-scaffold into main 2026-08-13 06:23:57 +02:00
Member

Flutter App — Groundwork (Phase 7 Step 1)

The most basic groundlaying work: Flutter project scaffold with all dependencies from ADR 0017, clean starting point, smoke test.

What's included

pubspec.yaml — all dependencies resolved and verified:

  • redux 5.0.0, flutter_redux 0.10.0, redux_epics 0.15.2
  • dio 5.7.0
  • go_router 14.6.2
  • freezed_annotation 2.4.4, json_annotation 4.9.0
  • flutter_secure_storage 9.2.2
  • dev: build_runner, freezed, json_serializable, mocktail, very_good_analysis 6.0.0

analysis_options.yaml — very_good_analysis lints, excluding generated files (*.g.dart, *.freezed.dart)

lib/main.dart — stripped default counter app, minimal clean DoujinManagerApp with placeholder

test/app_test.dart — smoke test (app renders title)

Platforms: Linux, Web, Android only (per ADR 0019 — Windows/macOS/iOS skipped)

Verification

  • flutter pub get
  • flutter analyzeNo issues found
  • flutter test1/1 passed

This is intentionally minimal — just the foundation. Next steps: Gallery theme, Redux store setup, folder structure, then feature-by-feature.

## Flutter App — Groundwork (Phase 7 Step 1) The most basic groundlaying work: Flutter project scaffold with all dependencies from ADR 0017, clean starting point, smoke test. ### What's included **`pubspec.yaml`** — all dependencies resolved and verified: - `redux` 5.0.0, `flutter_redux` 0.10.0, `redux_epics` 0.15.2 - `dio` 5.7.0 - `go_router` 14.6.2 - `freezed_annotation` 2.4.4, `json_annotation` 4.9.0 - `flutter_secure_storage` 9.2.2 - dev: `build_runner`, `freezed`, `json_serializable`, `mocktail`, `very_good_analysis` 6.0.0 **`analysis_options.yaml`** — very_good_analysis lints, excluding generated files (`*.g.dart`, `*.freezed.dart`) **`lib/main.dart`** — stripped default counter app, minimal clean `DoujinManagerApp` with placeholder **`test/app_test.dart`** — smoke test (app renders title) **Platforms**: Linux, Web, Android only (per ADR 0019 — Windows/macOS/iOS skipped) ### Verification - `flutter pub get` ✅ - `flutter analyze` → **No issues found** ✅ - `flutter test` → **1/1 passed** ✅ This is intentionally minimal — just the foundation. Next steps: Gallery theme, Redux store setup, folder structure, then feature-by-feature.
feat: scaffold Flutter app with dependencies and clean starting point
All checks were successful
CI / build (pull_request) Successful in 16s
CI / test (pull_request) Successful in 35s
e4d9d5cbec
- flutter create --platforms linux,web,android --org eu.kagaku
- pubspec.yaml with all dependencies per ADR 0017:
  redux 5.0.0, flutter_redux 0.10.0, redux_epics 0.15.2,
  dio 5.7.0, go_router 14.6.2, freezed_annotation 2.4.4,
  json_annotation 4.9.0, flutter_secure_storage 9.2.2
- dev deps: build_runner, freezed, json_serializable, mocktail,
  very_good_analysis 6.0.0
- analysis_options.yaml with very_good_analysis, excluding generated files
- Stripped default counter app, replaced with minimal clean main.dart
- Smoke test: app renders title
- flutter analyze: 0 issues, flutter test: 1/1 pass

Summary

Summary
Generated on: 06/29/2026 - 17:01:12
Coverage date: 06/29/2026 - 17:00:57 - 06/29/2026 - 17:01:10
Parser: MultiReport (4x Cobertura)
Assemblies: 4
Classes: 207
Files: 94
Line coverage: 83.8% (4293 of 5118)
Covered lines: 4293
Uncovered lines: 825
Coverable lines: 5118
Total lines: 8845
Branch coverage: 49.8% (368 of 738)
Covered branches: 368
Total branches: 738
Method coverage: Feature is only available for sponsors

Coverage

DoujinManager.ApplicationCore - 84.8%
Name Line Branch
DoujinManager.ApplicationCore 84.8% ****
DoujinManager.ApplicationCore.Entities.Chapter 87.5%
DoujinManager.ApplicationCore.Entities.Circle 100%
DoujinManager.ApplicationCore.Entities.Doujin 100%
DoujinManager.ApplicationCore.Entities.DoujinCircle 75%
DoujinManager.ApplicationCore.Entities.DoujinPerson 80%
DoujinManager.ApplicationCore.Entities.DoujinTag 75%
DoujinManager.ApplicationCore.Entities.ImageFile 100%
DoujinManager.ApplicationCore.Entities.Page 80%
DoujinManager.ApplicationCore.Entities.Person 100%
DoujinManager.ApplicationCore.Entities.Tag 100%
DoujinManager.ApplicationCore.Entities.Title 83.3%
DoujinManager.ApplicationCore.Entities.Variant 91.6%
DoujinManager.ApplicationCore.Ids.ChapterId 66.6%
DoujinManager.ApplicationCore.Ids.CircleId 66.6%
DoujinManager.ApplicationCore.Ids.DoujinId 100%
DoujinManager.ApplicationCore.Ids.ImageFileId 66.6%
DoujinManager.ApplicationCore.Ids.PageId 66.6%
DoujinManager.ApplicationCore.Ids.PersonId 66.6%
DoujinManager.ApplicationCore.Ids.TagId 66.6%
DoujinManager.ApplicationCore.Ids.TitleId 66.6%
DoujinManager.ApplicationCore.Ids.VariantId 66.6%
DoujinManager.ApplicationCore.Ports.ExtractedImage 100%
DoujinManager.ApplicationCore.Ports.ImageInspection 100%
DoujinManager.ApplicationCore.Services.BackupInfo 100%
DoujinManager.ApplicationCore.Services.ITagService 100%
DoujinManager.ApplicationCore.Services.ServiceResult 100%
DoujinManager.ApplicationCore.Services.ServiceResult`1 33.3%
DoujinManager.ApplicationCore.Services.VoidResult 88.8%
DoujinManager.ApplicationCore.UseCases.AddTitleCommand 0%
DoujinManager.ApplicationCore.UseCases.AssignCircleCommand 100%
DoujinManager.ApplicationCore.UseCases.AssignPersonCommand 100%
DoujinManager.ApplicationCore.UseCases.AssignTagCommand 100%
DoujinManager.ApplicationCore.UseCases.CreateChapterCommand 100%
DoujinManager.ApplicationCore.UseCases.CreateCircleCommand 100%
DoujinManager.ApplicationCore.UseCases.CreateDoujinCommand 100%
DoujinManager.ApplicationCore.UseCases.CreatePersonCommand 100%
DoujinManager.ApplicationCore.UseCases.CreateTagCommand 100%
DoujinManager.ApplicationCore.UseCases.CreateTitleCommand 100%
DoujinManager.ApplicationCore.UseCases.CreateVariantCommand 100%
DoujinManager.ApplicationCore.UseCases.DeleteChapterCommand 0%
DoujinManager.ApplicationCore.UseCases.DeleteDoujinCommand 100%
DoujinManager.ApplicationCore.UseCases.DeletePageCommand 100%
DoujinManager.ApplicationCore.UseCases.DeleteVariantCommand 0%
DoujinManager.ApplicationCore.UseCases.GetDoujinQuery 100%
DoujinManager.ApplicationCore.UseCases.GetImageQuery 100%
DoujinManager.ApplicationCore.UseCases.GetImageResult 100%
DoujinManager.ApplicationCore.UseCases.GetThumbnailQuery 100%
DoujinManager.ApplicationCore.UseCases.GetThumbnailResult 100%
DoujinManager.ApplicationCore.UseCases.GetVariantQuery 100%
DoujinManager.ApplicationCore.UseCases.ListChaptersQuery 100%
DoujinManager.ApplicationCore.UseCases.ListCirclesQuery 100%
DoujinManager.ApplicationCore.UseCases.ListDoujinsQuery 100%
DoujinManager.ApplicationCore.UseCases.ListPagesQuery 100%
DoujinManager.ApplicationCore.UseCases.ListPeopleQuery 100%
DoujinManager.ApplicationCore.UseCases.ListTagsQuery 100%
DoujinManager.ApplicationCore.UseCases.ListVariantsQuery 100%
DoujinManager.ApplicationCore.UseCases.RemoveCircleCommand 0%
DoujinManager.ApplicationCore.UseCases.RemovePersonCommand 0%
DoujinManager.ApplicationCore.UseCases.RemoveTagCommand 0%
DoujinManager.ApplicationCore.UseCases.RemoveTitleCommand 0%
DoujinManager.ApplicationCore.UseCases.ReorderPagesCommand 100%
DoujinManager.ApplicationCore.UseCases.SearchDoujinsQuery 100%
DoujinManager.ApplicationCore.UseCases.SearchResult 100%
DoujinManager.ApplicationCore.UseCases.SearchResults 100%
DoujinManager.ApplicationCore.UseCases.UpdateChapterCommand 0%
DoujinManager.ApplicationCore.UseCases.UpdateCircleCommand 0%
DoujinManager.ApplicationCore.UseCases.UpdateDoujinCommand 100%
DoujinManager.ApplicationCore.UseCases.UpdatePersonCommand 0%
DoujinManager.ApplicationCore.UseCases.UpdateVariantCommand 0%
DoujinManager.ApplicationCore.UseCases.UploadImageFile 100%
DoujinManager.ApplicationCore.UseCases.UploadPagesCommand 100%
DoujinManager.ApplicationCore.UseCases.UploadZipPagesCommand 100%
DoujinManager.Infrastructure - 91.6%
Name Line Branch
DoujinManager.Infrastructure 91.6% 70.5%
DoujinManager.Infrastructure.Archives.ZipExtractor 100% 87.5%
DoujinManager.Infrastructure.Data.Configurations.ChapterConfiguration 100%
DoujinManager.Infrastructure.Data.Configurations.CircleConfiguration 100%
DoujinManager.Infrastructure.Data.Configurations.DoujinCircleConfiguration 100%
DoujinManager.Infrastructure.Data.Configurations.DoujinConfiguration 100%
DoujinManager.Infrastructure.Data.Configurations.DoujinPersonConfiguration 100%
DoujinManager.Infrastructure.Data.Configurations.DoujinTagConfiguration 100%
DoujinManager.Infrastructure.Data.Configurations.ImageFileConfiguration 100%
DoujinManager.Infrastructure.Data.Configurations.PageConfiguration 100%
DoujinManager.Infrastructure.Data.Configurations.PersonConfiguration 100%
DoujinManager.Infrastructure.Data.Configurations.TagConfiguration 100%
DoujinManager.Infrastructure.Data.Configurations.TitleConfiguration 100%
DoujinManager.Infrastructure.Data.Configurations.VariantConfiguration 100%
DoujinManager.Infrastructure.Data.DoujinManagerDbContext 100%
DoujinManager.Infrastructure.Data.GuidIdGenerator 11.1%
DoujinManager.Infrastructure.Data.Migrations.DoujinManagerDbContextModelSna
pshot
100%
DoujinManager.Infrastructure.Data.Migrations.InitialCreate 97.1%
DoujinManager.Infrastructure.Data.ModelBuilderExtensions 50%
DoujinManager.Infrastructure.Data.StronglyTypedIdConverterFactory 69.2%
DoujinManager.Infrastructure.Images.SkiaSharpImageInspector 88.2% 70.9%
DoujinManager.Infrastructure.Images.SkiaSharpThumbnailGenerator 94.5% 66.6%
DoujinManager.Infrastructure.Services.BackupService 85.1% 66.6%
DoujinManager.Infrastructure.Services.ChapterService 54.2% 25%
DoujinManager.Infrastructure.Services.CircleService 69.6% 0%
DoujinManager.Infrastructure.Services.DoujinService 70.3% 45.8%
DoujinManager.Infrastructure.Services.ImageService 92% 50%
DoujinManager.Infrastructure.Services.PageService 84.9% 65%
DoujinManager.Infrastructure.Services.PersonService 69.6% 0%
DoujinManager.Infrastructure.Services.SearchService 100% 98.2%
DoujinManager.Infrastructure.Services.TagService 94.7% 100%
DoujinManager.Infrastructure.Services.VariantService 50.7% 16.6%
DoujinManager.Infrastructure.Storage.FilesystemImageStorage 100% 100%
DoujinManager.Infrastructure.Storage.FilesystemThumbnailStorage 95% 50%
DoujinManager.Infrastructure.UseCases.AddTitleUseCase 0% 0%
DoujinManager.Infrastructure.UseCases.AssignCircleUseCase 100% 100%
DoujinManager.Infrastructure.UseCases.AssignPersonUseCase 100% 100%
DoujinManager.Infrastructure.UseCases.AssignTagUseCase 100% 100%
DoujinManager.Infrastructure.UseCases.CreateChapterUseCase 100% 100%
DoujinManager.Infrastructure.UseCases.CreateCircleUseCase 100%
DoujinManager.Infrastructure.UseCases.CreateDoujinUseCase 100% 98%
DoujinManager.Infrastructure.UseCases.CreatePersonUseCase 100%
DoujinManager.Infrastructure.UseCases.CreateTagUseCase 100% 100%
DoujinManager.Infrastructure.UseCases.CreateVariantUseCase 100% 100%
DoujinManager.Infrastructure.UseCases.DeleteChapterUseCase 0%
DoujinManager.Infrastructure.UseCases.DeleteDoujinUseCase 100%
DoujinManager.Infrastructure.UseCases.DeletePageUseCase 92.3% 75%
DoujinManager.Infrastructure.UseCases.DeleteVariantUseCase 0%
DoujinManager.Infrastructure.UseCases.GetDoujinUseCase 100%
DoujinManager.Infrastructure.UseCases.GetImageUseCase 100% 100%
DoujinManager.Infrastructure.UseCases.GetThumbnailUseCase 100% 100%
DoujinManager.Infrastructure.UseCases.GetVariantUseCase 100%
DoujinManager.Infrastructure.UseCases.ListChaptersUseCase 100% 100%
DoujinManager.Infrastructure.UseCases.ListCirclesUseCase 100%
DoujinManager.Infrastructure.UseCases.ListDoujinsUseCase 100%
DoujinManager.Infrastructure.UseCases.ListPagesUseCase 100% 100%
DoujinManager.Infrastructure.UseCases.ListPeopleUseCase 100%
DoujinManager.Infrastructure.UseCases.ListTagsUseCase 100%
DoujinManager.Infrastructure.UseCases.ListVariantsUseCase 100% 100%
DoujinManager.Infrastructure.UseCases.RemoveCircleUseCase 0%
DoujinManager.Infrastructure.UseCases.RemovePersonUseCase 0%
DoujinManager.Infrastructure.UseCases.RemoveTagUseCase 0%
DoujinManager.Infrastructure.UseCases.RemoveTitleUseCase 0%
DoujinManager.Infrastructure.UseCases.ReorderPagesUseCase 100% 100%
DoujinManager.Infrastructure.UseCases.SearchDoujinsUseCase 100%
DoujinManager.Infrastructure.UseCases.UpdateChapterUseCase 0% 0%
DoujinManager.Infrastructure.UseCases.UpdateCircleUseCase 0% 0%
DoujinManager.Infrastructure.UseCases.UpdateDoujinUseCase 100% 100%
DoujinManager.Infrastructure.UseCases.UpdatePersonUseCase 0% 0%
DoujinManager.Infrastructure.UseCases.UpdateVariantUseCase 0%
DoujinManager.Infrastructure.UseCases.UploadPagesUseCase 91.1% 92.8%
DoujinManager.Infrastructure.UseCases.UploadZipPagesUseCase 70.2% 62.5%
DoujinManager.RestAdapter - 84.2%
Name Line Branch
DoujinManager.RestAdapter 84.2% 74.1%
DoujinManager.RestAdapter.Auth.StaticBearerTokenAuthMiddleware 100% 91.6%
DoujinManager.RestAdapter.Dtos.AssignTagDto 0%
DoujinManager.RestAdapter.Dtos.BackupDto 100%
DoujinManager.RestAdapter.Dtos.ChapterDto 100%
DoujinManager.RestAdapter.Dtos.CircleDto 100%
DoujinManager.RestAdapter.Dtos.CreateChapterDto 100%
DoujinManager.RestAdapter.Dtos.CreateCircleDto 100%
DoujinManager.RestAdapter.Dtos.CreateDoujinDto 100%
DoujinManager.RestAdapter.Dtos.CreatePersonDto 100%
DoujinManager.RestAdapter.Dtos.CreateTagDto 100%
DoujinManager.RestAdapter.Dtos.CreateTitleDto 100%
DoujinManager.RestAdapter.Dtos.CreateVariantDto 100%
DoujinManager.RestAdapter.Dtos.DoujinDetailDto 100%
DoujinManager.RestAdapter.Dtos.DoujinPersonDto 100%
DoujinManager.RestAdapter.Dtos.DoujinSummaryDto 100%
DoujinManager.RestAdapter.Dtos.ImageFileSummaryDto 0%
DoujinManager.RestAdapter.Dtos.LinkCircleDto 0%
DoujinManager.RestAdapter.Dtos.LinkPersonDto 100%
DoujinManager.RestAdapter.Dtos.PageDetailDto 100%
DoujinManager.RestAdapter.Dtos.PageDto 100%
DoujinManager.RestAdapter.Dtos.PersonDto 100%
DoujinManager.RestAdapter.Dtos.ReorderPagesDto 100%
DoujinManager.RestAdapter.Dtos.SearchDoujinsDto 100%
DoujinManager.RestAdapter.Dtos.SearchResultDto 100%
DoujinManager.RestAdapter.Dtos.TagDto 100%
DoujinManager.RestAdapter.Dtos.TitleDto 100%
DoujinManager.RestAdapter.Dtos.UpdateChapterDto 0%
DoujinManager.RestAdapter.Dtos.UpdateCircleDto 0%
DoujinManager.RestAdapter.Dtos.UpdateDoujinDto 100%
DoujinManager.RestAdapter.Dtos.UpdatePersonDto 0%
DoujinManager.RestAdapter.Dtos.UpdateVariantDto 0%
DoujinManager.RestAdapter.Dtos.UploadPagesResponseDto 100%
DoujinManager.RestAdapter.Dtos.VariantDetailDto 100%
DoujinManager.RestAdapter.Dtos.VariantSummaryDto 100%
DoujinManager.RestAdapter.Endpoints.BackupEndpoints 100%
DoujinManager.RestAdapter.Endpoints.DoujinEndpoints 81.2% 75%
DoujinManager.RestAdapter.Endpoints.ImageEndpoints 96.6% 50%
DoujinManager.RestAdapter.Endpoints.MetadataEndpoints 84.2%
DoujinManager.RestAdapter.Endpoints.PaginationParams 100%
DoujinManager.RestAdapter.Endpoints.SearchEndpoints 100% 50%
DoujinManager.RestAdapter.Endpoints.VariantEndpoints 69.9% 37.5%
DoujinManager.RestAdapter.Envelopes.CollectionResponse`1 83.3%
DoujinManager.RestAdapter.Envelopes.EnvelopeDefaults 0%
DoujinManager.RestAdapter.Envelopes.EnvelopeJsonOptions 100%
DoujinManager.RestAdapter.Envelopes.ErrorResponse 100%
DoujinManager.RestAdapter.Envelopes.HypermediaAction 100%
DoujinManager.RestAdapter.Envelopes.HypermediaHelpers 87% 100%
DoujinManager.RestAdapter.Envelopes.Link 100%
DoujinManager.RestAdapter.Envelopes.PageInfo 100%
DoujinManager.RestAdapter.Envelopes.ResourceResponse`1 80%
DoujinManager.RestAdapter.Envelopes.ValidationError 100%
DoujinManager.RestAdapter.Envelopes.ValidationErrorResponse 100%
DoujinManager.RestAdapter.Middleware.GlobalExceptionMiddleware 100% 50%
DoujinManager.RestAdapter.Middleware.RequestLoggingMiddleware 100% 100%
DoujinManager.RestAdapter.RestAdapterExtensions 100% 100%
Microsoft.Extensions.Validation.Generated 78.6% 78.2%
Microsoft.Extensions.Validation.Generated.<ValidatableInfoResolver_g>FB9B0C
E5CB12CEAC5BBBEA65844E1C05F9ADA4DA38B848075C41304FC6A1ABF77__ValidationAttr
ibuteCache
100% 62.5%
System.Runtime.CompilerServices 0%
DoujinManager.Server - 20.9%
Name Line Branch
DoujinManager.Server 20.9% 0%
DoujinManager.Server.ImageInfrastructureRegistration 100%
DoujinManager.Server.ScalarUi 100%
DoujinManager.Server.UseCaseRegistrationHelper 100%
Microsoft.AspNetCore.OpenApi.Generated 0% 0%
Program 0% 0%
System.Runtime.CompilerServices 0%
<!-- coverage-comment --> # Summary <details open><summary>Summary</summary> ||| |:---|:---| | Generated on: | 06/29/2026 - 17:01:12 | | Coverage date: | 06/29/2026 - 17:00:57 - 06/29/2026 - 17:01:10 | | Parser: | MultiReport (4x Cobertura) | | Assemblies: | 4 | | Classes: | 207 | | Files: | 94 | | **Line coverage:** | 83.8% (4293 of 5118) | | Covered lines: | 4293 | | Uncovered lines: | 825 | | Coverable lines: | 5118 | | Total lines: | 8845 | | **Branch coverage:** | 49.8% (368 of 738) | | Covered branches: | 368 | | Total branches: | 738 | | **Method coverage:** | [Feature is only available for sponsors](https://reportgenerator.io/pro) | </details> ## Coverage <details><summary>DoujinManager.ApplicationCore - 84.8%</summary> |**Name**|**Line**|**Branch**| |:---|---:|---:| |**DoujinManager.ApplicationCore**|**84.8%**|****| |DoujinManager.ApplicationCore.Entities.Chapter|87.5%|| |DoujinManager.ApplicationCore.Entities.Circle|100%|| |DoujinManager.ApplicationCore.Entities.Doujin|100%|| |DoujinManager.ApplicationCore.Entities.DoujinCircle|75%|| |DoujinManager.ApplicationCore.Entities.DoujinPerson|80%|| |DoujinManager.ApplicationCore.Entities.DoujinTag|75%|| |DoujinManager.ApplicationCore.Entities.ImageFile|100%|| |DoujinManager.ApplicationCore.Entities.Page|80%|| |DoujinManager.ApplicationCore.Entities.Person|100%|| |DoujinManager.ApplicationCore.Entities.Tag|100%|| |DoujinManager.ApplicationCore.Entities.Title|83.3%|| |DoujinManager.ApplicationCore.Entities.Variant|91.6%|| |DoujinManager.ApplicationCore.Ids.ChapterId|66.6%|| |DoujinManager.ApplicationCore.Ids.CircleId|66.6%|| |DoujinManager.ApplicationCore.Ids.DoujinId|100%|| |DoujinManager.ApplicationCore.Ids.ImageFileId|66.6%|| |DoujinManager.ApplicationCore.Ids.PageId|66.6%|| |DoujinManager.ApplicationCore.Ids.PersonId|66.6%|| |DoujinManager.ApplicationCore.Ids.TagId|66.6%|| |DoujinManager.ApplicationCore.Ids.TitleId|66.6%|| |DoujinManager.ApplicationCore.Ids.VariantId|66.6%|| |DoujinManager.ApplicationCore.Ports.ExtractedImage|100%|| |DoujinManager.ApplicationCore.Ports.ImageInspection|100%|| |DoujinManager.ApplicationCore.Services.BackupInfo|100%|| |DoujinManager.ApplicationCore.Services.ITagService|100%|| |DoujinManager.ApplicationCore.Services.ServiceResult|100%|| |DoujinManager.ApplicationCore.Services.ServiceResult`1|33.3%|| |DoujinManager.ApplicationCore.Services.VoidResult|88.8%|| |DoujinManager.ApplicationCore.UseCases.AddTitleCommand|0%|| |DoujinManager.ApplicationCore.UseCases.AssignCircleCommand|100%|| |DoujinManager.ApplicationCore.UseCases.AssignPersonCommand|100%|| |DoujinManager.ApplicationCore.UseCases.AssignTagCommand|100%|| |DoujinManager.ApplicationCore.UseCases.CreateChapterCommand|100%|| |DoujinManager.ApplicationCore.UseCases.CreateCircleCommand|100%|| |DoujinManager.ApplicationCore.UseCases.CreateDoujinCommand|100%|| |DoujinManager.ApplicationCore.UseCases.CreatePersonCommand|100%|| |DoujinManager.ApplicationCore.UseCases.CreateTagCommand|100%|| |DoujinManager.ApplicationCore.UseCases.CreateTitleCommand|100%|| |DoujinManager.ApplicationCore.UseCases.CreateVariantCommand|100%|| |DoujinManager.ApplicationCore.UseCases.DeleteChapterCommand|0%|| |DoujinManager.ApplicationCore.UseCases.DeleteDoujinCommand|100%|| |DoujinManager.ApplicationCore.UseCases.DeletePageCommand|100%|| |DoujinManager.ApplicationCore.UseCases.DeleteVariantCommand|0%|| |DoujinManager.ApplicationCore.UseCases.GetDoujinQuery|100%|| |DoujinManager.ApplicationCore.UseCases.GetImageQuery|100%|| |DoujinManager.ApplicationCore.UseCases.GetImageResult|100%|| |DoujinManager.ApplicationCore.UseCases.GetThumbnailQuery|100%|| |DoujinManager.ApplicationCore.UseCases.GetThumbnailResult|100%|| |DoujinManager.ApplicationCore.UseCases.GetVariantQuery|100%|| |DoujinManager.ApplicationCore.UseCases.ListChaptersQuery|100%|| |DoujinManager.ApplicationCore.UseCases.ListCirclesQuery|100%|| |DoujinManager.ApplicationCore.UseCases.ListDoujinsQuery|100%|| |DoujinManager.ApplicationCore.UseCases.ListPagesQuery|100%|| |DoujinManager.ApplicationCore.UseCases.ListPeopleQuery|100%|| |DoujinManager.ApplicationCore.UseCases.ListTagsQuery|100%|| |DoujinManager.ApplicationCore.UseCases.ListVariantsQuery|100%|| |DoujinManager.ApplicationCore.UseCases.RemoveCircleCommand|0%|| |DoujinManager.ApplicationCore.UseCases.RemovePersonCommand|0%|| |DoujinManager.ApplicationCore.UseCases.RemoveTagCommand|0%|| |DoujinManager.ApplicationCore.UseCases.RemoveTitleCommand|0%|| |DoujinManager.ApplicationCore.UseCases.ReorderPagesCommand|100%|| |DoujinManager.ApplicationCore.UseCases.SearchDoujinsQuery|100%|| |DoujinManager.ApplicationCore.UseCases.SearchResult|100%|| |DoujinManager.ApplicationCore.UseCases.SearchResults|100%|| |DoujinManager.ApplicationCore.UseCases.UpdateChapterCommand|0%|| |DoujinManager.ApplicationCore.UseCases.UpdateCircleCommand|0%|| |DoujinManager.ApplicationCore.UseCases.UpdateDoujinCommand|100%|| |DoujinManager.ApplicationCore.UseCases.UpdatePersonCommand|0%|| |DoujinManager.ApplicationCore.UseCases.UpdateVariantCommand|0%|| |DoujinManager.ApplicationCore.UseCases.UploadImageFile|100%|| |DoujinManager.ApplicationCore.UseCases.UploadPagesCommand|100%|| |DoujinManager.ApplicationCore.UseCases.UploadZipPagesCommand|100%|| </details> <details><summary>DoujinManager.Infrastructure - 91.6%</summary> |**Name**|**Line**|**Branch**| |:---|---:|---:| |**DoujinManager.Infrastructure**|**91.6%**|**70.5%**| |DoujinManager.Infrastructure.Archives.ZipExtractor|100%|87.5%| |DoujinManager.Infrastructure.Data.Configurations.ChapterConfiguration|100%|| |DoujinManager.Infrastructure.Data.Configurations.CircleConfiguration|100%|| |DoujinManager.Infrastructure.Data.Configurations.DoujinCircleConfiguration|100%|| |DoujinManager.Infrastructure.Data.Configurations.DoujinConfiguration|100%|| |DoujinManager.Infrastructure.Data.Configurations.DoujinPersonConfiguration|100%|| |DoujinManager.Infrastructure.Data.Configurations.DoujinTagConfiguration|100%|| |DoujinManager.Infrastructure.Data.Configurations.ImageFileConfiguration|100%|| |DoujinManager.Infrastructure.Data.Configurations.PageConfiguration|100%|| |DoujinManager.Infrastructure.Data.Configurations.PersonConfiguration|100%|| |DoujinManager.Infrastructure.Data.Configurations.TagConfiguration|100%|| |DoujinManager.Infrastructure.Data.Configurations.TitleConfiguration|100%|| |DoujinManager.Infrastructure.Data.Configurations.VariantConfiguration|100%|| |DoujinManager.Infrastructure.Data.DoujinManagerDbContext|100%|| |DoujinManager.Infrastructure.Data.GuidIdGenerator|11.1%|| |DoujinManager.Infrastructure.Data.Migrations.DoujinManagerDbContextModelSna<br/>pshot|100%|| |DoujinManager.Infrastructure.Data.Migrations.InitialCreate|97.1%|| |DoujinManager.Infrastructure.Data.ModelBuilderExtensions|50%|| |DoujinManager.Infrastructure.Data.StronglyTypedIdConverterFactory|69.2%|| |DoujinManager.Infrastructure.Images.SkiaSharpImageInspector|88.2%|70.9%| |DoujinManager.Infrastructure.Images.SkiaSharpThumbnailGenerator|94.5%|66.6%| |DoujinManager.Infrastructure.Services.BackupService|85.1%|66.6%| |DoujinManager.Infrastructure.Services.ChapterService|54.2%|25%| |DoujinManager.Infrastructure.Services.CircleService|69.6%|0%| |DoujinManager.Infrastructure.Services.DoujinService|70.3%|45.8%| |DoujinManager.Infrastructure.Services.ImageService|92%|50%| |DoujinManager.Infrastructure.Services.PageService|84.9%|65%| |DoujinManager.Infrastructure.Services.PersonService|69.6%|0%| |DoujinManager.Infrastructure.Services.SearchService|100%|98.2%| |DoujinManager.Infrastructure.Services.TagService|94.7%|100%| |DoujinManager.Infrastructure.Services.VariantService|50.7%|16.6%| |DoujinManager.Infrastructure.Storage.FilesystemImageStorage|100%|100%| |DoujinManager.Infrastructure.Storage.FilesystemThumbnailStorage|95%|50%| |DoujinManager.Infrastructure.UseCases.AddTitleUseCase|0%|0%| |DoujinManager.Infrastructure.UseCases.AssignCircleUseCase|100%|100%| |DoujinManager.Infrastructure.UseCases.AssignPersonUseCase|100%|100%| |DoujinManager.Infrastructure.UseCases.AssignTagUseCase|100%|100%| |DoujinManager.Infrastructure.UseCases.CreateChapterUseCase|100%|100%| |DoujinManager.Infrastructure.UseCases.CreateCircleUseCase|100%|| |DoujinManager.Infrastructure.UseCases.CreateDoujinUseCase|100%|98%| |DoujinManager.Infrastructure.UseCases.CreatePersonUseCase|100%|| |DoujinManager.Infrastructure.UseCases.CreateTagUseCase|100%|100%| |DoujinManager.Infrastructure.UseCases.CreateVariantUseCase|100%|100%| |DoujinManager.Infrastructure.UseCases.DeleteChapterUseCase|0%|| |DoujinManager.Infrastructure.UseCases.DeleteDoujinUseCase|100%|| |DoujinManager.Infrastructure.UseCases.DeletePageUseCase|92.3%|75%| |DoujinManager.Infrastructure.UseCases.DeleteVariantUseCase|0%|| |DoujinManager.Infrastructure.UseCases.GetDoujinUseCase|100%|| |DoujinManager.Infrastructure.UseCases.GetImageUseCase|100%|100%| |DoujinManager.Infrastructure.UseCases.GetThumbnailUseCase|100%|100%| |DoujinManager.Infrastructure.UseCases.GetVariantUseCase|100%|| |DoujinManager.Infrastructure.UseCases.ListChaptersUseCase|100%|100%| |DoujinManager.Infrastructure.UseCases.ListCirclesUseCase|100%|| |DoujinManager.Infrastructure.UseCases.ListDoujinsUseCase|100%|| |DoujinManager.Infrastructure.UseCases.ListPagesUseCase|100%|100%| |DoujinManager.Infrastructure.UseCases.ListPeopleUseCase|100%|| |DoujinManager.Infrastructure.UseCases.ListTagsUseCase|100%|| |DoujinManager.Infrastructure.UseCases.ListVariantsUseCase|100%|100%| |DoujinManager.Infrastructure.UseCases.RemoveCircleUseCase|0%|| |DoujinManager.Infrastructure.UseCases.RemovePersonUseCase|0%|| |DoujinManager.Infrastructure.UseCases.RemoveTagUseCase|0%|| |DoujinManager.Infrastructure.UseCases.RemoveTitleUseCase|0%|| |DoujinManager.Infrastructure.UseCases.ReorderPagesUseCase|100%|100%| |DoujinManager.Infrastructure.UseCases.SearchDoujinsUseCase|100%|| |DoujinManager.Infrastructure.UseCases.UpdateChapterUseCase|0%|0%| |DoujinManager.Infrastructure.UseCases.UpdateCircleUseCase|0%|0%| |DoujinManager.Infrastructure.UseCases.UpdateDoujinUseCase|100%|100%| |DoujinManager.Infrastructure.UseCases.UpdatePersonUseCase|0%|0%| |DoujinManager.Infrastructure.UseCases.UpdateVariantUseCase|0%|| |DoujinManager.Infrastructure.UseCases.UploadPagesUseCase|91.1%|92.8%| |DoujinManager.Infrastructure.UseCases.UploadZipPagesUseCase|70.2%|62.5%| </details> <details><summary>DoujinManager.RestAdapter - 84.2%</summary> |**Name**|**Line**|**Branch**| |:---|---:|---:| |**DoujinManager.RestAdapter**|**84.2%**|**74.1%**| |DoujinManager.RestAdapter.Auth.StaticBearerTokenAuthMiddleware|100%|91.6%| |DoujinManager.RestAdapter.Dtos.AssignTagDto|0%|| |DoujinManager.RestAdapter.Dtos.BackupDto|100%|| |DoujinManager.RestAdapter.Dtos.ChapterDto|100%|| |DoujinManager.RestAdapter.Dtos.CircleDto|100%|| |DoujinManager.RestAdapter.Dtos.CreateChapterDto|100%|| |DoujinManager.RestAdapter.Dtos.CreateCircleDto|100%|| |DoujinManager.RestAdapter.Dtos.CreateDoujinDto|100%|| |DoujinManager.RestAdapter.Dtos.CreatePersonDto|100%|| |DoujinManager.RestAdapter.Dtos.CreateTagDto|100%|| |DoujinManager.RestAdapter.Dtos.CreateTitleDto|100%|| |DoujinManager.RestAdapter.Dtos.CreateVariantDto|100%|| |DoujinManager.RestAdapter.Dtos.DoujinDetailDto|100%|| |DoujinManager.RestAdapter.Dtos.DoujinPersonDto|100%|| |DoujinManager.RestAdapter.Dtos.DoujinSummaryDto|100%|| |DoujinManager.RestAdapter.Dtos.ImageFileSummaryDto|0%|| |DoujinManager.RestAdapter.Dtos.LinkCircleDto|0%|| |DoujinManager.RestAdapter.Dtos.LinkPersonDto|100%|| |DoujinManager.RestAdapter.Dtos.PageDetailDto|100%|| |DoujinManager.RestAdapter.Dtos.PageDto|100%|| |DoujinManager.RestAdapter.Dtos.PersonDto|100%|| |DoujinManager.RestAdapter.Dtos.ReorderPagesDto|100%|| |DoujinManager.RestAdapter.Dtos.SearchDoujinsDto|100%|| |DoujinManager.RestAdapter.Dtos.SearchResultDto|100%|| |DoujinManager.RestAdapter.Dtos.TagDto|100%|| |DoujinManager.RestAdapter.Dtos.TitleDto|100%|| |DoujinManager.RestAdapter.Dtos.UpdateChapterDto|0%|| |DoujinManager.RestAdapter.Dtos.UpdateCircleDto|0%|| |DoujinManager.RestAdapter.Dtos.UpdateDoujinDto|100%|| |DoujinManager.RestAdapter.Dtos.UpdatePersonDto|0%|| |DoujinManager.RestAdapter.Dtos.UpdateVariantDto|0%|| |DoujinManager.RestAdapter.Dtos.UploadPagesResponseDto|100%|| |DoujinManager.RestAdapter.Dtos.VariantDetailDto|100%|| |DoujinManager.RestAdapter.Dtos.VariantSummaryDto|100%|| |DoujinManager.RestAdapter.Endpoints.BackupEndpoints|100%|| |DoujinManager.RestAdapter.Endpoints.DoujinEndpoints|81.2%|75%| |DoujinManager.RestAdapter.Endpoints.ImageEndpoints|96.6%|50%| |DoujinManager.RestAdapter.Endpoints.MetadataEndpoints|84.2%|| |DoujinManager.RestAdapter.Endpoints.PaginationParams|100%|| |DoujinManager.RestAdapter.Endpoints.SearchEndpoints|100%|50%| |DoujinManager.RestAdapter.Endpoints.VariantEndpoints|69.9%|37.5%| |DoujinManager.RestAdapter.Envelopes.CollectionResponse`1|83.3%|| |DoujinManager.RestAdapter.Envelopes.EnvelopeDefaults|0%|| |DoujinManager.RestAdapter.Envelopes.EnvelopeJsonOptions|100%|| |DoujinManager.RestAdapter.Envelopes.ErrorResponse|100%|| |DoujinManager.RestAdapter.Envelopes.HypermediaAction|100%|| |DoujinManager.RestAdapter.Envelopes.HypermediaHelpers|87%|100%| |DoujinManager.RestAdapter.Envelopes.Link|100%|| |DoujinManager.RestAdapter.Envelopes.PageInfo|100%|| |DoujinManager.RestAdapter.Envelopes.ResourceResponse`1|80%|| |DoujinManager.RestAdapter.Envelopes.ValidationError|100%|| |DoujinManager.RestAdapter.Envelopes.ValidationErrorResponse|100%|| |DoujinManager.RestAdapter.Middleware.GlobalExceptionMiddleware|100%|50%| |DoujinManager.RestAdapter.Middleware.RequestLoggingMiddleware|100%|100%| |DoujinManager.RestAdapter.RestAdapterExtensions|100%|100%| |Microsoft.Extensions.Validation.Generated|78.6%|78.2%| |Microsoft.Extensions.Validation.Generated.<ValidatableInfoResolver_g>FB9B0C<br/>E5CB12CEAC5BBBEA65844E1C05F9ADA4DA38B848075C41304FC6A1ABF77__ValidationAttr<br/>ibuteCache|100%|62.5%| |System.Runtime.CompilerServices|0%|| </details> <details><summary>DoujinManager.Server - 20.9%</summary> |**Name**|**Line**|**Branch**| |:---|---:|---:| |**DoujinManager.Server**|**20.9%**|**0%**| |DoujinManager.Server.ImageInfrastructureRegistration|100%|| |DoujinManager.Server.ScalarUi|100%|| |DoujinManager.Server.UseCaseRegistrationHelper|100%|| |Microsoft.AspNetCore.OpenApi.Generated|0%|0%| |Program|0%|0%| |System.Runtime.CompilerServices|0%|| </details>
Author
Member

🤖 Hermes automated review: minor comments

Reviewed diff 5014af3...e4d9d5cb (+1802/-0, 43 files): Flutter project scaffold under app/ with dependencies from ADR 0017, stripped-down main.dart, and a smoke test. The vast majority of the diff is stock flutter create boilerplate (Android/Linux/Web platform dirs, pubspec.lock, CMake/Gradle configs); the hand-written files are pubspec.yaml, analysis_options.yaml, lib/main.dart, test/app_test.dart, and minor .metadata/README.md tweaks.

ADR 0017 compliance: All 10 declared dependencies are present with sensible caret constraints (redux, flutter_redux, redux_epics, dio, go_router, freezed_annotation, json_annotation, flutter_secure_storage, very_good_analysis, mocktail + dev codegen tools). Platform targets (Linux/Web/Android only) match ADR 0019 — no iOS/Windows/macOS dirs. pubspec.lock is correctly committed (best practice for apps). Static security scan clean (no secrets, injection, eval/exec, pickle, SQL formatting in added lines). No blocking issues — four minor non-blocking notes below.

Minor (non-blocking)

1. Android launcher label is lowercase "doujinmanager" while the app title is "DoujinManager"
app/android/app/src/main/AndroidManifest.xml:3android:label="doujinmanager"

The Android home-screen/launcher label is lowercase doujinmanager, but MaterialApp.title in lib/main.dart:13 is DoujinManager. On Android the launcher icon will read doujinmanager; everywhere else (web <title>, Linux window title via GTK) it derives from the proper-case title. Consider aligning the manifest label to DoujinManager for a consistent brand across platforms.

2. Release build signed with debug keys (template default)
app/android/app/build.gradle.kts:37signingConfig = signingConfigs.getByName("debug")

This is the stock flutter create template with its // TODO: Add your own signing config comment still present. Fine for a scaffold, but must be replaced before any Play Store / distribution build — debug-signed release APKs are not installable on stock devices and the signing key is publicly predictable. Flagging so it's tracked.

3. very_good_analysis pinned at ^6.0.0 — 4 major versions behind current
app/pubspec.yaml:31very_good_analysis: ^6.0.0

flutter pub get reports very_good_analysis 6.0.0 (10.3.0 available). The pinned release is from mid-2024; 10.x adds newer Dart 3.x lints (e.g. stricter implicit_call_tearoffs, document_ignores, updated avoid_print). ADR 0017 doesn't pin a version, so this is just an opportunity — not a defect. Worth bumping in a follow-up once the scaffold lands, since a major-version lint bump later may surface many new warnings at once.

4. CI workflow (ci.yml) does not yet cover the Flutter app
The forgejo-actions coverage comment (#345) reports only the four .NET assemblies (ApplicationCore, Infrastructure, RestAdapter, Server) — the app/ Flutter code has no CI gate. I confirmed flutter analyze and flutter test pass locally (see Verification below), but until ci.yml is extended to run flutter analyze/flutter test on the app/ directory, future Flutter changes will merge without automated lint/test coverage. Suggest adding a Flutter job to ci.yml in a near-term follow-up.

Verification

  • CI/CD (backend): forgejo-actions coverage comment #345 is current for head e4d9d5cb (line 83.8%, branch 49.8%; generated 06/29 16:42 UTC). The ci.yml test job posts coverage only on successful .NET build+test, so the backend build+test passed. Backend local build/test skipped per CI-evidence policy.
  • CI/CD (Flutter): No CI coverage exists for the app/ Flutter code (CI is absent for this path), so per the CI-absent policy I ran lightweight local checks with Flutter 3.44.4 / Dart 3.12.2:
    • flutter pub get resolved (29 packages have newer incompatible versions, all non-blocking)
    • flutter analyze No issues found! (12.4s)
    • flutter test 1/1 passed (App renders title)
  • Diff computed locally via git diff between base 5014af3 and head e4d9d5cb.
  • Static security scan: clean on added lines.

Note: This is a conversation comment, not a formal Forgejo review approval — the current MCP integration cannot create review approval states or inline diff comments.

Automated daily review. I never merge PRs.

## 🤖 Hermes automated review: minor comments Reviewed diff `5014af3...e4d9d5cb` (+1802/-0, 43 files): Flutter project scaffold under `app/` with dependencies from ADR 0017, stripped-down `main.dart`, and a smoke test. The vast majority of the diff is stock `flutter create` boilerplate (Android/Linux/Web platform dirs, `pubspec.lock`, CMake/Gradle configs); the hand-written files are `pubspec.yaml`, `analysis_options.yaml`, `lib/main.dart`, `test/app_test.dart`, and minor `.metadata`/`README.md` tweaks. **ADR 0017 compliance:** ✅ All 10 declared dependencies are present with sensible caret constraints (`redux`, `flutter_redux`, `redux_epics`, `dio`, `go_router`, `freezed_annotation`, `json_annotation`, `flutter_secure_storage`, `very_good_analysis`, `mocktail` + dev codegen tools). Platform targets (Linux/Web/Android only) match ADR 0019 — no iOS/Windows/macOS dirs. `pubspec.lock` is correctly committed (best practice for apps). Static security scan clean (no secrets, injection, eval/exec, pickle, SQL formatting in added lines). No blocking issues — four minor non-blocking notes below. ### Minor (non-blocking) **1. Android launcher label is lowercase `"doujinmanager"` while the app title is `"DoujinManager"`** `app/android/app/src/main/AndroidManifest.xml:3` — `android:label="doujinmanager"` The Android home-screen/launcher label is lowercase `doujinmanager`, but `MaterialApp.title` in `lib/main.dart:13` is `DoujinManager`. On Android the launcher icon will read `doujinmanager`; everywhere else (web `<title>`, Linux window title via GTK) it derives from the proper-case title. Consider aligning the manifest label to `DoujinManager` for a consistent brand across platforms. **2. Release build signed with debug keys (template default)** `app/android/app/build.gradle.kts:37` — `signingConfig = signingConfigs.getByName("debug")` This is the stock `flutter create` template with its `// TODO: Add your own signing config` comment still present. Fine for a scaffold, but must be replaced before any Play Store / distribution build — debug-signed release APKs are not installable on stock devices and the signing key is publicly predictable. Flagging so it's tracked. **3. `very_good_analysis` pinned at `^6.0.0` — 4 major versions behind current** `app/pubspec.yaml:31` — `very_good_analysis: ^6.0.0` `flutter pub get` reports `very_good_analysis 6.0.0 (10.3.0 available)`. The pinned release is from mid-2024; 10.x adds newer Dart 3.x lints (e.g. stricter `implicit_call_tearoffs`, `document_ignores`, updated `avoid_print`). ADR 0017 doesn't pin a version, so this is just an opportunity — not a defect. Worth bumping in a follow-up once the scaffold lands, since a major-version lint bump later may surface many new warnings at once. **4. CI workflow (`ci.yml`) does not yet cover the Flutter app** The forgejo-actions coverage comment (#345) reports only the four .NET assemblies (ApplicationCore, Infrastructure, RestAdapter, Server) — the `app/` Flutter code has no CI gate. I confirmed `flutter analyze` and `flutter test` pass locally (see Verification below), but until `ci.yml` is extended to run `flutter analyze`/`flutter test` on the `app/` directory, future Flutter changes will merge without automated lint/test coverage. Suggest adding a Flutter job to `ci.yml` in a near-term follow-up. ### Verification - **CI/CD (backend):** forgejo-actions coverage comment #345 is current for head `e4d9d5cb` (line 83.8%, branch 49.8%; generated 06/29 16:42 UTC). The `ci.yml` test job posts coverage only on successful .NET build+test, so the backend build+test passed. **Backend local build/test skipped per CI-evidence policy.** - **CI/CD (Flutter):** No CI coverage exists for the `app/` Flutter code (CI is absent for this path), so per the CI-absent policy I ran lightweight local checks with Flutter 3.44.4 / Dart 3.12.2: - `flutter pub get` → ✅ resolved (29 packages have newer incompatible versions, all non-blocking) - `flutter analyze` → ✅ **No issues found!** (12.4s) - `flutter test` → ✅ **1/1 passed** (`App renders title`) - Diff computed locally via `git diff` between base `5014af3` and head `e4d9d5cb`. - Static security scan: clean on added lines. *Note: This is a conversation comment, not a formal Forgejo review approval — the current MCP integration cannot create review approval states or inline diff comments.* *Automated daily review. I never merge PRs.*
fix: Android label casing, bump very_good_analysis to 10.0.0
All checks were successful
CI / build (pull_request) Successful in 17s
CI / test (pull_request) Successful in 44s
98fe17b223
1. Android launcher label: 'doujinmanager' → 'DoujinManager' (brand consistency)
2. very_good_analysis: ^6.0.0 → ^10.0.0 (latest, stricter lints, 0 new issues)
Author
Member

Addressed findings in commit 98fe17b. flutter analyze 0 issues, flutter test 1/1 pass.

#1 — Android launcher label Fixed: doujinmanagerDoujinManager

#2 — Release signing config 📝 Tracked — template default, will be replaced before any distribution build. Not relevant for scaffold.

#3 — very_good_analysis Bumped: ^6.0.0^10.0.0 (latest). Zero new issues.

#4 — Flutter CI job 📝 Tracked — will add a Flutter job to ci.yml in a near-term follow-up once there's more app code to gate.

Addressed findings in commit `98fe17b`. `flutter analyze` 0 issues, `flutter test` 1/1 pass. **#1 — Android launcher label** ✅ Fixed: `doujinmanager` → `DoujinManager` **#2 — Release signing config** 📝 Tracked — template default, will be replaced before any distribution build. Not relevant for scaffold. **#3 — very_good_analysis** ✅ Bumped: `^6.0.0` → `^10.0.0` (latest). Zero new issues. **#4 — Flutter CI job** 📝 Tracked — will add a Flutter job to `ci.yml` in a near-term follow-up once there's more app code to gate.
ci: limit backend and docker jobs to relevant path changes
All checks were successful
CI / build (pull_request) Successful in 17s
CI / test (pull_request) Successful in 37s
3f550660eb
Backend CI (build+test) now only runs when backend/** or ci.yml changes.
Docker publish now only runs when backend/**, deploy/Dockerfile, or
docker-publish.yml changes.

This avoids unnecessary builds when only the Flutter app or docs change.
Author
Member

🤖 Hermes automated review: no blocking issues found

Follow-up review of commits 98fe17b and 3f55066 (incremental diff e4d9d5cb...3f550660, since the prior review). All actionable findings from the previous review are resolved; one new non-blocking observation on the path-filter change.

Prior findings — status

  • #1 Android launcher label Fixed in 98fe17b: app/android/app/src/main/AndroidManifest.xml:3 now android:label="DoujinManager" (matches MaterialApp.title).
  • #3 very_good_analysis 6.0.0 → 10.3.0 Bumped and verified in 98fe17b: app/pubspec.yaml:30 now very_good_analysis: ^10.0.0, pubspec.lock updated to 10.3.0. A 4-major-version lint bump is exactly where you'd expect new analyzer violations, so I ran the linter locally — flutter analyze → "No issues found!" with 10.3.0. Clean.
  • #2 Release signing config 📝 Acknowledged as tracked (template default; deferred to a distribution-build PR). No change expected now.
  • #4 Flutter CI job 📝 Acknowledged as tracked for a follow-up. See new note on the path-filter change below.

Minor (non-blocking) — new

1. Path filter on ci.yml means a Flutter-only PR still won't run any CI, and the docker-publish.yml path filter omits app/ entirely (intended) but also omits .dockerignore
.github/workflows/ci.yml:6-9 and .github/workflows/docker-publish.yml:6-9

The new paths filters correctly scope the backend CI and docker publish jobs to backend/** + their own workflow file — this is a good optimization and avoids redundant runs for docs/app-only changes. Two observations:

  • This reinforces the still-open finding #4: until a dedicated Flutter CI job is added, the app/ directory has zero CI gating (the path filter now makes that explicit rather than implicit). The local flutter analyze/flutter test I ran here is the only check the Flutter code currently gets.
  • docker-publish.yml paths list backend/**, deploy/Dockerfile, and the workflow file, but not .dockerignore. A change to .dockerignore alone won't trigger a container rebuild. Likely fine (.dockerignore changes are rare and usually paired with Dockerfile changes), just noting the gap.

Neither is actionable for this scaffold PR — flagging for when the Flutter CI job is added.

Verification

  • CI/CD (backend): The forgejo-actions coverage comment #345 has a coverage date of 06/29 17:00 UTC, which predates the fix commits (98fe17b at 18:57 UTC, 3f55066 after). It is therefore stale for head 3f550660. Per the stale-CI policy, I ran lightweight local checks for the changed Flutter code:
    • flutter pub get resolved (28 packages have newer incompatible versions, all non-blocking)
    • flutter analyze (very_good_analysis 10.3.0) → No issues found!
    • flutter test 1/1 passed (App renders title)
  • Diff computed locally via git diff between prior head e4d9d5cb and current head 3f550660.
  • Static security scan: clean on added lines (no secrets, injection, eval/exec, pickle, SQL formatting).

Note: This is a conversation comment, not a formal Forgejo review approval — the current MCP integration cannot create review approval states or inline diff comments.

Automated daily review. I never merge PRs.

## 🤖 Hermes automated review: no blocking issues found Follow-up review of commits `98fe17b` and `3f55066` (incremental diff `e4d9d5cb...3f550660`, since the prior review). All actionable findings from the previous review are resolved; one new non-blocking observation on the path-filter change. ### Prior findings — status - **#1 Android launcher label** ✅ **Fixed** in `98fe17b`: `app/android/app/src/main/AndroidManifest.xml:3` now `android:label="DoujinManager"` (matches `MaterialApp.title`). - **#3 `very_good_analysis` 6.0.0 → 10.3.0** ✅ **Bumped and verified** in `98fe17b`: `app/pubspec.yaml:30` now `very_good_analysis: ^10.0.0`, `pubspec.lock` updated to 10.3.0. A 4-major-version lint bump is exactly where you'd expect new analyzer violations, so I ran the linter locally — **`flutter analyze` → "No issues found!"** with 10.3.0. Clean. - **#2 Release signing config** 📝 Acknowledged as tracked (template default; deferred to a distribution-build PR). No change expected now. - **#4 Flutter CI job** 📝 Acknowledged as tracked for a follow-up. See new note on the path-filter change below. ### Minor (non-blocking) — new **1. Path filter on `ci.yml` means a Flutter-only PR still won't run *any* CI, and the `docker-publish.yml` path filter omits `app/` entirely (intended) but also omits `.dockerignore`** `.github/workflows/ci.yml:6-9` and `.github/workflows/docker-publish.yml:6-9` The new `paths` filters correctly scope the backend CI and docker publish jobs to `backend/**` + their own workflow file — this is a good optimization and avoids redundant runs for docs/app-only changes. Two observations: - This reinforces the still-open finding #4: until a dedicated Flutter CI job is added, the `app/` directory has **zero** CI gating (the path filter now makes that explicit rather than implicit). The local `flutter analyze`/`flutter test` I ran here is the only check the Flutter code currently gets. - `docker-publish.yml` paths list `backend/**`, `deploy/Dockerfile`, and the workflow file, but **not** `.dockerignore`. A change to `.dockerignore` alone won't trigger a container rebuild. Likely fine (`.dockerignore` changes are rare and usually paired with Dockerfile changes), just noting the gap. Neither is actionable for this scaffold PR — flagging for when the Flutter CI job is added. ### Verification - **CI/CD (backend):** The forgejo-actions coverage comment #345 has a coverage date of 06/29 17:00 UTC, which **predates** the fix commits (98fe17b at 18:57 UTC, 3f55066 after). It is therefore **stale** for head `3f550660`. Per the stale-CI policy, I ran lightweight local checks for the changed Flutter code: - `flutter pub get` → ✅ resolved (28 packages have newer incompatible versions, all non-blocking) - `flutter analyze` (very_good_analysis 10.3.0) → ✅ **No issues found!** - `flutter test` → ✅ **1/1 passed** (`App renders title`) - Diff computed locally via `git diff` between prior head `e4d9d5cb` and current head `3f550660`. - Static security scan: clean on added lines (no secrets, injection, eval/exec, pickle, SQL formatting). *Note: This is a conversation comment, not a formal Forgejo review approval — the current MCP integration cannot create review approval states or inline diff comments.* *Automated daily review. I never merge PRs.*
bjoern merged commit 7907427af9 into main 2026-06-29 20:04:14 +02:00
bjoern deleted branch feat/flutter-scaffold 2026-06-29 20:04:14 +02:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
TeamAI/doujin-manager!22
No description provided.