Skip to content

Lookup Tables

FORGE provides a generic lookup table system for managing key-value reference data used throughout your application. Lookups power dropdown menus, status labels, category lists, and any other standardized set of values that administrators need to manage without code changes.

Overview

Instead of hardcoding enum values or creating separate tables for every dropdown, the lookup system stores all reference data in a single table grouped by type. Administrators can add, edit, translate, and reorder values through the admin panel.

Database Schema

The lookups table stores all reference values:

ColumnTypeDescription
idUUIDPrimary key
typeVARCHAR(100)Group name (e.g., status, priority)
keyVARCHAR(100)Machine-readable identifier
valueVARCHAR(255)Human-readable display value
translationsJSONBPer-language translated values
is_activeBOOLEANWhether this value is available for selection
sort_orderINTEGERDisplay ordering within the type group
created_atTIMESTAMPRecord creation timestamp
updated_atTIMESTAMPLast update timestamp

Example Data

┌──────────┬────────────┬──────────────┬─────────────┐
│   type   │    key     │    value     │ sort_order  │
├──────────┼────────────┼──────────────┼─────────────┤
│ status   │ active     │ Active       │ 1           │
│ status   │ inactive   │ Inactive     │ 2           │
│ status   │ pending    │ Pending      │ 3           │
│ priority │ low        │ Low          │ 1           │
│ priority │ medium     │ Medium       │ 2           │
│ priority │ high       │ High         │ 3           │
│ priority │ critical   │ Critical     │ 4           │
│ category │ blog       │ Blog Post    │ 1           │
│ category │ news       │ News Article │ 2           │
│ category │ tutorial   │ Tutorial     │ 3           │
└──────────┴────────────┴──────────────┴─────────────┘

Translations Object Structure

json
{
  "en": { "value": "Active" },
  "ar": { "value": "نشط" },
  "fr": { "value": "Actif" }
}

API Endpoints

MethodPathDescription
GET/api/lookups?type=statusRetrieve all active values for a type

Example Response

json
[
  {
    "id": "uuid-1",
    "type": "status",
    "key": "active",
    "value": "Active",
    "sort_order": 1
  },
  {
    "id": "uuid-2",
    "type": "status",
    "key": "inactive",
    "value": "Inactive",
    "sort_order": 2
  },
  {
    "id": "uuid-3",
    "type": "status",
    "key": "pending",
    "value": "Pending",
    "sort_order": 3
  }
]

TIP

The API only returns values where is_active = true, sorted by sort_order. Translated values are automatically returned based on the request's Accept-Language header.

Admin Interface

The admin panel provides a grouped management interface:

  • Type List -- View all lookup types with the count of values in each
  • Value Management -- Add, edit, reorder, and deactivate values within a type
  • Translation Editor -- Translate values for each active language
  • Bulk Actions -- Activate or deactivate multiple values at once

Creating a New Lookup Type

To add a new lookup type, simply create a value with a new type name. The system automatically groups values by their type.

WARNING

Avoid changing lookup key values after they are in use. Other parts of the application may reference these keys. If you need to rename a key, search the codebase for usages first and update all references.

Usage in Application Code

Backend

rust
// Fetch all active statuses
let statuses = lookup_service.get_by_type("status").await?;

// Fetch a single value by type and key
let status = lookup_service.get_by_type_and_key("status", "active").await?;

Frontend

tsx
// Use lookups to populate a dropdown
const { data: statuses } = useLookups("status");

<select>
  {statuses?.map((item) => (
    <option key={item.key} value={item.key}>
      {item.value}
    </option>
  ))}
</select>

Common Use Cases

TypePurpose
statusRecord statuses (active, inactive, etc.)
priorityPriority levels for tickets or tasks
categoryContent or product categories
countryCountry list for address forms
currencySupported currencies
genderGender options for user profiles
departmentOrganizational departments

TIP

Lookups are cached on the backend. After updating values through the admin panel, the cache is automatically invalidated so changes take effect immediately.

Released under the MIT License.