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:
| Column | Type | Description |
|---|---|---|
id | UUID | Primary key |
type | VARCHAR(100) | Group name (e.g., status, priority) |
key | VARCHAR(100) | Machine-readable identifier |
value | VARCHAR(255) | Human-readable display value |
translations | JSONB | Per-language translated values |
is_active | BOOLEAN | Whether this value is available for selection |
sort_order | INTEGER | Display ordering within the type group |
created_at | TIMESTAMP | Record creation timestamp |
updated_at | TIMESTAMP | Last 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
{
"en": { "value": "Active" },
"ar": { "value": "نشط" },
"fr": { "value": "Actif" }
}API Endpoints
| Method | Path | Description |
|---|---|---|
GET | /api/lookups?type=status | Retrieve all active values for a type |
Example Response
[
{
"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
// 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
// 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
| Type | Purpose |
|---|---|
status | Record statuses (active, inactive, etc.) |
priority | Priority levels for tickets or tasks |
category | Content or product categories |
country | Country list for address forms |
currency | Supported currencies |
gender | Gender options for user profiles |
department | Organizational 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.