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

# Schema Design

> Naming conventions, best practices, and example schemas for common app types.

## Naming Conventions

| Thing        | Convention           | Examples                                   |
| ------------ | -------------------- | ------------------------------------------ |
| Entity keys  | `snake_case`, plural | `tasks`, `contacts`, `inventory_items`     |
| Entity names | Title Case, plural   | "Tasks", "Contacts", "Inventory Items"     |
| Field keys   | `snake_case`         | `due_date`, `is_complete`, `contact_email` |
| Field names  | Title Case           | "Due Date", "Completed", "Contact Email"   |

## Best Practices

### Use `select` over `text` for constrained values

If a field has a known set of valid values (status, priority, category), use `select` rather than `text`. This ensures data consistency and enables efficient filtering.

```
✓  status: select ["open", "in_progress", "done"]
✗  status: text (free-form — "Open", "In Progress", "DONE" are all different)
```

### Use `multi_select` for tags

When a record can belong to multiple categories simultaneously, use `multi_select`:

```
tags: multi_select ["frontend", "backend", "design", "devops"]
```

### Mark truly required fields

Only mark a field as `required` if the record is meaningless without it. Overly strict required fields frustrate users and complicate imports.

### Use `relation` for cross-entity references

When a record in one entity refers to a record in another entity in the same app, use `type: relation` rather than a plain `text` field:

```
✓  project_id: relation → related_entity: "projects", display_field: "name"
✗  project_id: text (free-form string — no referential integrity or validation)
```

HASP validates that the referenced record exists when creating or updating a record.

### Keep entities focused

One entity per concept. Don't combine "tasks" and "comments" into one entity — make two entities and use a `relation` field in the comments entity to point back to the task.

### Set a `display_field`

Every entity should have a designated `display_field` — the field shown in lists and the HASP dashboard. Usually this is the main name or title field.

## Example Schemas

### Task Tracker

| Field          | Key              | Type     | Required | Notes                       |
| -------------- | ---------------- | -------- | -------- | --------------------------- |
| Title          | `title`          | text     | Yes      | display\_field              |
| Description    | `description`    | textarea | No       |                             |
| Status         | `status`         | select   | Yes      | open, in\_progress, done    |
| Priority       | `priority`       | select   | No       | low, medium, high, critical |
| Due Date       | `due_date`       | date     | No       |                             |
| Assignee Email | `assignee_email` | email    | No       |                             |

### Contact Directory

| Field   | Key       | Type          | Required |
| ------- | --------- | ------------- | -------- |
| Name    | `name`    | text          | Yes      |
| Email   | `email`   | email         | Yes      |
| Company | `company` | text          | No       |
| Role    | `role`    | text          | No       |
| Website | `website` | url           | No       |
| Tags    | `tags`    | multi\_select | No       |
| Notes   | `notes`   | textarea      | No       |

### Inventory

| Field          | Key              | Type    | Required | Notes          |
| -------------- | ---------------- | ------- | -------- | -------------- |
| Name           | `name`           | text    | Yes      | display\_field |
| SKU            | `sku`            | text    | Yes      |                |
| Category       | `category`       | select  | Yes      |                |
| Quantity       | `quantity`       | number  | Yes      | min: 0         |
| Unit Price     | `unit_price`     | number  | No       |                |
| Low Stock      | `is_low_stock`   | boolean | No       |                |
| Last Restocked | `last_restocked` | date    | No       |                |
