> ## Documentation Index
> Fetch the complete documentation index at: https://docs.melonly.xyz/llms.txt
> Use this file to discover all available pages before exploring further.

# Record mappings

> How matchers, Search fill, and search indices connect templates, Run, Record Search, and uniqueness

**Matchers** tell CAD that two fields are the same piece of data, even when their labels differ. You set them in the template editor.

This page explains how matchers, option matchers, Search fill, and charge totals work together.

<Note>
  A matcher is lowercase letters and underscores only, up to 64 characters. Numbers, spaces, and hyphens are removed as you type. Leave **Matcher** blank if the field should not be searchable, filled from another record, or checked for uniqueness. CAD ignores the field **label** — “First Name” and “Given Name” only link if both use `first_name`.
</Note>

## Two kinds of matchers

| Where you set it | What it names | Example |
| - | - | - |
| The field itself (**Matcher**) | The *kind of data* on the form | `first_name`, `veh_plate`, `sex` |
| Each choice on a Select, Multiple choice, or Checkboxes field | Which *option* that choice is | On a Sex field: `male`, `female`, `other` |

Think of the field matcher as the folder, and the option matcher as the file inside it.

* Field matchers are how Search fill, Run, Record Search, uniqueness, and charge totals find a field.
* Option matchers are how CAD picks the right choice when labels differ (“Male” vs “M”) or when CAD itself sets the value (`valid` / `suspended` / `expired`).

## How Search fill matches things up

**Search fill** on a Standard section does two jobs: **find** a record, then **copy** onto this section.

### 1. Find the source record

| Search fill | How CAD finds it | What officers type |
| - | - | - |
| Civilian | Name search | First name, last name, date of birth (also middle initial and alias if those fields exist) |
| Vehicle | Plate search | Plate |
| Licence | Licence search | Licence number |
| A custom search (named after your [search index](#custom-search-indices)) | The matchers on that index | Whatever fields you added to the index |
| Record ID | The record’s ID | The ID itself — no matcher required |

You can turn on more than one Search fill on the same section (for example Civilian and Licence). CAD tries each source you enabled.

### 2. Copy every shared matcher

Finding a civilian does **not** only copy name and date of birth. CAD takes **every field on the found record that has a matcher**, then looks for the **same matcher** on this section and copies the value across.

Example: a civilian template has `first_name`, `last_name`, `dob`, `sex`, and `contact_number`. An arrest report section with Search fill **Civilian** and those same matchers gets all five fields filled — not just the name used to search.

Copying skips:

* Fields with no matcher
* Read-only fields
* Supervisor-only fields, unless the author is a supervisor for that record type

If the destination has an input mask, CAD fits the copied value to that mask. Types can differ: a date can fill a text field, a selected option can fill text with the option’s label, and so on.

### 3. How choices are matched

When the destination is a Select, Multiple choice, or Checkboxes field, CAD does **not** require the labels to match. It tries, in order:

1. **Option matcher** — if the source option and a destination option share the same matcher, that choice is selected. This is the reliable way.
2. **Option label** — if there is no matcher match, CAD compares labels, ignoring letter case (“Male” copies onto “male”).

Checkboxes can copy several options at once, still by option matcher.

<Accordion title="Worked example: Sex">
  Civilian template:

  * Field matcher: `sex`
  * Options: **Male** (option matcher `male`), **Female** (option matcher `female`)

  Arrest report:

  * Field matcher: `sex`
  * Options: **M** (option matcher `male`), **F** (option matcher `female`)

  Search fill **Civilian** copies the field because both use `sex`. It selects **M** or **F** because the option matchers (`male` / `female`) match, even though the labels are different.

  If you leave option matchers blank, “Male” only copies onto another option also labelled “Male” (ignoring case).
</Accordion>

After a record is saved, [Run](/CAD/User/run) and Record Search can find it by matcher. Opening a new record can copy those values again through Search fill.

Changing a matcher on a template does not update existing records by itself. Lookups keep using the old matcher until those records are saved again. Searches and uniqueness checks ignore letter case.

## Required matchers by record type

These types will not save until the listed matchers exist. Each matcher must appear **once**.

| Record type | Required matcher | Allowed field types |
| - | - | - |
| Civilian | `first_name` | Text |
| Civilian | `last_name` | Text |
| Civilian | `dob` | Date |
| Warrant | `first_name`, `last_name`, `dob` | Text, Text, Date |
| BOLO | `first_name`, `last_name`, `dob` | Text, Text, Date |
| Vehicle | `veh_plate` | Text |
| Vehicle | `veh_iss` | Date |
| Licence | `first_name`, `last_name`, `dob` | Text, Text, Date |
| Licence | `licence_number` | Text or Random |
| Licence | `licence_iss` | Date |

Police, fire, EMS, DOT, and law records and reports have **no** required matchers. Add whatever you need for fill and search.

Civilian and BOLO are **one-off** types: only one template of each may exist.

<Warning>
  Required matchers must sit on a field that is **required**, **not read-only**, and **not behind a section or field dependency**. They also cannot live in a duplicatable section. Otherwise CAD will refuse to save the template.
</Warning>

## Built-in field matchers

CAD treats these names as special. You can still invent your own (`phone_number`, `case_number`, and so on) for anything else.

### Identity (civilian / warrant / BOLO)

| Matcher | Typical type | Meaning |
| - | - | - |
| `first_name` | Text | First name. Required identity, Run name search |
| `last_name` | Text | Last name. Required identity, Run name search |
| `middle_initial` | Text | Middle initial. Included in Run name search / fill |
| `alias` | Text | Alias / AKA. Included in Run name search / fill |
| `dob` | Date | Date of birth. Required identity, used to calculate age |
| `age` | Number or text | Age. CAD calculates this from `dob` on the same section |
| `contact_number` | Text | Phone number on character / licence cards |
| `residence` | Text or address | Address on character / licence cards |
| `photo`, `identity_image`, `identity_photo` | Image | Portrait on Run results. These ids are recognized even though they are not in the matcher dropdown. An image field whose label contains “photo”, “identity image”, or “civilian photo” is treated the same way |
| `sex` | Select / choice | Sex. Pair with option matchers `male`, `female`, `other` |
| `roblox_username` | Text | Links a civilian to a Roblox user for auto-create and licence scan |

### Vehicle

| Matcher | Typical type | Meaning |
| - | - | - |
| `veh_plate` | Text | Plate. Required, Run plate search, traffic stops |
| `veh_iss` | Date | Registration issue date. Required; expiry is calculated from it |
| `veh_exp` | Date | Registration expiry. CAD calculates this (read-only on the form) |
| `veh_make` | Text or choice | Make. Shown on Run |
| `veh_model` | Text or choice | Model. Shown on Run |
| `veh_year` | Text or choice | Year. Shown on Run |
| `veh_col` | Text or choice | Colour. Shown on Run |
| `veh_type` | Text or choice | Type. Shown on Run |

### Licence

| Matcher | Typical type | Meaning |
| - | - | - |
| `licence_number` | Text or Random | Licence number. Required, Run licence search. Traffic and speeding charges on a record that also has this matcher apply points and suspensions to that licence |
| `licence_iss` | Date | Issue date. Required |
| `licence_exp` | Date | Expiry. CAD calculates this from the issue date and the template expiry (RP days / time scale) |
| `licence_points` | Number or text | Live demerit total |
| `licence_class` | Text | Class. Shown beside Conditions on a licence Run. Text fields only |
| `licence_conditions` | Text, choice, checkboxes, date, or time | Conditions. Shown beside Class on a licence Run |
| `licence_status` | Select / choice | Status. CAD selects the option — officers cannot pick it. See [option matchers](#option-matchers) |

### Authoring unit (filled on create)

These fill from the unit that created the record when the field is empty:

| Matcher | Fills with |
| - | - |
| `unit_number` or `unit_num` | Callsign |
| `unit_name` | Unit name |
| `unit_rank` | Rank |
| `unit_agency` | Agency abbreviation |
| `unit_division` or `unit_subdivision` | Subdivision |
| `unit_platoon` | Platoon |
| `unit_id` | Unit ID |
| `unit_location` or `unit_loc` | Last known location |
| `unit_street`, `unit_building`, `unit_postal` | Location parts |

The matcher dropdown lists the longer names (`unit_number`, `unit_division`, `unit_location`). The short names above are accepted as well when a field is filled from the creating unit.

Built-in unit search looks up `unit_number`, `unit_agency`, `unit_sub`, and `unit_id`. `unit_sub` is that search matcher for subdivision. Autofill of the subdivision onto a new record uses `unit_division` or `unit_subdivision`.

### Time

| Matcher | Meaning |
| - | - |
| `now` | Stamps a date or time field with the current local date or time when the record is created, including when the field is read-only. `dob` is never auto-stamped this way |

A date or time field with any other matcher is left blank until someone fills it.

## Option matchers

On each choice of a Select, Multiple choice, or Checkboxes field there is a **Matcher** box next to the label and the flag checkbox. That is the option matcher.

Use them whenever two templates might use different wording for the same choice, or when CAD needs to pick an option for you.

### Built-in option matchers

These only work when the **field** also has the matcher in the first column.

| Field matcher | Option matcher | When CAD selects it |
| - | - | - |
| `sex` | `male`, `female`, `other` | Search fill copies sex between records |
| `licence_status` | `valid` | Licence is current |
| `licence_status` | `suspended` | Licence is suspended |
| `licence_status` | `expired` | Licence is past its expiry |
| `charges_held_for_bond` | `yes` | The charges include Hold for Bond |
| `charges_held_for_bond` | `no` | They do not |

You can add option matchers on any other choice field (`veh_col`, `veh_type`, custom fields). Search fill will use them the same way.

### Flags

If an option’s **flag** checkbox is on and that option is selected, the option’s **label** appears as a flag on the record. Run plays the lookup-flags tone and TTS. Custom flags are red alerts and, on the Police panel, are sent to dispatch.

Licences and vehicles also add flags from their own state, even if no option is flagged:

| Flag | Colour | Who sees it |
| - | - | - |
| Licence expired | Yellow warning | The unit that ran it |
| Licence suspended | Yellow warning | The unit that ran it |
| Licence revoked | Yellow warning | The unit that ran it |
| Registration expired | Yellow warning | The unit that ran it |
| Registration cancelled | Yellow warning | The unit that ran it |
| Open warrant | Red alert | The unit that ran it, and dispatch on the Police panel |

A common pattern is a “Flags” multiple-choice field with field matcher `flags`, and each dangerous option marked as a flag.

## Charge matchers

Put these on a **Standard** section (not the Charges section itself). CAD fills them from the charges on **this same record** and locks the field so officers cannot edit it.

Use them when you want totals on a citation or arrest form without relying only on a Charges Summary section. The record still needs a **Charges** section (or a legacy Speed section) so there is something to total.

| Matcher | Typical type | Shows |
| - | - | - |
| `charges_fine_subtotal` | Number or text | Sum of fines **before** surcharges. Text includes your currency symbol |
| `charges_fine_total` | Number or text | Fines **plus** surcharges. Text includes your currency symbol |
| `charges_points` | Number or text | Total licence points from the charges |
| `charges_jail_total` | Number or text | Total jail days. Text is formatted like `10 days` |
| `charges_bond` | Number or text | Bond owed. Text includes your currency symbol |
| `charges_held_for_bond` | Text, number, or choice | Whether any charge is Hold for Bond. Text is `Yes` / `No`. Number is `1` / `0`. Choice fields need option matchers `yes` and `no` |
| `charges_surcharge_*` | Number or text | Amount for one surcharge. Replace `*` with that surcharge’s **abbreviation**, **name**, or **id**, lowercase |

Surcharge example: in Law → Surcharges you have a surcharge named “Court Costs” with abbreviation `cc`. On the template, set Matcher to `charges_surcharge_cc` (or `charges_surcharge_court_costs`). CAD fills it with that surcharge’s amount for the charges on the record. The surcharge id works the same way if you use that instead of the abbreviation or name.

<Tip>
  Add a read-only text field with matcher `charges_fine_total` under your Charges section so officers always see the payable total next to the charge list.
</Tip>

### Licence effects from charges

Traffic and speeding charges look at the **same record** for a field with matcher `licence_number`. If a licence exists with that number:

* Demerit points × charge count are added to the licence
* A suspension duration marks the licence suspended
* The licence form then shows the `licence_status` option whose matcher is `suspended` (or `expired` / `valid`)

Criminal charges with **Hold For Bond** create civilian holds unless the template has [Don't Hold or Bond](/CAD/Admin/recordsreports#dont-hold-or-bond).

## Unique fields

On text, text area, number, date, time, and random fields:

| Unique type | Rule |
| - | - |
| Not Unique | No extra check |
| Local | No other record may reuse this value on **this same field** (this template field only) |
| Global | No other record on the server may reuse this value on **any field with the same matcher** |

A field cannot be both read-only and unique unless it is a **Random** field (CAD generates the value). Random unique values are generated when the record is first created.

Use **Global** uniqueness to keep one `licence_number` or `veh_plate` across the CAD.

## Custom search indices

Admin → **Records & Reports** → **Search Indices**. Up to **5** indices, **4** fields each.

Each index becomes another Record Search tab, and another **Search fill** source (the first index is the first custom source, the second index the next, and so on).

| Setting | Meaning |
| - | - |
| Search type name | Tab label in Record Search |
| Record type | Optional. Limits hits to that type (`N/A` = all types) |
| Field name | Label on the search form |
| Matcher | Which matcher this box searches |
| Mask | Optional input mask. Queries that do not match the mask are rejected |

Query order follows the field list: the first box searches the first matcher, the second box the second matcher, and so on.

**Full** mode requires every non-empty query to match the same record. **Partial** mode matches if any query hits. Each query can be starts with, ends with, exact, or contains.

Built-in Run tabs do **not** use custom indices. They always search name, plate, or licence number as in [How Search fill matches things up](#how-search-fill-matches-things-up). Custom indices only appear in Record Search (and as Search fill sources on templates).

After a custom search finds a record, fill still copies **every** shared matcher — not only the fields you searched by.

New CADs include a **Phone Number** example (matcher `phone_number`, civilian, mask `(###) ###-####`). Add a `phone_number` matcher on civilian templates for it to return results.

<Steps>
  <Step title="Put the matcher on the template" icon="pen">
    Open the record template. On the field officers fill in, set **Matcher** to a stable name such as `phone_number`.
  </Step>

  <Step title="Create the search index" icon="magnifying-glass">
    Records & Reports → **Search Indices** → **+**. Set the same matcher. Restrict the record type if only one type should match.
  </Step>

  <Step title="Use it" icon="check">
    Officers get a new tab in Record Search. On other templates, enable that custom source under **Search fill** so selecting a hit copies matching fields.
  </Step>
</Steps>

## Dependencies

Sections and fields can hide until earlier fields match a rule (equal, not equal, contains). AND / OR logic is supported.

Hidden fields are skipped for required checks and do **not** count toward required matchers on the template. Keep identity matchers (`first_name`, `veh_plate`, and similar) on a section that is always visible.

## Practical rules

* Reuse the built-in matchers whenever the data is identity, a plate, a licence, or a charge total. That is what Run, warrants, bonds, traffic stops, and live totals read.
* Put the **same field matcher** on both templates you want Search fill to connect. Put the **same option matcher** on choices that mean the same thing, even if the labels differ.
* Use a custom matcher (`case_number`, `phone_number`, `insurance_policy`) for anything server-specific, then expose it with a search index if officers need to look it up.
* Do not put two required identity matchers of the same name on one template.
* Keep unique plates and licence numbers **Global**.
* Changing a matcher on a live template does not update old records until they are saved again. Search fill on *other* templates only copies if they share the new matcher.

For the screens to create templates and indices, see [Records & Reports](/CAD/Admin/recordsreports).

<Card title="Need help?" icon="headset" href="https://melonly.xyz/discord">
  Still have questions? Join our [Discord server](https://melonly.xyz/discord) for support from the Melonly team.
</Card>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.