# 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 │
{{ value }}
───────────────────────────────────────────────────── EDIT mode │ Input field │ ───────────────────────────────────────────────────── Field Type: BOOLEAN ───────────────────────────────────────────────────── LIST mode │ Badge (Yes/No) │ Yes ───────────────────────────────────────────────────── DETAIL mode │ Checkbox (disabled) + text │ Yes ───────────────────────────────────────────────────── EDIT mode │ Checkbox (editable) │ ───────────────────────────────────────────────────── Field Type: SELECT ───────────────────────────────────────────────────── LIST mode │ Selected label │ Active ───────────────────────────────────────────────────── DETAIL mode │ Selected label with styling │ Active ───────────────────────────────────────────────────── EDIT mode │ Dropdown select │ ───────────────────────────────────────────────────── ``` ## API Endpoints ``` Setup/Configuration (Metadata) ──────────────────────────────────────────────────── GET /api/setup/objects Returns: List of all object definitions GET /api/setup/objects/:objectName Returns: Object definition with fields GET /api/setup/objects/:objectName/ui-config ✨ Returns: Object definition with UI-ready field configs (fields mapped to frontend format with UIMetadata) POST /api/setup/objects Body: { apiName, label, description, ... } Returns: Created object definition POST /api/setup/objects/:objectName/fields Body: { apiName, label, type, uiMetadata, ... } Returns: Created field definition Runtime (Data CRUD) ──────────────────────────────────────────────────── GET /api/runtime/objects/:objectName Query: { search, filters, page, pageSize } Returns: Array of records GET /api/runtime/objects/:objectName/:recordId Returns: Single record POST /api/runtime/objects/:objectName Body: { field1: value1, field2: value2, ... } Returns: Created record PUT /api/runtime/objects/:objectName/:recordId Body: { field1: value1, field2: value2, ... } Returns: Updated record DELETE /api/runtime/objects/:objectName/:recordId Returns: Success status ``` ## Key Features ### Frontend - ✅ Universal field renderer for 15+ field types - ✅ Three view modes (list, detail, edit) - ✅ Client-side validation with custom rules - ✅ Responsive design (mobile-friendly) - ✅ Accessible components (WCAG compliant) - ✅ Type-safe with TypeScript - ✅ Composables for easy integration - ✅ Demo page for testing ### Backend - ✅ UI metadata stored in JSONB column - ✅ Field mapper service for transformation - ✅ Default metadata generation - ✅ Validation rule support - ✅ Flexible field type system - ✅ Multi-tenant support - ✅ RESTful API ### Database - ✅ Flexible schema with JSONB metadata - ✅ Support for custom objects - ✅ Versioning and migration support - ✅ Indexed for performance ## Extension Points ``` 1. Custom Field Types └─> Add to FieldType enum └─> Add rendering logic to FieldRenderer.vue └─> Add mapping in FieldMapperService 2. Custom Validation Rules └─> Add to ValidationRule type └─> Add validation logic in EditView.vue 3. Custom Actions └─> Add to ViewAction interface └─> Handle in view components 4. Custom Sections └─> Configure in DetailViewConfig/EditViewConfig └─> Auto-generation in useFields() 5. Custom Formatting └─> Add to UIMetadata └─> Implement in FieldRenderer.vue ``` This architecture provides a scalable, maintainable, and extensible system for building dynamic forms and views! 🎉