Docs
Lola Kifuliiru
Applications
Lola Kifuliiru
Overview
IntroductionArchitectureDevelopment setup
Kifuliiru FM integrationContent types and feed tabsHashtags and tagsAI moderation and language helperFeature planIn-app guide (developer notes)
Platform integration
HomeBrowse applications

© 2026 Wekify LLC · Kifuliiru Lab

Homellms.txtkifuliiru.com

GuidesFeature plan

Feature plan

Product and engineering roadmap for Lola.

Living document: break work into features (outcomes) and tasks (shippable units). Use Wemp tags in commits when you track with @wemp_feature / @wemp_start (see .cursorrules).


Conventions

| Term | Meaning | |------|---------| | Feature | User-visible outcome or capability | | Task | Concrete deliverable (often one PR or one focused commit) | | Task ID | Suggested kebab-case-### for Wemp search — create or reuse via your tasks API |


1. Feed & reading experience

Feature: Reliable feed UX — Users can browse many posts comfortably on all viewports.

| Task ID | Task | |---------|------| | feed-scroll-restore-001 | Restore scroll position using the shell scroll container (not window only), aligned with session cache keys. Done — lola-feed-scroll-v2 + findVerticalScrollParent in src/lib/lola-scroll.ts; realtime “near top” + show-new-posts scroll use the same container. | | feed-pull-refresh-001 | Pull-to-refresh on mobile Done — touch handlers on feedRootRef when max-width: 767px, damped pull + PTR_RELEASE_PX; RefreshCw indicator; reuses fetchActivities(false). | | feed-load-more-btn-001 | Optional Load more button below the feed (accessibility + slow networks), alongside infinite scroll. Done — button + lola.load_more / lola.loading_more_posts. | | feed-prefetch-001 | Tune infinite-scroll prefetch Done — IntersectionObserver rootMargin set to 200px (was 160px). |


2. Posts & composer

Feature: Richer posting — Composer stays fast; drafts and edits reduce friction.

| Task ID | Task | |---------|------| | post-lang-ai-001 | AI post language check + Mini Dictionary table Done — OpenAI check on publish; block mismatch / mixed when Kifuliiru is selected; lola_kifuliiru_mini_dictionary stores Kifuliiru-only words. Handoff: LOLA-AI-MODERATION.md. | | post-translations-001 | Composer translations + feed mark + complete-on-press Done — Add translation fields; save content_*; feed shows main language + extra-language mark; background complete + sparkles preview. Handoff: LOLA-AI-MODERATION.md. | | post-ai-guard-001 | Junk skip + AI rate limits + 24h pause Done in Lola (lola_user_ai_guard). Unblock / pause UI goes in Tabula, not Lola. | | post-drafts-001 | Persist drafts Done — localStorage key lola-composer-ls-v1-{userId} (debounced text); session lola_composer_draft kept for login redirect; cleared on post/cancel. | | post-edit-001 | Edit own posts with optional “edited” label; validate permissions server-side. | | post-templates-001 | Optional post “kinds” (e.g. question vs story) via metadata + filters. |


3. Social & discovery

Feature: Find people and content — Search and browsing extend beyond the main timeline.

| Task ID | Task | |---------|------| | social-hashtags-001 | Partial — #tags in post body are links to feed search /?q=%23… (PostContentWithHashtags). No separate tag pages or DB index yet. See LOLA-TAGS.md. | | social-content-types-001 | Planned — Parse canonical tags on publish; persist metadata.tags, metadata.contentKind (e.g. #Imyazi / #Umwazi → news). Spec: LOLA-CONTENT-TYPES.md Phase A. | | social-feed-tabs-001 | Planned — Feed tabs (All, News, Culture, …) filtered by captured metadata; sidebar tags switch tab. Spec: LOLA-CONTENT-TYPES.md Phase B. | | social-mentions-001 | @username mentions + notification on mention. | | profile-pinned-001 | Pin one post on profile (if not already). | | profile-tabs-001 | Tabs: posts / media / replies (scope per product). |


4. Language & community (Kifuliiru)

Feature: Language-aware feed — Aligns Lola with Tabula’s mission.

| Task ID | Task | |---------|------| | lang-post-locale-001 | Optional language tag Done — metadata.postLocale (kifuliiru | sw | fr | en | other); composer select + feed chips (incl. untagged); badge on PostCard; draft saves postLocale. | | lang-glossary-link-001 | MVP composer hint Done — line under expanded composer + getTabulaDictionaryUrl() (default kifuliiru.com/dictionary; optional NEXT_PUBLIC_KIFULIIRU_DICTIONARY_URL). |


5. Safety & trust

Feature: Safe community — Clear reporting and moderation paths.

Admin work stays in the Tabula dashboard (same Supabase project). Spec: LOLA-AI-MODERATION.md.

| Task ID | Task | |---------|------| | safety-report-001 | Report post/user: Lola writes lola_content_reports; toast already exists. | | safety-mod-queue-001 | Report + guard + dictionary queue in Tabula (/lola/reports, /lola/guard, /lola/dictionary). |


6. Notifications & realtime

Feature: Timely updates — Users don’t miss replies and mentions.

| Task ID | Task | |---------|------| | notif-mentions-001 | Wire mention notifications (depends on social-mentions-001). | | notif-batch-001 | Optional digest / batching preferences. |


7. Performance & quality

Feature: Fast, stable app — Perceived performance and fewer layout bugs.

| Task ID | Task | |---------|------| | perf-lazy-media-001 | Lazy-load images in PostCard / feed with blur or dimensions to reduce CLS. Partial — feed images already had loading="lazy"; added decoding="async". Blur placeholders optional later. | | perf-optimistic-001 | Optimistic like Done for likes in PostCard with rollback + lola.like_failed. Comments unchanged (dialog flow). | | qa-analytics-001 | Event hooks Done — src/lib/lola-analytics.ts dispatches lola-analytics on window with feed_load_more, feed_pull_refresh, feed_search (query length only), post_create; dev console.debug. |


8. Kifuliiru FM

Feature: Radio-style listening experience — Kifuliiru FM should feel like one focused station player, supported by a clean audio library.

Integration & merge (for agents): see KIFULIIRU-FM-INTEGRATION.md — single table kifuliiru_fm_recordings, write/read paths, playback rules, and follow-up checklist.

Product decisions

  • Use one main player for Kifuliiru FM. The recordings list should not render separate mini players.
  • Clicking a recording in the list loads that recording into the main player and updates the now-playing content.
  • Keep the station opening transition for the main station play flow. A direct click on a specific recording can play that recording directly.
  • Desktop: full-width hero player; recordings library in a revealable right rail (closed by default, opened via Library control on the player).
  • When the library is open on desktop, player uses ~65–70% width and the rail ~30–35%.
  • Mobile: player first; library opens as a slide-over sheet with backdrop (same Library control).
  • Keep the page visually clean: fewer globe decorations, simple public pages, white public-page backgrounds, and clear CTAs.
  • On /kifuliiru-fm, the in-app header and player copy position Kifuliiru FM as the home for all Kifuliiru audio from our community and platforms (not as a Lola sub-brand). SEO/browser title remains Kifuliiru FM.

Recording taxonomy

Recordings should become structured audio content, not only audio posts.

Suggested first fields:

| Field | Purpose | Example values | |-------|---------|----------------| | audioType | The format of the recording | voice_note, story, reflection, podcast, music, interview, lesson, announcement, faith, other | | audioCategory | The topic or community area | language, culture, history, community, music, education, family, news, faith, humor | | audioTags | Flexible discovery labels | proverbs, wedding, migration, children, grammar | | audioSeriesId | Optional grouping for multi-part work | A user's playlist/series ID |

Public labels can be simpler than storage values:

| Stored type | Public label | |-------------|--------------| | voice_note | Voice notes | | story | Stories | | reflection | Reflections | | podcast | Podcasts | | music | Music | | interview | Interviews | | lesson | Lessons | | announcement | Announcements | | faith | Faith | | other | Other |

Filters and discovery

The Kifuliiru FM recordings list should support:

  • Search by title, description, speaker, and tags.
  • Filter by author.
  • Filter by audio type.
  • Filter by category.
  • Optional later filters: language, duration, date, popularity, saved/bookmarked.

The list row should stay compact and scannable:

  • Title.
  • Author/speaker.
  • Type badge.
  • Category or tag hint.
  • Duration.
  • Date.
  • A clear row-click behavior that loads the main player.

Ganuula recording workflow

Users need to classify audio when they create or upload it.

| Task ID | Task | |---------|------| | fm-audio-taxonomy-001 | Add audio type, category, and tags metadata to Ganuula audio creation/upload. | | fm-audio-edit-meta-001 | Let users edit title, description, type, category, and tags after publishing. | | fm-audio-series-001 | Add optional user-created series/playlists for organizing multiple recordings. | | fm-audio-manage-001 | Add a "My recordings" management view for users with many recordings. |

Series/playlists are especially important for users who publish related recordings, such as:

  • Kifuliiru Proverbs.
  • Family Stories.
  • Songs from Home.
  • Beginner Kifuliiru Lessons.
  • Community Interviews.

Player and station tasks

| Task ID | Task | |---------|------| | fm-single-player-001 | Refactor Kifuliiru FM to one main player; remove per-row list players. Done — single <audio>; list rows select track only. | | fm-side-list-001 | Split the desktop player section into main player left and recordings list right. Done — revealable right library rail; full-width player when closed. | | fm-mobile-queue-001 | Stack player then list on mobile with stable spacing and touch-friendly rows. Done — player-first; library as slide-over sheet. | | fm-opening-transition-001 | Keep the station opening transition… Done — station Play uses opening; row click plays direct. | | fm-list-filters-001 | Add list filters for author, type, category, and search. |

SEO for recordings

Each recording should be independently findable by search engines.

Preferred URL shape:

∑Formula
/kifuliiru-fm/audio/[slug-or-id]
```text

Each recording page should include:

- Unique title: recording title + Kifuliiru FM.
- Description from recording description/caption.
- Author/speaker.
- Published date.
- Duration when available.
- Audio type and category.
- Tags.
- Canonical URL.
- Open Graph and Twitter metadata.
- Embedded or linked audio player.
- Transcript when available.
- JSON-LD structured data using `AudioObject`.

| Task ID | Task | |---------|------| | `fm-audio-pages-001` | Create public SEO pages for individual recordings. | | `fm-audio-metadata-001` | Generate page metadata per recording: title, description, canonical, Open Graph, Twitter. | | `fm-audio-jsonld-001` | Add `AudioObject` structured data for each recording. | | `fm-audio-transcript-001` | Support optional transcripts for stronger search discovery and accessibility. |

---

## Suggested phases

| Phase | Focus | Features (numbers above) | |-------|--------|----------------------------| | **A — Polish** | What you already started | 1 (scroll restore), 7 (lazy/optimistic) | | **B — Growth** | Discovery + language | 3 (hashtags), 4 (locale tags) | | **C — Trust** | Reporting + mod | 5 | | **D — Social depth** | Mentions, drafts, edit | 2, 3 (mentions, profile) | | **E — Kifuliiru FM** | Radio player + audio library | 8 |

Reorder phases to match your launch goals.

---

## How to use this file

1. Pick a **task** from a table. 
2. Query Wemp for existing `Task ID` (`GET /api/tasks/search?search=…`). 
3. If new, create the task and link commits with `@wemp_feature` + `@wemp_start` as in `.cursorrules`. 
4. When a task ships, mark it in your tracker; optionally trim or strike it here so the doc stays honest.

---

### Lola routes (inventory)

| Route | Status | |-------|--------| | `/` (home feed) | **Built** — `FeedPageClient`, composer, filters, realtime, etc. | | `/notifications` | **Built** — list from `notifications` table, mark read / mark all, matches Lola styling; bell listens for `lola-notifications-updated`. | | `/bookmarks` | **Placeholder** (“coming soon”) — needs saved-posts model + UI. | | `/community` | **Placeholder** — needs product scope (directory, topics, etc.). | | `/p/[postId]` | **Built** — permalink / share target. | | `/test-deep-link` | Dev/test helper. | | `/profile/{id}` | **Built** — Lola social profile (`ProfilePageClient`: posts, follow, link to Tabula contributor profile via `getTabulaProfileUrl`). |

Session required (middleware): `/notifications`, `/bookmarks`.

---

*Last updated: created as a planning scaffold — edit freely.*
PreviousAI moderation and language helperNextIn-app guide (developer notes)

On this page

  • Conventions
  • 1. Feed & reading experience
  • 2. Posts & composer
  • 3. Social & discovery
  • 4. Language & community (Kifuliiru)
  • 5. Safety & trust
  • 6. Notifications & realtime
  • 7. Performance & quality
  • 8. Kifuliiru FM
  • Product decisions
  • Recording taxonomy
  • Filters and discovery
  • Ganuula recording workflow
  • Player and station tasks
  • SEO for recordings