# Field Types System Architecture ## System Overview ``` ┌─────────────────────────────────────────────────────────────────┐ │ Frontend (Vue 3 + Nuxt) │ ├─────────────────────────────────────────────────────────────────┤ │ │ │ ┌───────────────────────────────────────────────────────────┐ │ │ │ View Components │ │ │ ├───────────────────────────────────────────────────────────┤ │ │ │ ListView.vue │ DetailView.vue │ EditView.vue │ │ │ │ - Data Table │ - Read Display │ - Form │ │ │ │ - Search │ - Sections │ - Validation │ │ │ │ - Sort/Filter │ - Actions │ - Sections │ │ │ │ - Bulk Actions │ │ │ │ │ └────────────────────────┬──────────────────────────────────┘ │ │ │ uses │ │ ┌────────────────────────▼──────────────────────────────────┐ │ │ │ FieldRenderer.vue │ │ │ │ Universal component for rendering any field type │ │ │ │ - Handles LIST, DETAIL, EDIT modes │ │ │ │ - Type-aware rendering │ │ │ │ - Validation support │ │ │ └────────────────────────┬──────────────────────────────────┘ │ │ │ uses │ │ ┌────────────────────────▼──────────────────────────────────┐ │ │ │ shadcn-vue Components │ │ │ │ Input, Textarea, Select, Checkbox, Switch, Calendar, │ │ │ │ Table, Badge, Dialog, Popover, etc. │ │ │ └───────────────────────────────────────────────────────────┘ │ │ │ │ ┌───────────────────────────────────────────────────────────┐ │ │ │ Composables │ │ │ ├───────────────────────────────────────────────────────────┤ │ │ │ useFields() │ useViewState() │ │ │ │ - Map backend data │ - CRUD operations │ │ │ │ - Build configs │ - State management │ │ │ │ - Generate sections │ - Navigation │ │ │ └───────────────────────────────────────────────────────────┘ │ │ │ │ ┌───────────────────────────────────────────────────────────┐ │ │ │ Type Definitions │ │ │ │ field-types.ts - TypeScript interfaces for field system │ │ │ └───────────────────────────────────────────────────────────┘ │ └─────────────────────────────────────────────────────────────────┘ │ │ HTTP/REST API ▼ ┌─────────────────────────────────────────────────────────────────┐ │ Backend (NestJS) │ ├─────────────────────────────────────────────────────────────────┤ │ │ │ ┌───────────────────────────────────────────────────────────┐ │ │ │ Controllers │ │ │ ├───────────────────────────────────────────────────────────┤ │ │ │ SetupObjectController │ RuntimeObjectController │ │ │ │ - GET /objects │ - GET /objects/:name │ │ │ │ - GET /objects/:name │ - GET /objects/:name/:id │ │ │ │ - GET /ui-config ✨ │ - POST /objects/:name │ │ │ │ - POST /objects │ - PUT /objects/:name/:id │ │ │ └────────────────────────┬────────────────┬─────────────────┘ │ │ │ │ │ │ ┌────────────────────────▼────────────────▼─────────────────┐ │ │ │ Services │ │ │ ├───────────────────────────────────────────────────────────┤ │ │ │ ObjectService │ FieldMapperService ✨ │ │ │ │ - CRUD operations │ - Map field definitions │ │ │ │ - Query building │ - Generate UI configs │ │ │ │ - Validation │ - Default metadata │ │ │ └────────────────────────┬──────────────────────────────────┘ │ │ │ │ │ ┌────────────────────────▼──────────────────────────────────┐ │ │ │ Models │ │ │ │ ObjectDefinition │ FieldDefinition ✨ │ │ │ │ - Object metadata │ - Field metadata │ │ │ │ │ - UIMetadata interface │ │ │ └───────────────────────────────────────────────────────────┘ │ └─────────────────────────────────────────────────────────────────┘ │ │ Prisma/Knex ▼ ┌─────────────────────────────────────────────────────────────────┐ │ Database (PostgreSQL) │ ├─────────────────────────────────────────────────────────────────┤ │ │ │ ┌───────────────────────────────────────────────────────────┐ │ │ │ object_definitions │ │ │ │ - id, tenant_id, api_name, label, plural_label │ │ │ │ - description, is_system, table_name │ │ │ └───────────────────────────────────────────────────────────┘ │ │ │ │ │ │ 1:many │ │ ▼ │ │ ┌───────────────────────────────────────────────────────────┐ │ │ │ field_definitions │ │ │ │ - id, object_definition_id, api_name, label, type │ │ │ │ - is_required, is_unique, is_system │ │ │ │ - ui_metadata (JSONB) ✨ NEW │ │ │ │ { │ │ │ │ placeholder, helpText, showOnList, showOnDetail, │ │ │ │ showOnEdit, sortable, options, rows, min, max, │ │ │ │ validationRules, format, prefix, suffix, etc. │ │ │ │ } │ │ │ └───────────────────────────────────────────────────────────┘ │ └─────────────────────────────────────────────────────────────────┘ ✨ = New/Enhanced component ``` ## Data Flow ### 1. Loading Object Definition ``` ┌──────────┐ GET /api/setup/objects/Contact/ui-config ┌──────────┐ │ │ ──────────────────────────────────────────────────> │ │ │ Frontend │ │ Backend │ │ │ <────────────────────────────────────────────────── │ │ └──────────┘ { objectDef with mapped fields } └──────────┘ │ │ useFields().buildListViewConfig(objectDef) ▼ ┌──────────────────────────────────────┐ │ ListViewConfig │ │ - objectApiName: "Contact" │ │ - mode: "list" │ │ - fields: [ │ │ { │ │ apiName: "firstName", │ │ type: "text", │ │ showOnList: true, │ │ ... │ │ } │ │ ] │ └──────────────────────────────────────┘ │ │ Pass to ListView component ▼ ┌──────────────────────────────────────┐ │ ListView renders data table │ └──────────────────────────────────────┘ ``` ### 2. Fetching Records ``` ┌──────────┐ GET /api/runtime/objects/Contact ┌──────────┐ │ │ ──────────────────────────────────────────────────> │ │ │ Frontend │ │ Backend │ │ │ <────────────────────────────────────────────────── │ │ └──────────┘ [{ id, firstName, lastName, ... }] └──────────┘ │ ▼ ┌──────────────────────────────────────┐ │ ListView displays records │ │ Each field rendered by │ │ FieldRenderer with mode="list" │ └──────────────────────────────────────┘ ``` ### 3. Field Rendering ``` ┌─────────────────────────────────────────────────────────────┐ │ FieldRenderer │ │ Props: { field, modelValue, mode } │ └────────────────────────┬────────────────────────────────────┘ │ ┌────────────────┼────────────────┐ │ │ │ ▼ ▼ ▼ mode="list" mode="detail" mode="edit" │ │ │ ▼ ▼ ▼ Simple text Formatted Input component or badge display with based on type: display labels - Input - Textarea - Select - DatePicker - Checkbox - etc. ``` ### 4. Saving Record ``` ┌──────────┐ ┌──────────┐ │ EditView │ ──> User fills form ──> Validation │ │ │ │ │ │ │ │ │ ▼ │ │ │ │ Valid? │ │ │ │ ✓ Yes │ │ │ │ @save event │ │ │ │ │ ──────────────────────────┘ │ │ │ │ │ │ │ │ POST/PUT /api/runtime/objects/Contact/:id │ Backend │ │ Frontend │ ──────────────────────────────────────────────────> │ │ │ │ │ │ │ │ <────────────────────────────────────────────────── │ │ │ │ { saved record } │ │ │ │ │ │ │ │ ──> Navigate to DetailView │ │ └──────────┘ └──────────┘ ``` ## Component Hierarchy ``` Page/App └── ObjectViewContainer ├── ListView │ ├── Search/Filters │ ├── Table │ │ ├── TableHeader │ │ │ └── Sortable columns │ │ └── TableBody │ │ └── TableRow (for each record) │ │ └── TableCell (for each field) │ │ └── FieldRenderer (mode="list") │ └── Actions (Create, Export, etc.) │ ├── DetailView │ ├── Header with actions │ └── Sections │ └── Card (for each section) │ └── FieldRenderer (mode="detail") for each field │ └── EditView ├── Header with Save/Cancel └── Form └── Sections └── Card (for each section) └── FieldRenderer (mode="edit") for each field └── Input component based on field type ``` ## Field Type Mapping ``` Database Type → FieldType Enum → Component (Edit Mode) ───────────────────────────────────────────────────────── string → TEXT → Input[type="text"] text → TEXTAREA → Textarea email → EMAIL → Input[type="email"] url → URL → Input[type="url"] integer → NUMBER → Input[type="number"] decimal → NUMBER → Input[type="number"] currency → CURRENCY → Input[type="number"] + prefix boolean → BOOLEAN → Checkbox date → DATE → DatePicker datetime → DATETIME → DatePicker (with time) picklist → SELECT → Select multipicklist → MULTI_SELECT → Select[multiple] lookup → BELONGS_TO → Combobox (relation picker) file → FILE → FileUpload image → IMAGE → ImageUpload richtext → MARKDOWN → Textarea (+ preview) json → JSON → Textarea (JSON editor) ``` ## View Mode Rendering ``` Field Type: TEXT ───────────────────────────────────────────────────── LIST mode │ Simple text, truncated │ {{ value }} ───────────────────────────────────────────────────── DETAIL mode │ Text with label │