feat: editable taken_at + folder-based date repair and filter
Lets operators fix corrupted capture dates at scale. Adds an editable Date Taken field with a folder/filename-derived suggestion hint, a bulk Date Taken section in the multi-select sidebar that either applies one date to the whole selection or infers a per-photo date from each path, a warning badge on thumbnails whose stored date disagrees with the path, and a "Date issues" filter pill so suspicious photos can be surfaced and fixed as a group. Edits are written back to EXIF on disk so rescans don't clobber the fix. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
49
backend/alembic/versions/0008_photos_date_warning.py
Normal file
49
backend/alembic/versions/0008_photos_date_warning.py
Normal file
@@ -0,0 +1,49 @@
|
||||
"""photos has_date_warning flag
|
||||
|
||||
Revision ID: 0008_photos_date_warning
|
||||
Revises: 0007_folder_hidden
|
||||
Create Date: 2026-04-11
|
||||
|
||||
Adds `photos.has_date_warning` — a denormalized boolean that's true when
|
||||
the scanner's folder/filename date guesser disagrees with the stored
|
||||
taken_at by more than 24h (or taken_at is missing and the path would
|
||||
provide a date). Surfacing this as a real column means the filter bar
|
||||
can restrict the timeline to suspicious photos without the client
|
||||
recomputing the heuristic for every row.
|
||||
|
||||
Indexed because the filter is meant to run on top of the existing
|
||||
taken_at / folder queries that dominate the timeline, and we want the
|
||||
partial `WHERE has_date_warning` scan to stay cheap as the library
|
||||
grows.
|
||||
"""
|
||||
from typing import Sequence, Union
|
||||
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
|
||||
revision: str = "0008_photos_date_warning"
|
||||
down_revision: Union[str, None] = "0007_folder_hidden"
|
||||
branch_labels: Union[str, Sequence[str], None] = None
|
||||
depends_on: Union[str, Sequence[str], None] = None
|
||||
|
||||
|
||||
def upgrade() -> None:
|
||||
op.add_column(
|
||||
"photos",
|
||||
sa.Column(
|
||||
"has_date_warning",
|
||||
sa.Boolean(),
|
||||
nullable=False,
|
||||
server_default=sa.false(),
|
||||
),
|
||||
)
|
||||
op.create_index(
|
||||
"ix_photos_has_date_warning",
|
||||
"photos",
|
||||
["has_date_warning"],
|
||||
)
|
||||
|
||||
|
||||
def downgrade() -> None:
|
||||
op.drop_index("ix_photos_has_date_warning", table_name="photos")
|
||||
op.drop_column("photos", "has_date_warning")
|
||||
Reference in New Issue
Block a user