Move favorites to local library and keep confirmed task heads in cloud

This commit is contained in:
Pigway
2026-10-06 09:31:09 +08:00
parent c005a9444a
commit 180b6ae100
16 changed files with 1187 additions and 56 deletions
+37 -18
View File
@@ -162,24 +162,43 @@ skipping only invalid or unavailable images. Explicit selections never fall back
Operation `result.photo_attempts` records source-relative item IDs, names, status
and stable error codes, including failures. This does not retry upload or switch.
### Starred cloud photos and seven-day retention
### Local favorites, origins and minimal cloud storage
Automation `cleanup_unstarred` is opt-in and defaults to false. It is valid only
for random photo-source jobs. New uploads retain their confirmed cloud image ID
and an expiry seven days after upload. Existing images are never backfilled.
The cloud gallery's star button stores a Frame Flow star in SQLite; it does not
modify Synology Photos favorites or synchronize with KoKonna app favorites.
Starred images stay; unstarred overdue images are eligible for deletion from the
KoKonna cloud gallery. NAS originals and local Frame Flow assets remain.
Stars are now stored on local assets in SQLite. The local library filters by
`origin` (`manual`, `task`, `external`, `template`, `unknown`) and `job_id`.
Task ID and name are recorded when an asset is generated; deleted tasks do not
rewrite that historical label. Older assets without reliable provenance remain
unknown. Multi-select supports star, unstar and deletion with per-item results.
Referenced assets are rejected rather than breaking pending operations/jobs.
The scheduler checks hourly, queues at most 20 deletions per cycle, and rechecks
stars and protection when executing. Current, previous/restore, override,
playlist and explicit job image references are protected. Offline devices and
write-disabled services skip cleanup. A failed or unknown deletion is retained
for investigation and is not retried automatically. Unstarring an expired image
makes it eligible at the next check. Removing a job does not cancel retention
already assigned to its uploads; star these images to keep them.
Every new task upload is tracked by cloud ID, local asset ID and task ID. Each
task keeps its latest confirmed cloud image. Uploaded local favorites are kept
as cloud copies (one confirmed copy per local asset). New images must reach
COMPLETED with device `synced=true` before an older image can be removed. A
failed/unknown replacement leaves the previous image intact. Current, active
restore/override and playlist/explicit job references remain protected. Cleanup
checks at most once per minute and uses the existing queue, history, write guard
and UNKNOWN barrier. Deletion is never automatically retried after a failure or
unknown response. Superseded task-owned previous-image references are released
only once a replacement is confirmed; unrelated restore references are kept.
API: `PUT /api/v1/devices/{device_id}/images/{image_id}/star` with
`{"starred": true}`; scope `images:write`. Gallery responses add `starred` and
`expires_at`. All cleanup uses the existing operation queue, history and driver.
Starring a local image does not immediately upload it: KoKonna upload changes
the display. The star protects its cloud copy after a normal display upload.
Local originals remain available even if cloud cleanup removes the cloud copy.
NAS source originals are never deleted by these operations. Existing unmanaged
cloud images are not automatically swept; clearing them is an explicit action.
The previous `cleanup_unstarred` seven-day field remains accepted for API
compatibility but is superseded by the minimal-cloud policy in the scheduler.
Endpoints:
- `PUT /api/v1/assets/{asset_id}/star` with `{"starred": true}`.
- `POST /api/v1/assets/batch` with `asset_ids` (up to 100) and action
`star`, `unstar` or `delete`; per-item completion/failure results.
- `GET /api/v1/assets?origin=task&job_id=...&offset=0&limit=200`.
- Administrator `POST /api/v1/devices/{device_id}/images/clear` with
`{"confirm_current": true}` explicitly clears all listed cloud images,
including current and restore references. It returns queued operation IDs.
This is destructive, does not restore artwork, and stops at unknown writes.
The legacy cloud star route forwards to the linked local asset when available;
cloud star controls are removed from the UI. App/Synology favorites are separate.