# Contribution v1 Data Model

> Status: v1 decision doc for #43. This captures the approved contribution data model after Plan PR #52. It defines the data contract; it does not implement kk-api schema or endpoints.

## Decision

v1 is **multiselect-primary with free-text-secondary**.

One contribution records what a contributor did with one shown data item:

- the shown data item / prompt the user saw;
- the UI language used to render question, explanation, and options;
- the target dialect context the task is collecting for;
- one or more selected reviewed answer options, or free text in `other_text`, or an explicit `not_provided` state;
- dialect metadata and provenance.

This is not a Kurdish language-learning level flow. There are no A1/A2-style proficiency levels.

## Contribution Unit

One v1 contribution is:

```
shown data item
  + input mode
  + selected options or other_text
  + UI/source language metadata
  + target dialect context
  + dialect provenance
  + audit snapshots/hashes
```

The first shown data items are expected to be words, phrases, or sentences. Later phases may add media references such as image, audio, or video. Audio capture itself is deferred.

## Required Contract Fields

| Field | Purpose |
|---|---|
| `shown_data_id` / `prompt_id` | Stable reference to the item shown to the contributor. |
| `shown_data_version` | Version or equivalent revision marker for auditability. |
| `source_language` | Language of the shown data / source concept. |
| `ui_language` | Language used for UI labels, question title, explanation, and rendered option text. |
| `input_mode` | One of `selected_options`, `other_text`, or `not_provided`. |
| `selected_option_ids` | One or more reviewed options selected by the contributor when `input_mode = "selected_options"`. |
| `other_text` | Free-text secondary input when `input_mode = "other_text"`. Available from v1 launch. |
| `target_dialect_context` | The dialect/sub-dialect context the task is collecting for. |
| `declared_dialect_ids` | Contributor-declared dialects, nullable/empty for low-friction contribution. |
| `dialect_source` | Provenance for dialect metadata: `user_confirmed`, `prior_default`, or `not_provided`. |

## Audit Snapshot

Each contribution must remain understandable even if catalogue content changes later.

Store:

- displayed question/explanation text;
- displayed shown data text or media reference;
- shown data content hash;
- displayed option text snapshots;
- option content hashes;
- selected option IDs when applicable.

## Language Model

UI language and dialect are independent.

- **UI language** controls the app chrome, question title, explanation, and displayed option text.
- **Target dialect context** describes which dialect/sub-dialect the task is collecting for.
- **Declared dialect metadata** describes what the contributor says they speak/write, when provided.

City/country/place context may create a dialect prior, but must never become a hard dialect label.

## Low-Friction Rules

- Do not require a contributor to choose a dialect label before saving useful data.
- Allow `not_provided` when neither selected options nor free text applies.
- Allow free text as `other_text` from v1 launch, but keep multiselect as the primary flow.
- Defer audio capture and free-text-primary workflows.

## Storage Guidance

For the first kk-api slice, a generic contribution envelope is acceptable if it names the durable fields above clearly.

Normalize selected options and dialect tags into join tables only after the first corpus slice proves which queries and filters are needed.

## Downstream Impact

- #44 supplies prompt/option sourcing decisions and candidate seed content.
- #45 must align its catalogue model with prompt options, not prompt text only.
- kk-web contribution UI should render reviewed options first, expose `other_text` as secondary input, and preserve `not_provided`.
- Future analytics can compare selected option, `other_text`, declared dialect, prior dialect, and later inferred dialect.
