spb/focale Public
Swift 100%
1//2// SearchFilter.swift3// Focale4//5// Author: Simon-Pierre Boucher6// Contact: contact@spboucher.ai7//8// A natural query becomes this structured filter, which runs on the9// local database — instant on 40 000 photos as on 400 (CLAUDE.md §7).10// The model analyzes the query; it never walks the photos.11//1213import Foundation1415struct SearchFilter: Codable, Sendable, Equatable {16 var dateRange: ClosedRange<Date>?17 var kinds: [String] // PhotoKind raw values18 var textTerms: [String] // matched against OCR text19 var entityTerms: [String] // matched against entities / labels / hints20 var placeTerms: [String]21 var projectTerm: String?22 var similarToIdentifier: String? // "photos like this one"23 var favoritesOnly: Bool24 var actionableOnly: Bool // "documents avec une date d'expiration"2526 static let empty = SearchFilter(27 dateRange: nil, kinds: [], textTerms: [], entityTerms: [],28 placeTerms: [], projectTerm: nil, similarToIdentifier: nil,29 favoritesOnly: false, actionableOnly: false30 )3132 var isEmpty: Bool { self == .empty }33}3435extension String {36 /// Case- and diacritic-insensitive folding for French matching37 /// ("reçu" == "recu", "Éléonore" == "eleonore").38 var searchFolded: String {39 folding(options: [.caseInsensitive, .diacriticInsensitive], locale: Locale(identifier: "fr_CA"))40 }41}42