feat(dictionary): bulk-add most-common-first + hnc-<band> tags #72

Merged
raisondetredev merged 2 commits from refs/pull/72/head into main 2026-07-02 01:28:45 +02:00
raisondetredev commented 2026-07-01 23:19:17 +02:00 (Migrated from codeberg.org)

What

Makes add_dictionary_vocabulary introduce bulk-added cards most-common / most-elementary first and tag each with its frequency band.

How

New-card introduction order in the app is driven solely by cards.due_at ASC (no tiebreak) — not ordering, not created_at. So due_at is the only lever, staggered off a fixed far-past anchor keyed on an absolute rank/level (stable & global across separate adds):

  • Greek: due_at = epoch + hnc_rank seconds → rank 1 = oldest.
  • JLPT: due_at = epoch + (6 - jlpt) days → N5 oldest … N1 newest (so adding N5+N4 makes N5 older).
  • else (common-only / other languages): due_at = now() (unchanged).

created_at stays now() (the real add time). All anchors are in the past, so cards are immediately eligible and the app's daily new-card limit introduces them in frequency order.

Also emits a visible hnc-<band> content tag (hnc-500, hnc-1000, …) — the Greek analogue of jlpt-n* — derived from hnc_rank (ceil to the next 500, capped at 23500), so a learner can filter/study "the most common 500 first."

Only the FOR query (adds e.hnc_rank + frequency ORDER BY), the due_at value, and the tag UNION change; everything else matches the repaired body. Same signature → CREATE OR REPLACE.

Depends on

  • #70 (repaired RPC body — the base this layers on)
  • #71 (hnc_rank column) + curator halkyon-curator#23 (populates hnc_rank; already backfilled on the live el entries, 24,087 ranked)

Apply after #70/#71 in the SQL editor.

## What Makes `add_dictionary_vocabulary` introduce bulk-added cards **most-common / most-elementary first** and tag each with its **frequency band**. ## How New-card introduction order in the app is driven **solely by `cards.due_at` ASC** (no tiebreak) — not `ordering`, not `created_at`. So `due_at` is the only lever, staggered off a fixed far-past anchor keyed on an *absolute* rank/level (stable & global across separate adds): - **Greek**: `due_at = epoch + hnc_rank seconds` → rank 1 = oldest. - **JLPT**: `due_at = epoch + (6 - jlpt) days` → N5 oldest … N1 newest (so adding N5+N4 makes N5 older). - **else** (common-only / other languages): `due_at = now()` (unchanged). `created_at` stays `now()` (the real add time). All anchors are in the past, so cards are immediately eligible and the app's daily new-card limit introduces them in frequency order. Also emits a visible `hnc-<band>` content tag (`hnc-500`, `hnc-1000`, …) — the Greek analogue of `jlpt-n*` — derived from `hnc_rank` (ceil to the next 500, capped at 23500), so a learner can filter/study "the most common 500 first." Only the FOR query (adds `e.hnc_rank` + frequency `ORDER BY`), the `due_at` value, and the tag UNION change; everything else matches the repaired body. Same signature → `CREATE OR REPLACE`. ## Depends on - #70 (repaired RPC body — the base this layers on) - #71 (`hnc_rank` column) + curator halkyon-curator#23 (populates `hnc_rank`; already backfilled on the live el entries, 24,087 ranked) Apply after #70/#71 in the SQL editor.
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
project-halkyon/halkyon-infra!72
No description provided.