pluto
PLUTO-505
Accent-insensitive search (tilde): 'matias' must match 'matias'/'matias'
Done normal
cpcoder-pluto-cc
Elazar 2026-07-04 (g): name/text searches are tilde-sensitive; Spanish users expect accent-insensitive results. Pluto side of a FLEET-WIDE issue routed to aro:evolutiva-management via pm-mars-cc. BLOCKED on the shared approach decision (proposed: Postgres unaccent extension on the search predicate, DB-side, index-friendly). Implement once management-aro settles the approach.
Activity
-
DECIDED bs-mr6s4nyj1th (unanimous 3-PM 2026-07-04). Fleet convention: wrapper f_unaccent(text) RETURNS text LANGUAGE sql IMMUTABLE PARALLEL SAFE AS $$ SELECT unaccent('unaccent',$1) $$ (2-arg pinned-dict, load-bearing). Predicate wraps BOTH sides: f_unaccent(lower(col)) <op> f_unaccent(lower($q)). Index per-surface: btree(f_unaccent(lower(col))) prefix/eq; pg_trgm GIN over SAME expr for substring/typeahead. n-fold accepted. Email EXCLUDED (canonicalizeEmail owns identity, unaccent must not touch auth/dedup). Next: db-pluto inventories pluto search surfaces (which are substring->GIN vs prefix->btree; whether unaccent/pg_trgm ext already present), then DDL (ext+f_unaccent+indexes) as db task, audit pre-apply. UNBLOCKED (approach settled); awaiting prioritization.
-
Approach ratified fleet-wide; unblocked, ready for pluto surface inventory + db DDL.
-
coder-pluto-cc
-
Pluto surface inventory complete (coder-pluto-cc 2026-08-22), DDL requested from db-pluto-cc as migration 115. SURFACES - all six are SUBSTRING searches (%q% via buildSearchPattern), none prefix/eq, so all want pg_trgm GIN over f_unaccent(lower(col)) and none needs a btree: admin-actions.ts:576 (/admin/usuarios nombre/apellido/legajo), admin-actions.ts:1694 (pending users nombre/apellido + composite apellido||', '||nombre), personas-actions.ts:41 (/admin/personas nombre/apellido/numeroDocumento), queries.ts:2618+2791 (student summary composite + legajo), administrar-actions.ts:547+619 (/administrar typeaheads - NOTE these two use bare ILIKE $1 with no LOWER on either side, unlike every other site, and get normalised in the app half), admin/logs/page.tsx:148 (mixed: unaccent the human name arm only, leave action/route/errorName/digest/id alone - do not unaccent an error digest). Email arms EXCLUDED everywhere per the fleet ruling: canonicalizeEmail owns identity and unaccent must not touch auth/dedup. OPEN QUESTIONS TO DB: (a) are unaccent+pg_trgm installed and in which schema - the wrapper's pinned dict name resolves against search_path and PLUTO-673's defect family is why this is not being guessed; (b) whether composite-expression indexes earn their write cost at pluto's row counts (n-fold growth was accepted fleet-wide, which is not the same as mandatory); (c) whether the vUsers view definition even lets those base-table expression indexes be used - a view that blocks the expression match makes the index dead weight, and that must be known BEFORE apply. SEQUENCING IS LOAD-BEARING: DDL first, app predicates second. A predicate calling f_unaccent() reaching prod before the function exists 42883s the entire /admin roster, personas, both typeaheads and the student list simultaneously.
-
Shipped 9327377. Migration 115 (db-pluto-cc, applied+verified on prod: unaccent 1.1 + pg_trgm 1.6, f_unaccent('Pena Nono') confirmed live) carried by coder-pluto-cc with schema.md regen; app predicates fold both sides on six surfaces: admin-actions x2, personas-actions, queries.ts student-summary x2, administrar-actions both typeaheads (ILIKE->LIKE + JS toLowerCase), logs page human-name arm only. Email arms excluded everywhere (canonicalizeEmail owns identity). NO indexes - db-pluto-cc ruled seq-scan at 376 users. COVERAGE: source-level invariant test (7 cases) proves no one-sided fold and no folded email arm; tsc clean; NOT exercised in a browser and no query was run against prod through the new predicates.
task
2026-07-04 by wi-cli-venus
7w ago
2026-08-22 10:15