Docs
Tabula Kifuliiru
Applications
Tabula Kifuliiru
Overview
IntroductionArchitectureDevelopment setup
Publish pipelinePublish to LabPublish to cloud
Platform integration
HomeBrowse applications

© 2026 Wekify LLC · Kifuliiru Lab

Homellms.txtkifuliiru.com

GuidesPublish to cloud

Publish to cloud

Promote reviewed data toward production consumers.

Last updated: August 2026

Push new local PostgreSQL rows to the shared Supabase project (same project as Tabula Kifuliiru). Inserts only — existing cloud rows are never overwritten.

UI: /data-management/publish-to-cloud Lab staging runbook: PUBLISH_TO_LAB.md step-by-step for lab_* Impact metrics after publish: IMPACT_VARIABLES.md Related: DATABASE_MAPPER.md, TABLE_MAPPING_CONFIG.md, PROJECT_OVERVIEW.md


Two publish destinations

| Destination | Supabase tables | Used by | Kifuliiru required | |-------------|-----------------|---------|-------------------| | Lab staging | lab_* (e.g. lab_verbs) | Deployed Lab, admin review | Optional locally; enforced on deployed Lab | | Production (live) | Unprefixed (e.g. verbs) | Tabula, public apps | Always |

Choose the destination on the publish page before scanning or publishing.

When to use each

  • Lab staging — draft cloud copy, smoke tests on deployed Lab, data that is not yet ready for Tabula. → Full guide: PUBLISH_TO_LAB.md
  • Production — validated lexical/content rows that should appear in live Tabula and consumer apps.

Note (Aug 2026): All lab_* staging tables are currently empty. Local lab has thousands of rows; publish to lab_* before expecting deployed Lab pages to show data. Run npm run audit:cloud to compare.


Prerequisites

  1. Local PostgreSQL running with the kifuliiru database populated.
  2. Supabase credentials in .env or .env.local:
Code
SUPABASE_URL=https://your-project.supabase.co
SUPABASE_ANON_KEY=your_supabase_anon_key
DB_HOST=localhost
DB_USER=...
DB_PASSWORD=...
DB_NAME=kifuliiru
```text

3. Admin role in Supabase (`admin` or `super_admin` via `user_roles`) if RLS is enabled on target tables.

---

## Workflow (UI)

1. Open **`/data-management/publish-to-cloud`**
2. **Test connection**
3. Select **Lab staging (lab_*)** or **Production (live)**
4. Optionally toggle **Require Kifuliiru-side text** (locked on for Production)
5. **Scan all tables** — compares local vs the selected Supabase destination
6. Select tables with pending rows → **Publish selected**

### What gets published

- Only rows **not already** in the target table (matched by dedup key).
- Dedup key: `english` when set; otherwise first non-empty Kifuliiru-side field (`kifuliiru`, `verb_kifuliiru`, `igambo`, etc.).
- Field-level differences are shown for review but **not** auto-synced.

---

## Kifuliiru publish readiness

A row is eligible when **any** of these fields is non-empty:

`verb_kifuliiru`, `kifuliiru`, `igambo`, `igambo_plural`, `question_kifuliiru`, `conjugated_form`

| Target | Filter behavior | |--------|-----------------| | **Production** | Always on — English-only drafts are skipped | | **Lab staging (local dev)** | Off by default — publish everything; turn on to preview deployed behavior | | **Lab staging (deployed)** | On — same as `NODE_ENV=production` policy |

Override for testing: `NEXT_PUBLIC_REQUIRE_KIFULIIRU_FOR_PUBLISH=true|false` in `.env.local`.

Implementation:

| File | Role | |------|------| | `src/lib/utils/publish-target.ts` | Destination (`lab` \| `production`), table name resolution | | `src/lib/utils/publish-policy.ts` | Lab deploy vs local filter policy | | `src/lib/utils/publish-readiness.ts` | Row-level Kifuliiru field checks, dedup keys | | `src/lib/services/db-mapper.ts` | Compare & sync engine | | `src/lib/utils/table-mapping.ts` | `local` → `lab_*` mapping for staging |

---

## Table name resolution

Local table names stay unchanged in PostgreSQL. Supabase target depends on destination:

| Local | Lab staging | Production | |-------|-------------|------------| | `verbs` | `lab_verbs` | `verbs` | | `dictionary_nouns` | `lab_dictionary_nouns` | `dictionary_nouns` | | `semantics_dictionary` | `lab_semantics_dictionary` | `semantics_dictionary` | | `sentences` | `lab_sentences` | `sentences` |

Full list: `getAllMappableTables()` in `src/lib/utils/table-mapping.ts`.

---

## API (mapper routes)

### Compare

```http
GET /api/mapper/compare?target=lab
GET /api/mapper/compare?target=production&publishReady=1
GET /api/mapper/compare?table=verbs&target=production
```text

Query parameters:

| Param | Values | Description | |-------|--------|-------------| | `target` or `publishTarget` | `lab`, `production`, `prod` | Destination (default: `lab`) | | `publishReady` | `1`, `true` | Count/sync only Kifuliiru-ready rows | | `table` | table name | Compare one table; omit for all |

### Sync (single table)

```http
POST /api/mapper/sync
Content-Type: application/json

{
 "table": "verbs",
 "direction": "to-supabase",
 "target": "production",
 "publishReady": true
}
```text

### Sync batch

```http
POST /api/mapper/sync-batch
Content-Type: application/json

{
 "tables": ["verbs", "dictionary_nouns"],
 "target": "lab",
 "publishReady": false
}
```text

`direction: "from-supabase"` pulls new cloud rows into local Postgres (uses the same `target` for table resolution).

---

## Mappable tables (summary)

Dictionary, content, conversations, questions, templates, semantics, number–noun agreement, conjugation rules — see [PROJECT_OVERVIEW.md](PROJECT_OVERVIEW.md#database-tables-mappable-to-cloud).

**Not published:** `wemp_users` (local NextAuth only). Cloud auth uses Tabula Supabase `auth.users` + `user_roles`.

---

## Troubleshooting

| Symptom | Likely cause | |---------|----------------| | Connection failed | Wrong `SUPABASE_URL` / `SUPABASE_ANON_KEY` | | 0 cloud rows on scan | Table missing in Supabase or wrong `target` | | Insert permission denied | RLS on production tables — need admin role or policy update | | Rows skipped | No Kifuliiru-side text (Production) or already in cloud (dedup key match) | | Counts stale after filter change | Re-run **Scan all tables** |

---

## Security notes

- Never commit `.env` with real keys.
- `NEXT_PUBLIC_*` vars are browser-visible — use anon key only, not service role.
- Production publish affects live Tabula data — confirm destination before publishing.

---

## Related documentation

| Doc | Focus | |-----|--------| | [PUBLISH_TO_LAB.md](/tabula-kifuliiru/guides/publish-to-lab) | **Lab staging** — first publish, phases, troubleshooting | | [IMPACT_VARIABLES.md](IMPACT_VARIABLES.md) | Impact KPIs fed from published corpus | | [PROJECT_OVERVIEW.md](PROJECT_OVERVIEW.md) | Architecture, `lab_*` migration, auth | | [DATABASE_MAPPER.md](DATABASE_MAPPER.md) | Bidirectional compare/sync UI | | [TABLE_MAPPING_CONFIG.md](TABLE_MAPPING_CONFIG.md) | `lab_*` prefix mapping | | [SEMANTICS_CURRENT.md](SEMANTICS_CURRENT.md) | Semantics cloud gaps (`semantic_relationships`) |
PreviousPublish to LabNextPlatform integration

On this page

  • Two publish destinations
  • When to use each
  • Prerequisites