Skip to content

Starred to highlight#4106

Merged
ildyria merged 9 commits intomasterfrom
starred_to_highlight
Feb 24, 2026
Merged

Starred to highlight#4106
ildyria merged 9 commits intomasterfrom
starred_to_highlight

Conversation

@ildyria
Copy link
Member

@ildyria ildyria commented Feb 22, 2026

closes #4104

Summary by CodeRabbit

  • Refactor
    • Renamed the "Starred" concept to "Highlighted" across the app (albums, badges, filters, buttons, menus, and emitted events).
    • Photo actions and UI controls now use "Highlight"/"Unhighlight" instead of "Star"/"Unstar".
    • Updated related API endpoints and services reflecting the "highlight" terminology.
  • Chores
    • Updated settings labels and translations in 22 languages to reflect "Highlighted".
  • Docs
    • Updated user-facing docs and specs to use "Highlighted" terminology.
  • Bug Fixes
    • Added five new star SVG icons for better UI badge representation.
  • New Features
    • Added UI badge sets for rating-based albums and photo highlight status.
    • Introduced a highlight filter toggle in the photo thumbnail panel.

- Migration: convert is_starred → is_highlighted column with ratings backfill
- PHP enums, models, DTOs, pipes, controllers, requests, resources updated
- SmartAlbums: HighlightedAlbum replaces StarredAlbum
- TypeScript types, stores, composables, Vue components all updated
- 22 language translation files updated
- All related test files updated

Spec impact: docs/specs/4-architecture/features/013-starred-to-highlighted/
@coderabbitai
Copy link

coderabbitai bot commented Feb 22, 2026

📝 Walkthrough

Walkthrough

Renames the "starred" concept to "highlighted" across the codebase: DB column and migrations, models/DTOs/enums, action pipes, HTTP layer (requests/resources/controller/routes), policies, frontend (Vue, services, stores, types), translations, docs, and tests. Adds migrations that migrate data and recreate indexes.

Changes

Cohort / File(s) Summary
Database migrations
database/migrations/2026_02_22_090000_drop_old_album_id_from_photos.php, database/migrations/2026_02_22_100000_rename_starred_to_highlighted.php
Add migrations to drop legacy old_album_id, rename photos.is_starredphotos.is_highlighted, perform chunked data migration (insert 5-star ratings & recompute averages), and recreate/dropping indexes.
Models, factories & DB-related code
app/Models/Photo.php, app/Models/Extensions/Thumb.php, database/factories/PhotoFactory.php, app/Models/BaseAlbumImpl.php
Replace is_starred with is_highlighted in casts, annotations and ordering; adjust query helpers and PHPDoc return types.
Enums & smart-album classes
app/Enum/*, app/SmartAlbums/HighlightedAlbum.php, app/SmartAlbums/BaseSmartAlbum.php, app/Factories/AlbumFactory.php
Rename enum cases (STARRED→HIGHLIGHTED), replace StarredAlbum with HighlightedAlbum, and update factory mapping and smart-album predicates to use is_highlighted.
DTOs, pipes & photo creation flow
app/DTO/*, app/Actions/Photo/Pipes/Shared/SetHighlighted.php, app/Actions/Photo/Create.php, app/Actions/Photo/Pipes/...
Constructor-promoted properties and DTO fields renamed to is_highlighted; pipeline step SetStarredSetHighlighted and state assignment updated; Create pipelines now use SetHighlighted.
HTTP layer, routes & contracts
app/Contracts/Http/Requests/RequestAttribute.php, app/Http/Requests/Photo/SetPhotosHighlightedRequest.php, app/Http/Resources/Models/PhotoResource.php, app/Http/Resources/Rights/RootAlbumRightsResource.php, app/Http/Controllers/Gallery/PhotoController.php, routes/api_v2.php
Request attribute constant and request class renamed; PhotoResource and rights properties renamed; controller action starhighlight; route POST /Photo::star/Photo::highlight.
Policies & authorization traits
app/Policies/AlbumPolicy.php, app/Policies/PhotoPolicy.php, app/Http/Requests/Traits/Authorize/AuthorizeCanHighlightPhotosTrait.php
Permission constants and methods renamed (CAN_STARCAN_HIGHLIGHT, canStarcanHighlight); authorization trait renamed and checks updated to can_highlight.
Backend jobs & docs
app/Jobs/RecomputeAlbumStatsJob.php, app/Contracts/Models/AbstractAlbum.php, app/SmartAlbums/README.md, docs under docs/specs/**
Job ordering and docblocks updated to is_highlighted; architecture/docs/specs/ADR updated to reflect renamed concept and migration plan.
Frontend components, services & types
resources/js/components/**, resources/js/views/**, resources/js/composables/**, resources/js/services/photo-service.ts, resources/js/lychee.d.ts, resources/js/config/constants.ts
All UI handlers, events, emitted names and service methods renamed from star→highlight (e.g., toggleStartoggleHighlight, PhotoService.starPhotoService.highlight); types and sorting option updated to is_highlighted.
Stores & state
resources/js/stores/AlbumState.ts, resources/js/stores/PhotosState.ts
Removed showStarredOnly; rating filter option "starred""highlighted"; getters and counts renamed to reflect highlighted photos.
UI assets & badges
resources/views/includes/svg.blade.php, resources/js/components/gallery/albumModule/thumbs/*
Added star-rating SVG symbols; replaced starred badge with highlighted/flag icon and added rating badges; badge rendering and permission checks updated.
Translations
lang/*/all_settings.php, lang/*/gallery.php (multiple locales)
Rename translation keys: enable_starredenable_highlighted; starred/star/unstarhighlighted/highlight/unhighlight across locales.
Tests & constants
tests/**, tests/Constants/TestConstants.php
Tests updated to call new endpoint/payload (Photo::highlight, is_highlighted), smart-album id highlighted; TestConstants entries adjusted; many test fixtures/expectations renamed.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Poem

🐰 I hopped through code with tiny paws,
Swapping stars for flags because,
DB and UI, docs in flight,
Languages twenty-two sing bright,
Hop — the gallery gleams in highlight. ✨

🚥 Pre-merge checks | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 65.71% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@ildyria ildyria marked this pull request as ready for review February 23, 2026 23:50
@ildyria ildyria requested a review from a team as a code owner February 23, 2026 23:50
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 14

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (13)
docs/specs/1-concepts/system.md (1)

294-294: ⚠️ Potential issue | 🟡 Minor

Update the stale "Last updated" date.

The date still reads December 22, 2025, but this file is being modified in a PR opened on February 22, 2026. As per coding guidelines, the date must reflect the actual date of the update.

📝 Proposed fix
-*Last updated: December 22, 2025*
+*Last updated: February 22, 2026*
docs/specs/3-reference/frontend-gallery.md (2)

47-47: ⚠️ Potential issue | 🟡 Minor

Residual "Star" references in context-menu docs not updated.

Lines 47 and 475 still list Star as a photo operation / context-menu item. These should be updated to Highlight to stay consistent with the PR rename.

📝 Proposed fix
-  - **Photo Operations**: Star, rotate, tag, copy, move, delete
+  - **Photo Operations**: Highlight, rotate, tag, copy, move, delete
-  - **Photo Context**: Star, Rotate, Tag, Copy, Move, Delete
+  - **Photo Context**: Highlight, Rotate, Tag, Copy, Move, Delete

Also applies to: 475-475


517-517: ⚠️ Potential issue | 🟡 Minor

Stale "Last updated" date.

The file was modified in this PR but the date at the bottom still reads December 22, 2025. As per coding guidelines, the "Last updated" line must reflect the date of the update.

📝 Proposed fix
-*Last updated: December 22, 2025*
+*Last updated: February 22, 2026*
docs/specs/6-decisions/ADR-0003-album-computed-fields-precomputation.md (1)

5-5: ⚠️ Potential issue | 🟡 Minor

Stale Last updated field in ADR header.

The file was modified in this PR but the header still reads 2025-12-28. As per coding guidelines, the "Last updated" value must reflect the date of the current update.

📝 Proposed fix
-- **Last updated:** 2025-12-28
+- **Last updated:** 2026-02-22
docs/specs/1-concepts/albums.md (1)

312-312: ⚠️ Potential issue | 🟡 Minor

Stale "Last updated" date.

The file was modified in this PR but the footer still reads December 22, 2025. As per coding guidelines, this must reflect the date of the update.

📝 Proposed fix
-*Last updated: December 22, 2025*
+*Last updated: February 22, 2026*
resources/js/views/gallery-panels/Album.vue (1)

30-39: ⚠️ Potential issue | 🔴 Critical

Update listener to match PhotoPanel's emitted event name.
PhotoPanel emits toggleHighlight, but the listener is set to @toggle-star. This mismatch means the handler will never fire.

✅ Fix
-		`@toggle-star`="toggleHighlight"
+		`@toggle-highlight`="toggleHighlight"
docs/specs/3-reference/frontend-architecture.md (1)

694-694: ⚠️ Potential issue | 🟡 Minor

Stale "Last updated" date.

The file was modified in this PR but the date still reads "December 22, 2025". As per coding guidelines, this should be updated.

📝 Proposed fix
-*Last updated: December 22, 2025*
+*Last updated: February 22, 2026*

As per coding guidelines: "At the bottom of documentation files, add an hr line followed by 'Last updated: [date of the update]'".

docs/specs/1-concepts/photos.md (1)

24-34: ⚠️ Potential issue | 🟡 Minor

Update the “Last updated” date for this doc.
Since this file changed, the footer date should be refreshed (e.g., February 23, 2026).

Suggested footer update
-*Last updated: December 22, 2025*
+*Last updated: February 23, 2026*

As per coding guidelines “At the bottom of documentation files, add an hr line followed by "Last updated: [date of the update]".”

app/SmartAlbums/README.md (1)

241-241: ⚠️ Potential issue | 🟡 Minor

Update the stale "Last updated" date.

The date still reads "August 14, 2025" but this file was modified in a February 2026 PR. As per coding guidelines, the footer should reflect the actual update date.

-*Last updated: August 14, 2025*
+*Last updated: February 2026*
docs/specs/4-architecture/knowledge-map.md (1)

154-246: ⚠️ Potential issue | 🟡 Minor

Update the “Last updated” date to reflect this change.

The document was modified, but the footer still shows January 14, 2026. Please refresh it to the current update date (e.g., February 22, 2026 or February 23, 2026).
As per coding guidelines, “At the bottom of documentation files, add an hr line followed by Last updated: [date of the update].”

📝 Suggested footer update
-*Last updated: January 14, 2026*
+*Last updated: February 22, 2026*
docs/specs/3-reference/database-schema.md (1)

90-246: ⚠️ Potential issue | 🟡 Minor

Refresh the “Last updated” footer date.

This document changed but still shows January 21, 2026. Please update the footer to reflect this change.
As per coding guidelines, “At the bottom of documentation files, add an hr line followed by Last updated: [date of the update].”

📝 Suggested footer update
-*Last updated: January 21, 2026*
+*Last updated: February 22, 2026*
resources/js/views/gallery-panels/Tag.vue (1)

9-18: ⚠️ Potential issue | 🟠 Major

Change the PhotoPanel event binding from @toggle-star to @toggle-highlight.

PhotoPanel defines toggleHighlight in its emits (line 75 of PhotoPanel.vue), not toggle-star. The internal child components use @toggle-star, but PhotoPanel converts that to emit toggleHighlight to its parent. Tag.vue must listen to the correct emitted event.

Fix
-		`@toggle-star`="toggleHighlight"
+		`@toggle-highlight`="toggleHighlight"

This same issue affects Album.vue, Search.vue, and Timeline.vue—all should change @toggle-star to @toggle-highlight when binding PhotoPanel.

app/Policies/PhotoPolicy.php (1)

264-274: ⚠️ Potential issue | 🟡 Minor

Docblock still references “star” after rename.
Update the wording to avoid confusion.

✏️ Suggested docblock wording update
-	 * A photo is called _highlighted_ if the current user is allowed to star
-	 * the photo.
+	 * A photo is called _highlighted_ if the current user is allowed to highlight
+	 * the photo.
...
-	 * - the settings is set to allow anonymous users to star photos
-	 * - the settings is set to allow authenticated users to star photos and the user is authenticated
-	 * - the settings is set to allow editors to star photos and the user is an editor
+	 * - the settings is set to allow anonymous users to highlight photos
+	 * - the settings is set to allow authenticated users to highlight photos and the user is authenticated
+	 * - the settings is set to allow editors to highlight photos and the user is an editor

Also applies to: 282-282

🧹 Nitpick comments (11)
lang/bg/gallery.php (1)

45-45: All key renames are structurally correct — minor translation-term inconsistency.

The nine key renames (starred → highlighted, star/unstar → highlight/unhighlight, etc.) are complete and the PHP array syntax is valid.

One optional note: lines 45, 99, 153, 233, and 235 all use the отбелязан- word root, but:

  • Line 100 (copy_highlighted_names) uses маркираните (a synonymous but different root).
  • Lines 154 and 234 (unhighlight / unhighlight_all) use отметка / отметките (literally "tick/checkmark"), which is slightly different semantically.

If you want full consistency, aligning these to отбелязани/отбележи throughout would read more uniformly. That said, all are understandable Bulgarian, so this is entirely optional.

Based on learnings, ildyria does not prioritize strict localization consistency for translation files, so no action is required.

Also applies to: 99-100, 153-154, 233-236

lang/ja/all_settings.php (1)

127-127: Stale + typo in SA_random_thumbs doc string not caught by the rename.

Line 127 still reads 'stared/sorting order'stared is a typo of starred, and since this PR renames the whole concept to "highlighted", the string should be updated accordingly.

✏️ Suggested fix
-        'SA_random_thumbs' => 'Use random thumbs instead of stared/sorting order.',
+        'SA_random_thumbs' => 'Use random thumbs instead of highlighted/sorting order.',
resources/views/includes/svg.blade.php (1)

199-203: Consider adding a star-0 symbol for the "no rating" state.

The PR introduces a 1–5 rating system. If the UI needs to represent an unrated photo (rating = 0 / null) with a consistent icon — e.g. an empty or greyed-out star badge — there is currently no star-0 symbol. The existing star symbol (line 198) is a full-size star and doesn't match the mini-star badge style of the new series.

resources/js/components/gallery/albumModule/PhotoThumbPanelControl.vue (1)

3-16: Consider hiding the highlighted button when there are no highlighted photos.

The star rating filter (lines 17-36) is gated by v-if="photosStore.hasRatedPhotos", but the highlighted filter button is visible whenever the user has the right permissions, even if highlightedPhotosCount is 0. This shows a "🏳 0" button that may confuse users when no photos are highlighted.

Consider adding && photosStore.highlightedPhotosCount > 0 to the v-if condition, or a similar computed check, to mirror the star filter's behavior.

Suggested change
 	<div
 		class="inline-flex items-center gap-0.5 pr-2 mr-2 border-r border-neutral-300 dark:border-neutral-600 h-8"
-		v-if="lycheeStore.is_se_enabled && (albumsStore.rootRights?.can_highlight || albumStore.album?.rights?.can_edit)"
+		v-if="lycheeStore.is_se_enabled && (albumsStore.rootRights?.can_highlight || albumStore.album?.rights?.can_edit) && photosStore.highlightedPhotosCount > 0"
 	>
lang/es/gallery.php (1)

45-45: Translation value retained from the old starred key.

'Sembrado de estrellas' (literally "strewn with stars") was the pre-existing label and is now reused under the highlighted key. Consider updating this to a semantically accurate Spanish equivalent (e.g., "Destacadas") in a follow-up.

lang/zh_TW/gallery.php (1)

153-154: Values still use "Star"/"Unstar" under the renamed highlight/unhighlight keys.

lang/zh_TW/gallery.php was already using English fallbacks for these entries and that hasn't changed. Consider updating these (and the corresponding menus entries at Lines 233–236) to reflect "highlight" semantics in a follow-up translation pass.

lang/de/gallery.php (1)

152-153: Inconsistency between photo.actions and menus translations.

photo.actions.highlight"Mit Stern bewerten" (Rate with a star) while menus.highlight"Favorit hinzufügen" (Add to favorites). This discrepancy is pre-existing (carried forward values) but now more visible under the unified highlight/highlighted key set. Consider aligning them in a follow-up translation pass.

database/migrations/2026_02_22_100000_rename_starred_to_highlighted.php (2)

93-104: Step 2: Rating recomputation issues N+1 queries per chunk but acceptable for a one-time migration.

Each row triggers a separate UPDATE (line 100-102). For very large datasets this could be slow. A single raw UPDATE ... JOIN would be faster, but for a migration this is fine.

♻️ Optional: single UPDATE with JOIN (MySQL/PostgreSQL)

For MySQL:

UPDATE photos
JOIN statistics ON photos.id = statistics.photo_id
SET photos.rating_avg = ROUND(statistics.rating_sum / statistics.rating_count, 4)
WHERE statistics.rating_count > 0;

For PostgreSQL:

UPDATE photos
SET rating_avg = ROUND(statistics.rating_sum::numeric / statistics.rating_count, 4)
FROM statistics
WHERE photos.id = statistics.photo_id AND statistics.rating_count > 0;

This would replace the entire chunk loop with a single statement.


124-135: Index names contain album_id but the indexes no longer include album_id column.

The index names like photos_album_id_is_highlighted_index (line 126) are misleading since album_id was dropped in the prior migration and these indexes only cover is_highlighted (+ other columns). This was inherited from the earlier migration, but it could cause confusion for future maintainers.

resources/js/composables/contextMenus/contextMenu.ts (1)

21-32: PhotoCallbacks type still uses star/unstar — rename to highlight/unhighlight for consistency.

The feature has been renamed throughout the stack, but the exported PhotoCallbacks type and the property references on lines 99, 106, 199, and 206 still use the old names. This creates a mismatch between the external API name and the feature semantics.

♻️ Proposed rename
 export type PhotoCallbacks = {
-	star: () => void;
-	unstar: () => void;
+	highlight: () => void;
+	unhighlight: () => void;
 	setAsCover: () => void;

And update the four usages in photoMenu and photosMenu:

-			callback: photoCallbacks.unstar,
+			callback: photoCallbacks.unhighlight,
-			callback: photoCallbacks.star,
+			callback: photoCallbacks.highlight,

Note: all call sites that pass a PhotoCallbacks object will need a corresponding rename.

resources/js/composables/album/photoActions.ts (1)

15-28: Rename newStarValue to match highlight semantics.
Keeps terminology consistent after the star → highlight rename.

♻️ Suggested rename for clarity
-		const newStarValue = !photoStore.photo.is_highlighted;
-		PhotoService.highlight([photoStore.photo.id], newStarValue).then(() => {
+		const newHighlightValue = !photoStore.photo.is_highlighted;
+		PhotoService.highlight([photoStore.photo.id], newHighlightValue).then(() => {
 			// Update the current photo store
-			photoStore.photo!.is_highlighted = newStarValue;
+			photoStore.photo!.is_highlighted = newHighlightValue;

 			// Update the photo in the album list (photosStore) to keep it in sync
 			const photoIndex = photosStore.photos.findIndex((p) => p.id === photoStore.photo!.id);
 			if (photoIndex !== -1) {
-				photosStore.photos[photoIndex].is_highlighted = newStarValue;
+				photosStore.photos[photoIndex].is_highlighted = newHighlightValue;
 			}

Also applies to: 102-103


ℹ️ Review info

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between dd69f18 and 63ad01d.

📒 Files selected for processing (125)
  • app/Actions/Photo/Create.php
  • app/Actions/Photo/Pipes/Init/InitParentAlbum.php
  • app/Actions/Photo/Pipes/Shared/SetHighlighted.php
  • app/Contracts/Http/Requests/RequestAttribute.php
  • app/Contracts/Models/AbstractAlbum.php
  • app/DTO/ImportParam.php
  • app/DTO/PhotoCreate/DuplicateDTO.php
  • app/DTO/PhotoCreate/InitDTO.php
  • app/DTO/PhotoCreate/StandaloneDTO.php
  • app/Enum/ColumnSortingPhotoType.php
  • app/Enum/ColumnSortingType.php
  • app/Enum/SmartAlbumType.php
  • app/Factories/AlbumFactory.php
  • app/Http/Controllers/Gallery/PhotoController.php
  • app/Http/Requests/Photo/SetPhotosHighlightedRequest.php
  • app/Http/Requests/Traits/Authorize/AuthorizeCanHighlightPhotosTrait.php
  • app/Http/Resources/Models/PhotoResource.php
  • app/Http/Resources/Rights/RootAlbumRightsResource.php
  • app/Jobs/RecomputeAlbumStatsJob.php
  • app/Models/BaseAlbumImpl.php
  • app/Models/Extensions/Thumb.php
  • app/Models/Photo.php
  • app/Policies/AlbumPolicy.php
  • app/Policies/PhotoPolicy.php
  • app/SmartAlbums/BaseSmartAlbum.php
  • app/SmartAlbums/HighlightedAlbum.php
  • app/SmartAlbums/README.md
  • database/factories/PhotoFactory.php
  • database/migrations/2026_02_22_090000_drop_old_album_id_from_photos.php
  • database/migrations/2026_02_22_100000_rename_starred_to_highlighted.php
  • docs/specs/1-concepts/albums.md
  • docs/specs/1-concepts/photos.md
  • docs/specs/1-concepts/system.md
  • docs/specs/3-reference/api-design.md
  • docs/specs/3-reference/database-schema.md
  • docs/specs/3-reference/frontend-architecture.md
  • docs/specs/3-reference/frontend-gallery.md
  • docs/specs/4-architecture/backend-architecture.md
  • docs/specs/4-architecture/features/013-starred-to-highlighted/plan.md
  • docs/specs/4-architecture/features/013-starred-to-highlighted/spec.md
  • docs/specs/4-architecture/features/013-starred-to-highlighted/tasks.md
  • docs/specs/4-architecture/knowledge-map.md
  • docs/specs/6-decisions/ADR-0003-album-computed-fields-precomputation.md
  • lang/ar/all_settings.php
  • lang/ar/gallery.php
  • lang/bg/all_settings.php
  • lang/bg/gallery.php
  • lang/cz/all_settings.php
  • lang/cz/gallery.php
  • lang/de/all_settings.php
  • lang/de/gallery.php
  • lang/el/all_settings.php
  • lang/el/gallery.php
  • lang/en/all_settings.php
  • lang/en/gallery.php
  • lang/es/all_settings.php
  • lang/es/gallery.php
  • lang/fa/all_settings.php
  • lang/fa/gallery.php
  • lang/fr/all_settings.php
  • lang/fr/gallery.php
  • lang/hu/all_settings.php
  • lang/hu/gallery.php
  • lang/it/all_settings.php
  • lang/it/gallery.php
  • lang/ja/all_settings.php
  • lang/ja/gallery.php
  • lang/nl/all_settings.php
  • lang/nl/gallery.php
  • lang/no/all_settings.php
  • lang/no/gallery.php
  • lang/pl/all_settings.php
  • lang/pl/gallery.php
  • lang/pt/all_settings.php
  • lang/pt/gallery.php
  • lang/ru/all_settings.php
  • lang/ru/gallery.php
  • lang/sk/all_settings.php
  • lang/sk/gallery.php
  • lang/sv/all_settings.php
  • lang/sv/gallery.php
  • lang/vi/all_settings.php
  • lang/vi/gallery.php
  • lang/zh_CN/all_settings.php
  • lang/zh_CN/gallery.php
  • lang/zh_TW/all_settings.php
  • lang/zh_TW/gallery.php
  • resources/js/components/gallery/albumModule/AlbumListItem.vue
  • resources/js/components/gallery/albumModule/AlbumPanel.vue
  • resources/js/components/gallery/albumModule/PhotoThumbPanelControl.vue
  • resources/js/components/gallery/albumModule/thumbs/AlbumThumb.vue
  • resources/js/components/gallery/albumModule/thumbs/PhotoThumb.vue
  • resources/js/components/gallery/photoModule/Dock.vue
  • resources/js/components/gallery/photoModule/PhotoPanel.vue
  • resources/js/components/gallery/tagModule/TagPanel.vue
  • resources/js/components/headers/AlbumHeader.vue
  • resources/js/components/headers/PhotoHeader.vue
  • resources/js/composables/album/photoActions.ts
  • resources/js/composables/contextMenus/contextMenu.ts
  • resources/js/config/constants.ts
  • resources/js/lychee.d.ts
  • resources/js/services/photo-service.ts
  • resources/js/stores/AlbumState.ts
  • resources/js/stores/PhotosState.ts
  • resources/js/views/gallery-panels/Album.vue
  • resources/js/views/gallery-panels/Search.vue
  • resources/js/views/gallery-panels/Tag.vue
  • resources/js/views/gallery-panels/Timeline.vue
  • resources/views/includes/svg.blade.php
  • routes/api_v2.php
  • tests/Constants/TestConstants.php
  • tests/Feature_v2/Album/AlbumHeadEndpointTest.php
  • tests/Feature_v2/Frame/FrameTest.php
  • tests/Feature_v2/SmartAlbums/OverridePermissionsTest.php
  • tests/ImageProcessing/Photo/PhotoStarTest.php
  • tests/Precomputing/CoverSelection/Console/AlbumMutationScenariosTest.php
  • tests/Precomputing/CoverSelection/Console/CoverDisplayPermissionTest.php
  • tests/Precomputing/CoverSelection/Console/ExplicitCoverTest.php
  • tests/Precomputing/CoverSelection/CoverSelectionNsfwTest.php
  • tests/Precomputing/CoverSelection/DeepNestingPropagationTest.php
  • tests/Precomputing/CoverSelection/RecomputeAlbumStatsJobTest.php
  • tests/Unit/CoverageTest.php
  • tests/Unit/Enum/SmartAlbumTypeTest.php
  • tests/Unit/Rules/AlbumIDListRuleTest.php
  • tests/Unit/Rules/AlbumIDRuleTest.php
💤 Files with no reviewable changes (1)
  • tests/Constants/TestConstants.php

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (1)
database/migrations/2026_02_22_100000_rename_starred_to_highlighted.php (1)

55-86: ⚠️ Potential issue | 🔴 Critical

$insert is overwritten on every iteration — only the last starred photo per chunk gets a rating row (still unresolved from the previous review).

The three interrelated bugs remain:

  1. Line 67: $insert = [...] replaces the array each loop; only the final non-skipped photo ends up in $insert.
  2. Line 75: insert($insert) is called unconditionally, even when all chunk photos were skipped and $insert is still [].
  3. Line 78: array_column($insert, 'photo_id') is called on a flat associative array, so it always returns [] — making the rating_sum/rating_count increments no-ops on every chunk.
🐛 Proposed fix
 					->chunk(500, function ($photos) {
 						$insert = [];
 						foreach ($photos as $photo) {
 							$exists = DB::table('photo_ratings')
 								->where('photo_id', '=', $photo->id)
 								->where('user_id', '=', $photo->owner_id)
 								->exists();
 
 							if ($exists) {
 								continue;
 							}
 
-							$insert = [
+							$insert[] = [
 								'photo_id' => $photo->id,
 								'user_id' => $photo->owner_id,
 								'rating' => 5,
 							];
 						}
 
+						if ($insert === []) {
+							return;
+						}
+
 						// Insert the 5-star rating
 						DB::table('photo_ratings')->insert($insert);
 
 						// Update statistics aggregate
 						$photo_ids = array_column($insert, 'photo_id');
 						DB::table('statistics')
 							->whereIn('photo_id', $photo_ids)
 							->increment('rating_sum', 5);
 
 						DB::table('statistics')
 							->whereIn('photo_id', $photo_ids)
 							->increment('rating_count', 1);
 					});
🧹 Nitpick comments (1)
database/migrations/2026_02_22_100000_rename_starred_to_highlighted.php (1)

98-104: Step 2 issues N individual UPDATE per row — consider a single JOIN-based UPDATE.

The inner DB::table('photos')->where(...)->update(...) loop inside the chunk fires one round-trip per row. For a large installation this could be very slow. A set-based update avoids the N+1 pattern:

♻️ Proposed refactor
-		DB::table('photos')
-			->join('statistics', 'photos.id', '=', 'statistics.photo_id')
-			->where('statistics.rating_count', '>', 0)
-			->select('photos.id', 'statistics.rating_sum', 'statistics.rating_count')
-			->orderBy('photos.id')
-			->chunk(500, function ($rows) {
-				foreach ($rows as $row) {
-					DB::table('photos')
-						->where('id', '=', $row->id)
-						->update(['rating_avg' => round($row->rating_sum / $row->rating_count, 4)]);
-				}
-			});
+		// Single set-based update using a JOIN (MySQL / SQLite 3.33+ / PostgreSQL)
+		DB::statement('
+			UPDATE photos
+			JOIN statistics ON photos.id = statistics.photo_id
+			SET photos.rating_avg = ROUND(statistics.rating_sum / statistics.rating_count, 4)
+			WHERE statistics.rating_count > 0
+		');

Note: the exact syntax varies by driver. If the project supports multiple RDBMS, keep a driver branch or use the chunked approach but batch the UPDATEs with upsert() / a CASE WHEN expression.


ℹ️ Review info

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 63ad01d and 7c7a2be.

📒 Files selected for processing (1)
  • database/migrations/2026_02_22_100000_rename_starred_to_highlighted.php

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (3)
docs/specs/3-reference/api-design.md (1)

329-329: LGTM — footer date updated to February 24, 2026.

The --- separator and *Last updated: February 24, 2026* footer satisfy the project's documentation guidelines.

resources/js/components/gallery/photoModule/PhotoPanel.vue (1)

33-33: ⚠️ Potential issue | 🔴 Critical

@toggle-star on Dock is stale — highlight toggle from the dock won't fire.

Dock.vue emits toggleHighlight (kebab-case: toggle-highlight), but this line still binds @toggle-star. The fix on Line 3 was applied correctly but this one was missed.

Proposed fix
-			`@toggle-star`="emits('toggleHighlight')"
+			`@toggle-highlight`="emits('toggleHighlight')"
database/migrations/2026_02_22_100000_rename_starred_to_highlighted.php (1)

194-196: Add a hasColumn guard before renaming in down().
Unconditional rename at Line 194-196 can throw on partial rollbacks.

🧹 Nitpick comments (1)
resources/js/views/gallery-panels/Timeline.vue (1)

326-335: Rename the star / unstar callback keys to highlight / unhighlight for consistency.

The callback bodies correctly call PhotoService.highlight(...), but the property names star and unstar create inconsistency that could confuse future maintainers. Note that EmptyPhotoCallbacks in resources/js/utils/Helpers.ts also defines these same keys and will need updating.


ℹ️ Review info

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7c7a2be and 57288b3.

📒 Files selected for processing (25)
  • database/migrations/2026_02_22_100000_rename_starred_to_highlighted.php
  • docs/specs/3-reference/api-design.md
  • docs/specs/4-architecture/backend-architecture.md
  • lang/ar/all_settings.php
  • lang/cz/all_settings.php
  • lang/de/all_settings.php
  • lang/el/all_settings.php
  • lang/en/all_settings.php
  • lang/es/all_settings.php
  • lang/fa/all_settings.php
  • lang/hu/all_settings.php
  • lang/it/all_settings.php
  • lang/ja/all_settings.php
  • lang/nl/all_settings.php
  • lang/no/all_settings.php
  • lang/pl/all_settings.php
  • lang/pt/all_settings.php
  • lang/ru/all_settings.php
  • lang/sk/all_settings.php
  • lang/sv/all_settings.php
  • lang/vi/all_settings.php
  • lang/zh_CN/all_settings.php
  • lang/zh_TW/all_settings.php
  • resources/js/components/gallery/photoModule/PhotoPanel.vue
  • resources/js/views/gallery-panels/Timeline.vue
🚧 Files skipped from review as they are similar to previous changes (8)
  • lang/nl/all_settings.php
  • docs/specs/4-architecture/backend-architecture.md
  • lang/el/all_settings.php
  • lang/cz/all_settings.php
  • lang/vi/all_settings.php
  • lang/ar/all_settings.php
  • lang/es/all_settings.php
  • lang/pt/all_settings.php

@codecov
Copy link

codecov bot commented Feb 24, 2026

Codecov Report

❌ Patch coverage is 89.28571% with 3 lines in your changes missing coverage. Please review.
✅ Project coverage is 90.16%. Comparing base (dd69f18) to head (57288b3).
⚠️ Report is 4 commits behind head on master.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@ildyria ildyria merged commit d3d57e6 into master Feb 24, 2026
44 checks passed
@ildyria ildyria deleted the starred_to_highlight branch February 24, 2026 10:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Rename starred to highlight + migration of stars to 5 star rating.

1 participant