# Custom Fields

Custom fields allow organizations to define structured metadata that appears in issue sidebars and repository settings across all repos in the organization.

## Overview

Custom fields are defined at the **organization level** in Org Settings > Custom Fields. Each field has a scope:

- **Issue scope** — appears in the issue sidebar for inline editing
- **Repo scope** — appears in Repository Settings > Metadata for repo-level values

## Field Types

| Type | Description | Example |
|------|-------------|---------|
| `text` | Free-form text input | "Affected Component" |
| `number` | Numeric input | "Story Points" |
| `date` | Date picker | "Due Date" |
| `dropdown` | Select from predefined options | "Priority: Low/Medium/High/Critical" |
| `checkbox` | Boolean toggle | "Requires QA" |
| `url` | URL input | "Design Link" |

## Org Settings

Navigate to **Organization Settings > Custom Fields** to manage field definitions.

Each field has:

| Field | Description |
|-------|-------------|
| Name | Display name |
| Scope | `issue` (sidebar) or `repo` (metadata) |
| Type | One of: text, number, date, dropdown, checkbox, url |
| Options | JSON array for dropdown options (e.g., `["Low","Medium","High"]`) |
| Description | Help text (shown as tooltip) |
| Sort Order | Controls display order |
| Is Active | Inactive fields are hidden from new forms but preserved on existing entities |

## Issue Sidebar

Issue-scoped fields appear in the sidebar between labels and milestones. Dropdown fields auto-submit on change. Text/number/date fields display their current value.

Each field renders as an inline form posting to:
```
POST /{owner}/{repo}/issues/{issue_id}/custom-fields/{field_id}
```

## Repository Metadata

Repo-scoped fields appear on the **Repository Settings > Metadata** page. All fields for the org are shown with their current values for the repository. Values are saved via form POST.

## Issue Template Integration

Custom fields can be pre-filled from issue template YAML frontmatter:

```yaml
name: Bug Report
about: Report a bug
custom_fields:
  Priority: High
  Affected Component: Backend
```

When a new issue is created from this template, the sidebar shows the custom fields with the specified defaults pre-selected.

## API

### Issue-Level Custom Fields

| Method | Path | Description |
|--------|------|-------------|
| GET | `/api/v1/repos/{owner}/{repo}/issues/{index}/custom-fields` | Get field values for an issue |
| PUT | `/api/v1/repos/{owner}/{repo}/issues/{index}/custom-fields` | Set field values (name-value map) |

### Repo-Level Metadata

| Method | Path | Description |
|--------|------|-------------|
| GET | `/api/v1/repos/{owner}/{repo}/metadata` | Get repo metadata field values |
| PUT | `/api/v1/repos/{owner}/{repo}/metadata` | Set repo metadata field values |

### Org-Level Definitions

| Method | Path | Description |
|--------|------|-------------|
| GET | `/api/v1/orgs/{org}/custom-fields` | List all field definitions |
| POST | `/api/v1/orgs/{org}/custom-fields` | Create a field definition |
| DELETE | `/api/v1/orgs/{org}/custom-fields/{id}` | Delete a field definition |

## Database

### Tables

**`custom_field_def`** — field definitions (org-level)

| Column | Type | Description |
|--------|------|-------------|
| id | bigint | Primary key |
| owner_id | bigint | Org ID (0 = legacy repo-level) |
| repo_id | bigint | 0 for org-level definitions |
| scope | varchar(10) | `issue` or `repo` |
| name | varchar | Field name |
| field_type | varchar(20) | text, number, date, dropdown, checkbox, url |
| description | text | Help text |
| options | text | JSON array for dropdown options |
| required | bool | Whether the field is required |
| sort_order | int | Display order |
| is_active | bool | Visibility flag |

**`custom_field_value`** — field values (per entity)

| Column | Type | Description |
|--------|------|-------------|
| id | bigint | Primary key |
| entity_id | bigint | Issue ID or Repo ID |
| entity_type | varchar(10) | `issue` or `repo` |
| field_id | bigint | FK to custom_field_def |
| value | text | The stored value |

### Cascade on Delete

When a field definition is deleted, all associated values in `custom_field_value` are also deleted.

## Relationship to Other Systems

| System | Relationship |
|--------|-------------|
| Update Server | Repo-scoped custom fields with specific names (Extension Name, Display Name, etc.) are read by the update feed generators as the highest-priority metadata source. |
| Manifest Settings | Manifest fields follow the moko-platform schema and are separate from custom fields. Custom fields are user-defined; manifest fields are standardized. |
| Issue Statuses | Custom statuses are a separate feature with their own dedicated table and UI, not implemented as custom fields. |

---

| Revision | Date | Author | Description |
|---|---|---|---|
| 1.0 | 2026-06-06 | Jonathan Miller (@jmiller) | Initial version |
