Data model and glossary
The archive was migrated from a WordPress site (src/migrate/, stage by stage: taxonomies → materials → transcripts → content). Postgres is the source of truth; Meilisearch holds projections that can always be rebuilt from it.
Collections
Section titled “Collections”| Collection | Admin name | What one row is |
|---|---|---|
materials |
مادة | One recording: a lesson, lecture, sermon or clip. Carries the media links (audioUrl mp3 on files.kalelm.com, youtubeId, rarely videoUrl, documentUrl), date, duration, sheikh, series, book chapter, tags. 49,016 rows. |
transcripts |
تفريغ | The timestamped text of one material in one language: a JSON array of { start, text } cues. Unique per material + language. 12,870 rows. source records where it came from: wordpress, whisper, gemini, cohere, manual. |
sheikhs |
شيخ | A speaker. Grouped uae / abroad / unsorted; hidden keeps a row out of listings. |
series |
البرنامج | A programme or course a material belongs to. The largest holds 3,394 lessons. |
books, book-chapters |
كتاب، الباب | The book being explained and the chapter a lesson covers. |
tags |
الوسوم | Free topical tags. |
articles, pages |
مقال، صفحة | Written content and static pages, with rich text. |
media |
Uploaded images only; archive audio and video are never uploaded here. | |
transcription-jobs |
مهام التفريغ | The transcription queue: one row per material with status, worker, stage, attempts, error and timings. |
search-logs |
One row per search: query, mode, result count, top score. | |
users |
المستخدمون | Admin accounts. Roles: admin (everything, including delete and users) and editor (create and edit). |
Globals: search-settings (stopwords) and pipeline-settings (paused, post-edit on/off, post-edit model).
Material fields worth knowing
Section titled “Material fields worth knowing”- type:
lessonدرس,lectureمحاضرة,sermonخطبة,clipمقطع. - status:
publishedمنشور,draftمسودة,pendingقيد المراجعة. Only published material is public, indexed, or eligible for transcription. - language is what language the recording is in:
ar,en,ur. It is a different axis from localization: a translated title lives in the same row under another locale; a separate Urdu recording is its own row linked bytranslationOf. - hasTranscript is denormalized from
transcriptsbecause Payload cannot query “has a related row”. The transcript hooks maintain it; the gate checks it never drifts. - duration is seconds, with
durationSourcesaying whether it came from YouTube or the mp3 header; the durations panel backfills it. - oldSlugs keeps WordPress URLs alive as redirects.
Relationships
Section titled “Relationships”sheikh 1 ── n material n ── 1 series │ ├── n tags ├── 1 book-chapter ── 1 book ├── 1 translationOf (another material) └── 1..3 transcripts (one per language)Glossary
Section titled “Glossary”| Term | Meaning here |
|---|---|
| مادة / material | One recording, whatever its type. |
| تفريغ / transcript | Timestamped text of a recording. |
| cue | One { start, text } entry in a transcript; end time is the next cue’s start. |
| segment | A cue as indexed for keyword search (caption_segments). |
| sentence, passage | Units built from cues for semantic search: a sentence to retrieve, a ~125-word window for context. |
| تشكيل / tashkeel | Arabic diacritics. The pipeline restores only hamza, ta-marbuta, shadda and tanween; never full vowels. |
| eligible material | Published, has an audioUrl, no youtubeId, language ar or en, no transcript yet. What the pipeline may queue. |
| degraded search | A semantic or hybrid request answered with keyword results because the vector path was unavailable. |