# Best Practices

### **Design for Queryability**

Structure your tables to make querying easy and predictable:

* Use **identifying columns** for anything users will pick in dropdowns or reference selectors.
* Prefer **flat fields** for filterable or sortable data (e.g. status, type, created\_at).
* If you’ll be using filters in UI components or automation, keep field names short and consistent (`status`, `owner`, `is_published`).

{% hint style="info" %}
Use **Dropdown** or **Multiple Choice** fields for controlled vocabularies like categories, states, or tags.
{% endhint %}

***

### **Normalize for Relationships — But Don’t Overdo It**

Ondeva supports **table references** (like foreign keys), allowing you to link entries across tables. Use them when:

* Data is **reused** in multiple places (e.g. users, clients, roles)
* You need to enforce **consistency** across submissions or components

**But avoid excessive normalization** for operational or analytical data. For example:

* If you're tracking tasks, log entries, or user actions — and frequently need to **group, sort, or filter** by related values — it’s often better to keep those fields **in the same table**.

{% hint style="info" %}
Good rule of thumb:\
**Normalize for reusability and UI clarity.**\
**Denormalize for filtering, grouping, and performance.**
{% endhint %}

#### When to Use Table References

* “One-to-one” or “many-to-one” relationships where a dropdown picker makes UX cleaner
* Data that’s maintained separately (e.g. Teams, Plans, Categories)

#### When to Flatten into the Same Table

* Metrics, submissions, or logs you’ll run analytics on
* Dynamic data where query speed matters more than data purity

{% hint style="warning" %}
Avoid deep reference chains — they create overhead and slow down performance in large apps.
{% endhint %}

***

### **Use ‘One Entry Per User’ for Personal Data**

For profile-like data (user preferences, application forms, onboarding data), enable the **One Entry Per User** setting:

* Prevents duplicate submissions
* Simplifies queries and access control
* Automatically ties data to the logged-in user

{% hint style="info" %}
Ideal for forms like “My Account”, “Startup Registration”, “Grant Application”, etc.
{% endhint %}

***

### **Model State Transitions Explicitly**

Use fields like `status`, `phase`, or `is_active` to represent the state of your entries. These fields allow:

* Workflows to branch based on state
* UI to show dynamic labels or badges
* Queries to filter logically (e.g. “only active”, “only pending approval”)

{% hint style="info" %}
Combine with [**Workflow steps**](https://docs.ondeva.com/workflow/steps-reference) that update these fields in automation flows.
{% endhint %}

***

### **Use Default Values to Streamline Entry Creation**

For operational tables (e.g. task tracking, logs, form submissions), set defaults to:

* Reduce user input friction
* Ensure consistency across manual and automated inserts
* Prevent missing or inconsistent data downstream

Example: Set default `status = pending`, `priority = normal`, or `country = DE`.

***

### **Validate Where It Matters**

Field-level validation prevents fragile downstream logic. Use:

* **Required** fields to avoid nulls
* **Regex** to ensure structure (e.g. emails, phone numbers)
* **Unique per user** for IDs, usernames, emails
* **Formula validations** for business rules (e.g. start\_date < end\_date)

{% hint style="info" %}
Don’t over-validate early. Start with must-haves, then layer in business logic over time.
{% endhint %}

***

### **Avoid Complex JSON in Text Fields**

Ondeva supports complex logic — but don’t overuse `Text` fields to store structured blobs. Instead:

* Use **rich text** for formatted content
* Use **JSON-compatible** structures only when paired with processing logic in workflows

{% hint style="info" %}
If you need to store complex objects, consider breaking them into related tables or use [`Create Object`](https://docs.ondeva.com/workflow/steps-reference/parameters-and-variables#create-object) + [`Save Entry`](https://docs.ondeva.com/workflow/steps-reference/data#save-entry) via workflows.
{% endhint %}

***

### **Tag and Track Metadata When Needed**

For audit trails or analytics, add fields like:

* `created_at` (date)
* `created_by` (user reference)
* `last_updated` (date)
* `is_deleted` (soft delete flag)

These can power:

* Admin interfaces
* Time-based automations
* Conditional access to data

***

### Summary

Strong data modeling leads to strong apps. When building with Ondeva:

* Keep schemas clean, normalized, and queryable
* Use built-in settings to simplify access control and validation
* Combine structured tables with workflows to build powerful, self-sustaining systems

**Tables aren’t just storage — they’re the living logic of your app.**
