4788ae7723
Fuzzy search: pg_trgm extension + trigram GIN indexes on name parts and a GET /trees/{id}/persons?q= search ranked by trigram similarity (finds Mueller for 'muller'), privacy-filtered. Living-person protection: the privacy engine now derives possibly-living status (explicit flag, else no death fact + birth within ~100y or unknown) and returns 'redacted' for non-members of public/unlisted trees; the service minimises those records ('Living person', no vitals). Members are unaffected. 31 tests pass.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Justin Paul <justin@jpaul.me>
34 lines
938 B
Python
34 lines
938 B
Python
"""pg_trgm extension + trigram name indexes for fuzzy search
|
|
|
|
Revision ID: 9a2b1c7d4e10
|
|
Revises: 7fc7024ef432
|
|
Create Date: 2026-06-07
|
|
|
|
"""
|
|
from collections.abc import Sequence
|
|
|
|
from alembic import op
|
|
|
|
revision: str = "9a2b1c7d4e10"
|
|
down_revision: str | None = "7fc7024ef432"
|
|
branch_labels: str | Sequence[str] | None = None
|
|
depends_on: str | Sequence[str] | None = None
|
|
|
|
|
|
def upgrade() -> None:
|
|
op.execute("CREATE EXTENSION IF NOT EXISTS pg_trgm")
|
|
op.execute(
|
|
"CREATE INDEX IF NOT EXISTS ix_names_given_trgm "
|
|
"ON names USING gin (given gin_trgm_ops)"
|
|
)
|
|
op.execute(
|
|
"CREATE INDEX IF NOT EXISTS ix_names_surname_trgm "
|
|
"ON names USING gin (surname gin_trgm_ops)"
|
|
)
|
|
|
|
|
|
def downgrade() -> None:
|
|
op.execute("DROP INDEX IF EXISTS ix_names_surname_trgm")
|
|
op.execute("DROP INDEX IF EXISTS ix_names_given_trgm")
|
|
# Leave the pg_trgm extension in place; other features may rely on it.
|