mirror of
https://github.com/fsolla/teqo.git
synced 2026-11-13 06:43:06 +00:00
Troca o motor do modo tema (Câmara + internet) de expansão lexical para embeddings (Deep Infra, BAAI/bge-m3), com índice próprio (speechEmbedding), ranking por proximidade em memória, evidência real do trecho mais próximo, vazio honesto por limiar e degradação para a busca literal. Inclui a collection oculta + migration, o CLI pnpm acervo:index (--dry-run/--limit/ --source/--force/--probe), o port do design aprovado e a suíte de testes. Pós-rebase: o snapshot da migration seguinte (20260926_062039_add_archive_photo, do C231 já na main) foi regenerado para incluir speech_embedding — sem ele o próximo migrate:create recriaria a tabela. Closes #1360
63 lines
2.6 KiB
TypeScript
63 lines
2.6 KiB
TypeScript
/**
|
|
* C216 — the ONE ordering vocabulary of the acervo list: the recordings source
|
|
* (C219) and the web speeches source (C216) share the options, the labels, the
|
|
* `recentes` default (never serialized) and the duration gate. Each domain owns
|
|
* the mapping to its Payload order (recordings default `-createdAt`, web
|
|
* `-speechAt`); a duration order only lists rows with a measured duration,
|
|
* because Postgres sorts NULLS FIRST on DESC.
|
|
*/
|
|
|
|
export const ACERVO_SORT_OPTIONS = [
|
|
{ value: 'recentes', label: 'Mais recentes' },
|
|
{ value: 'duracao_maior', label: 'Duração (maior)' },
|
|
{ value: 'duracao_menor', label: 'Duração (menor)' },
|
|
] as const
|
|
|
|
export type AcervoSortKey = (typeof ACERVO_SORT_OPTIONS)[number]['value']
|
|
|
|
const ACERVO_SORT_SET = new Set<string>(ACERVO_SORT_OPTIONS.map(({ value }) => value))
|
|
|
|
const firstParam = (value: string | string[] | undefined): string | undefined =>
|
|
Array.isArray(value) ? value[0] : value
|
|
|
|
/**
|
|
* Only the non-default orders are meaningful; anything else (and `recentes`) is the default.
|
|
*/
|
|
export const parseAcervoSort = (raw: string | string[] | undefined): AcervoSortKey | undefined => {
|
|
const value = firstParam(raw)
|
|
return value && value !== 'recentes' && ACERVO_SORT_SET.has(value)
|
|
? (value as AcervoSortKey)
|
|
: undefined
|
|
}
|
|
|
|
/**
|
|
* C229 — the ordering vocabulary of the theme mode of the speech acervo:
|
|
* relevance is the default (never serialized) and the explicit date/duration
|
|
* order must stay askable. Recordings and the public Central keep
|
|
* `ACERVO_SORT_OPTIONS` — their theme mode is not the semantic engine.
|
|
*/
|
|
export const ACERVO_THEME_SORT_OPTIONS = [
|
|
{ value: 'relevancia', label: 'Mais relevantes' },
|
|
...ACERVO_SORT_OPTIONS,
|
|
] as const
|
|
|
|
export type AcervoThemeSortKey = (typeof ACERVO_THEME_SORT_OPTIONS)[number]['value']
|
|
|
|
const ACERVO_THEME_SORT_SET = new Set<string>(ACERVO_THEME_SORT_OPTIONS.map(({ value }) => value))
|
|
|
|
/**
|
|
* Theme-aware parse: `relevancia` (and anything unknown) parses away as the
|
|
* default, while `recentes` is a REAL state here — the exact-mode default has
|
|
* to stay explicitly askable after relevance became the theme default.
|
|
*/
|
|
export const parseAcervoThemeSort = (
|
|
raw: string | string[] | undefined,
|
|
): AcervoSortKey | undefined => {
|
|
const value = firstParam(raw)
|
|
if (!value || value === 'relevancia' || !ACERVO_THEME_SORT_SET.has(value)) return undefined
|
|
return value as AcervoSortKey
|
|
}
|
|
|
|
/** Duration orders only make sense over rows with a measured duration. */
|
|
export const acervoSortIsDuration = (sort: AcervoSortKey | undefined): boolean =>
|
|
sort === 'duracao_maior' || sort === 'duracao_menor'
|