# NUMU — UI → API Mapping

> Audit of every field/operation the admin can **see** or **edit** in the dashboard UI for **Investors, Companies (Startups), Demos, Committees**, mapped against the existing MCP / REST API surface (`/api/v1/...`, 40 MCP tools).
>
> Legend: ✅ supported · ⚠️ partial · ❌ missing.
> "API Read" = exposed by an MCP read tool / GET endpoint. "API Update" = exposed by an MCP full-tier write tool / PATCH·POST endpoint.
>
> **How the UI works (important):** Investors & Startups have **no create/edit pages** — the admin edits everything *inline on the single show page* via per-section AJAX saves (`update-section`, `update-label`, member/file/note endpoints). Records are created only via the public signup form / Monday sync. Demos & Committees DO have create/edit forms.

---

## 1. Investors

Source of truth for editable fields: `app/Services/Admin/EntitySectionSchema::investorSections()`. Write API: `PATCH /api/v1/investors/{id}` (`InvestorApiWriteController`, ~40-field whitelist) + MCP `investor_update`.

| UI Field | Visible | Editable | API Read | API Update | Missing / Notes |
|---|---|---|---|---|---|
| full_name_ar / full_name_en | ✅ | ✅ | ✅ | ✅ | — |
| first_name_ar / first_name_en | ✅ | ✅ | ✅ | ✅ | — |
| email | ✅ | ✅ | ✅ | ✅ | — |
| phone_number | ✅ | ✅ | ✅ | ✅ | — |
| country_id / city_id | ✅ | ✅ | ✅ | ✅ | — |
| linkedin_profile | ✅ | ✅ | ✅ | ✅ | — |
| investor_bio | ✅ | ✅ | ✅ | ✅ | — |
| group_id | ✅ | ✅ | ✅ | ✅ | — |
| category_option_id | ✅ | ✅ | ✅ | ✅ | — |
| background_option_id | ✅ | ✅ | ✅ | ✅ | — |
| investment_experience_option_id | ✅ | ✅ | ✅ | ✅ | — |
| activity_in_numu_option_id | ✅ | ✅ | ✅ | ✅ | — |
| whatsapp_group_status | ✅ | ✅ | ✅ | ✅ | — |
| average_ticket_option_id | ✅ | ✅ | ✅ | ✅ | — |
| expected_annual_investments_option_id | ✅ | ✅ | ✅ | ✅ | — |
| investments_count | ✅ | ✅ | ✅ | ✅ | — |
| investment_experience_level_option_id | ✅ | ✅ | ✅ | ✅ | — |
| has_angel_invested_option_id | ✅ | ✅ | ✅ | ✅ | — |
| exit_experience_option_id | ✅ | ✅ | ✅ | ✅ | — |
| previous_investments_companies (array) | ✅ | ✅ | ✅ | ✅ | AI enrich whitelist |
| action_option_id (hero workflow) | ✅ | ✅ | ✅ | ✅ | triggers `InvestorLabelActionService` (group move + notify) |
| referral_source_option_id | ✅ | ✅ | ✅ | ✅ | — |
| is_in_other_angel_group_option_id | ✅ | ✅ | ✅ | ✅ | — |
| rejection_reason | ✅ | ✅ | ✅ | ✅ | — |
| avatar (avatar_path) | ✅ | ✅ (upload) | ✅ | ✅ | `investor_upload_avatar` (from URL) |
| is_favorite (star toggle) | ✅ | ✅ | ✅ | ❌ | **GAP: no favorite-toggle write** |
| **sectors** (multiselect pivot) | ✅ | ✅ | ⚠️ (read via get) | ❌ | **GAP: cannot set preferred sectors** |
| **stages** (multiselect pivot) | ✅ | ✅ | ⚠️ | ❌ | **GAP: cannot set preferred stages** |
| **payment_methods** (multiselect pivot) | ✅ | ✅ | ⚠️ | ❌ | **GAP: cannot set payment methods** |
| **tags** | ✅ | ✅ add/remove/create/rename | ✅ | ⚠️ attach-only | **GAP: no detach / full-sync / rename via API** |
| **notes** | ✅ | ✅ CRUD | ✅ list | ⚠️ create-only | **GAP: no note update/delete** |
| meetings | ✅ | read-only | ✅ | ✅ note+attendance | API exceeds UI here |
| activity log | ✅ | read-only | ✅ | — | — |

Read coverage **~100%** · Update coverage **~82%** (gaps: 3 multiselect pivots, favorite, note update/delete, tag detach/rename).

---

## 2. Companies (Startups)

Source of truth: `EntitySectionSchema::startupSections()`. Write API: `PATCH /api/v1/startups/{id}` (`StartupApiWriteController`, ~36 fields + name-resolution) + MCP `startup_update`.

| UI Field / Operation | Visible | Editable | API Read | API Update | Missing / Notes |
|---|---|---|---|---|---|
| name / name_en / applicant_full_name | ✅ | ✅ | ✅ | ✅ | — |
| first_name_ar / first_name_en | ✅ | ✅ | ✅ | ✅ | — |
| email / phone_number | ✅ | ✅ | ✅ | ✅ | — |
| country_id / city_id | ✅ | ✅ | ✅ | ✅ | — |
| website / linkedin_url | ✅ | ✅ | ✅ | ✅ | — |
| startup_brief / problem / solution / investment_opportunity / kpi_targets | ✅ | ✅ | ✅ | ✅ | — |
| sector / product_stage / traction / revenue_model / customer_focus option_ids | ✅ | ✅ | ✅ | ✅ | name-resolution supported |
| investment_stage / round_type option_ids | ✅ | ✅ | ✅ | ✅ | — |
| asking_fund_sar / min_ticket_size_sar / offered_equity_pct / valuation / runway_months / total_raised_sar | ✅ | ✅ | ✅ | ✅ | valuation auto-computed |
| referral_source / note_type option_ids / rejection_reason | ✅ | ✅ | ✅ | ✅ | — |
| action_option_id (hero workflow) | ✅ | ✅ | ✅ | ✅ | `StartupLabelActionService` |
| status_option_id | ⚠️ (index) | ✅ (index) | ✅ | ✅ | — |
| group (monday_group_id/group_id) | ✅ | ✅ | ✅ | ✅ | — |
| is_favorite | ✅ | ✅ | ✅ | ❌ | **GAP: no favorite toggle** |
| logo (file slot=logo) | ✅ | ✅ upload | ✅ | ✅ | `startup_upload_logo` |
| ios_url / android_url | ✅ icons | API/Monday only | ✅ | ⚠️ | not in AI whitelist (REST only) |
| **Team Members / Founders** (name, job_type, country, linkedin, positions[], short_brief, is_founder) | ✅ | ✅ **full CRUD** | ⚠️ (loaded in get) | ❌ | **GAP: no member create/update/delete API** |
| **Files** logo/pitch_deck/other/initial_dd (upload/replace/move/delete) | ✅ | ✅ full CRUD | ✅ list/stream | ⚠️ logo only | **GAP: no upload/replace/move/delete for pitch_deck/other/DD** |
| **geographic_focuses** (multiselect pivot) | ⚠️ (schema, hidden) | ✅ | ⚠️ | ❌ | **GAP: cannot set geographic focus** |
| fund_use_* / market_size_* | ⚠️ (schema, hidden) | ✅ | ✅ (REST whitelist) | ✅ (REST) | UI hidden, API covers |
| **notes** | ✅ | ✅ CRUD | ✅ list | ⚠️ create-only | **GAP: no note update/delete** |
| meetings | ✅ | read-only | ✅ | ✅ | — |

Read coverage **~100%** · Update coverage **~70%** (gaps: team members CRUD, file CRUD beyond logo, geographic-focus, favorite, note update/delete).

---

## 3. Demos

Source of truth: `DemoRequest`, `DemoController`. Write API today: **`PUT /api/v1/demos/{id}/notes` + retry-notifications only.**

| UI Field / Operation | Visible | Editable | API Read | API Update | Missing / Notes |
|---|---|---|---|---|---|
| title_ar / title_en | ✅ | ✅ | ✅ (get) | ❌ | **GAP** |
| type_option_id / mode_option_id | ⚠️ (form commented) | pass-through | ✅ | ❌ | **GAP** |
| meeting_date | ✅ | ✅ | ✅ | ❌ | **GAP** |
| meeting_time | ✅ | ✅ | ✅ | ❌ | **GAP** |
| meeting_url | ✅ | ✅ | ✅ | ❌ | **GAP** |
| cover_image | ✅ | ✅ upload | ⚠️ | ❌ | **GAP** |
| status | ✅ | read-only (cron) | ✅ | — | not admin-editable |
| meeting_month_key | derived | auto | ✅ | — | derived |
| notes | ✅ | ✅ | ✅ | ✅ | `demo_update_notes` |
| **Slots** (startup + start/end time) | ✅ | ✅ add/remove/reorder | ⚠️ | ❌ | **GAP: no slot API** |
| **Investors (pins)** `demo_investors` | ✅ | ✅ sync | ✅ (get) | ❌ | **GAP: no link/unlink** |
| **Groups** `demo_groups` (primary audience) | ✅ | ✅ sync | ⚠️ | ❌ | **GAP: no group attach/detach** |
| **Investor attendance** (admin status) | ✅ | ✅ | ⚠️ | ❌ | **GAP: no attendance write** |
| **Startup attendance** (admin status) | ✅ | ✅ | ⚠️ | ❌ | **GAP** |
| per-startup investor notes | ✅ | read-only | ⚠️ | — | view-only in UI too |
| retry notifications | ✅ | ✅ | ✅ preview | ✅ execute | — |
| **Create demo** | ✅ (form) | ✅ | — | ❌ | **GAP: no create API** |
| **Delete demo** | ✅ | ✅ | — | ❌ | (delete deliberately absent across API) |

Read coverage **~90%** · Update coverage **~12%** (only notes + retry; core fields, create, slots, audience links, attendance all missing).

---

## 4. Committees

Source of truth: `CommitteeRequest`, `CommitteeController`. Write API today: **`PUT /api/v1/committees/{id}/notes` + retry-notifications only.**

| UI Field / Operation | Visible | Editable | API Read | API Update | Missing / Notes |
|---|---|---|---|---|---|
| meeting_date | ✅ | ✅ | ✅ (get) | ❌ | **GAP** |
| meeting_time | ✅ | ✅ | ✅ | ❌ | **GAP** |
| meeting_url | ✅ | ✅ | ✅ | ❌ | **GAP** |
| status | ✅ | read-only (cron) | ✅ | — | — |
| meeting_month_key | derived | auto | ✅ | — | — |
| notes | ✅ | ✅ | ✅ | ✅ | `committee_update_notes` |
| **Slots** (startup + start/end) | ✅ | ✅ | ⚠️ | ❌ | **GAP** |
| **Investors (members)** `committee_investors` | ✅ | ✅ sync | ✅ (get) | ❌ | **GAP: no link/unlink** |
| **Investor attendance** (admin status) | ✅ | ✅ | ⚠️ | ❌ | **GAP** |
| **Startup attendance** (admin status) | ✅ | ✅ | ⚠️ | ❌ | **GAP** |
| **Evaluations** (pass/fail matrix) | ✅ | ✅ | ❌ | ❌ | **GAP: committee-only feature, no API at all** |
| per-startup investor notes | ✅ | read-only | ⚠️ | — | — |
| retry notifications | ✅ | ✅ | ✅ preview | ✅ execute | — |
| **Create committee** | ✅ (form) | ✅ | — | ❌ | **GAP** |

Read coverage **~90%** · Update coverage **~10%** (only notes + retry).

---

## Coverage summary

| Section | API Read | API Update | Biggest gaps |
|---|---|---|---|
| Investors | ~100% | ~82% | preferred sectors/stages/payment-methods, note update/delete, tag detach/rename, favorite |
| Companies | ~100% | ~70% | team-member CRUD, file CRUD (pitch/other/DD), geographic-focus, note update/delete |
| Demos | ~90% | ~12% | core fields, create, slots, audience links, attendance |
| Committees | ~90% | ~10% | core fields, create, slots, members, attendance, evaluations |

See `NUMU_MCP_GAP_ANALYSIS.md` for the prioritized close-out plan and `NUMU_MCP_API_DOCUMENTATION.md` for endpoint details.
