# Company IM + TKO Investor Fields (Developer Doc)

## Goal
Add “rich” UI behavior for company dynamic fields:

- `Im1..Im9`: autocomplete user picker (stored as email)
- `tko_investor*`: remote dropdown investor picker (stored as `edm_id`)
- profile rendering resolves IDs/emails to human readable labels
- textarea edit locking based on `tko_investor2`

## UI Components
### Edit form inputs
Implemented in `lncshared/resources/assets/js/components/fields/inputs-list.vue`

Input selection rules:
- IM fields: `field.input_type == 'text'` and `field.name` starts with `im` (case-insensitive, up to `im9`)
  - Component: `lncshared/resources/assets/js/components/forms/input-email-autocomplete.vue`
- Investor fields: `field.input_type == 'text'` and `field.name` is `fund1/fund2` OR starts with `tko_investor`
  - Component: `lncshared/resources/assets/js/components/forms/input-edm-fund.vue`

### Profile read-only rendering
Implemented in `lncshared/resources/assets/js/components/fields/fields-list.vue`

Display rules:
- `Im1..Im9`: uses `user-email-display.vue`
  - resolves stored email into `first_name last_name`
  - unknown values are displayed with a yellow background
- `tko_investor*`: uses `fund-edm-display.vue`
  - resolves stored `edm_id` into `short_name`
  - unknown values are displayed with a yellow background

## API
All routes are under `routes/api.php`.

### Users (IM fields)
- `POST /api/search/user_search` (`api.search.user_search`)
  - returns users matching email/first_name/last_name (min 2 chars)

### EDM investors (TKO fields)
- `POST /api/search/edm_investors` (`api.search.edm_investors`)
  - case-insensitive search using PostgreSQL `ILIKE`
  - matches on `short_name` or `edm_id`
  - returns `edm_id`, `short_name`, and `value=edm_id`
- `GET /api/edm_investor_lookup` (`api.edm_investor_lookup`)
  - resolves `edm_id` to `short_name` for default label rendering

## Validation (Server-side)
Implemented in `app/Models/Company.php` (`Company::rules()`).

- IM fields (`im1..im9`):
  - enforced as: `nullable|email|exists:users,email`
- TKO fields (`tko_investor*` and also `fund1/fund2`):
  - enforced as: `nullable|string|exists:edm_investors,edm_id`

Important: overrides are applied only when a corresponding dynamic field already exists.

## Textarea locking rule (edit-only)
Implemented in `app/Models/Company.php` in `booted()` using `static::retrieved()`.

Condition:
- applies ONLY on the web route named `companies.edit`
- when `company.data->tko_investor2` is **not empty**
- then set `no_edit = true` for every dynamic field:
  - `input_type == 'textarea'`
  - `field_name` ends with `2`

Implementation notes:
- `dynamicFields` are cloned per instance before setting `no_edit`
- the edit UI excludes fields when `full_property.no_edit` is true

