You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: .ai/skills/v5-migration/SKILL.md
+16Lines changed: 16 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -118,6 +118,22 @@ public function handle(): int
118
118
}
119
119
```
120
120
121
+
## Post-Migration Fix: Orphaned Tags (2026-04-04)
122
+
123
+
The v5 migration left 189,518 `photo_tags` rows with `category_litter_object_id = NULL` because `DEPRECATED_TAG_MAP` mapped v4 keys to composite names (e.g. `beerCan` → `beer_can`) instead of decomposing into object + type (e.g. `alcohol.can` + type `beer`). The fallback created runtime `litter_objects` (crowdsourced=1) without CLO relationships.
-`php artisan olm:regenerate-summaries --orphan-fix` — Regenerates stale summaries for affected photos. Chunked via `chunkById`, resumable (skips photos with non-null `clo_id` in summary), `Photo::withoutEvents()`.
128
+
-`php artisan olm:reprocess-metrics --from-file=<ids>` — Delta-based MetricsService reprocess for ~1,041 photos with XP changes (special object bonus corrections).
Copy file name to clipboardExpand all lines: CLAUDE.md
+3-2Lines changed: 3 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -142,7 +142,7 @@ Built by a single developer over 17 years.
142
142
- Replace tags (`PUT /api/v3/tags`) accepts empty `tags: []` to clear all tags from a photo
143
143
-`TagsConfig` provides helper methods: `buildObjectMap()`, `buildObjectMaps()`, `allMaterialKeys()`, `allTypeKeys()` — use these instead of hardcoding lists
144
144
- Legacy v1/v2 mobile endpoints removed (2026-03-01) — mobile uses v3 endpoints with CLO format only
145
-
-`Photo` model uses`SoftDeletes`— `$photo->delete()`soft-deletes, `Photo::public()` auto-excludes
145
+
-`Photo` model has`SoftDeletes`trait but all delete endpoints use `forceDelete()`for hard deletion. Cascading FKs on `photo_tags` (→ `photo_tag_extras`) handle relationship cleanup
146
146
- Locations API uses `locations`/`location_type` keys (not `children`/`children_type`)
147
147
-`UsersUploadsController` returns tags under key `'new_tags'` (frontend reads `photo.new_tags`)
148
148
- Untagged photo filter uses `whereNull('summary')` — summary is set by `GeneratePhotoSummaryService` when tags are added, regardless of verification status
@@ -163,7 +163,7 @@ Built by a single developer over 17 years.
- Photo deletion must reverse metrics first: call `MetricsService::deletePhoto()` BEFORE `$photo->delete()`
165
165
- Consistent API field naming: all list/leaderboard endpoints use `total_tags`, `total_images`, `total_members`, `created_at`, `updated_at` — never `total_litter`, `tags`, `photos`, `contributors`
166
-
-`GET /api/global/stats-data` is public (no auth) — returns `total_tags`, `total_images`, `total_users`, `new_users_today`, `new_users_last_7_days`, `new_users_last_30_days`, `new_tags_today`, `new_tags_last_7_days`, `new_tags_last_30_days`, `new_photos_today`, `new_photos_last_7_days`, `new_photos_last_30_days` from metrics table + users table
166
+
-`GET /api/global/stats-data` is public (no auth) — returns `total_tags`, `total_images`, `total_users`, `new_users_last_24_hours`, `new_users_last_7_days`, `new_users_last_30_days`, `new_tags_last_24_hours`, `new_tags_last_7_days`, `new_tags_last_30_days`, `new_photos_last_24_hours`, `new_photos_last_7_days`, `new_photos_last_30_days` from metrics table + users table. Also returns legacy `*_today` aliases (`new_users_today`, `new_tags_today`, `new_photos_today`) for pre-v5.7 mobile compat
167
167
168
168
## Level System
169
169
XP-threshold based levels defined in `config/levels.php`. `LevelService::getUserLevel($xp)` returns level info.
After every change in a session, append a one-line entry to `readme/changelog/YYYY-MM-DD.md` (create the file if it doesn't exist for today's date). Group entries by session. This is the running record of all work done each day.
0 commit comments