From 38a499e1215eed9c24f040d4a60257924c46afc5 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 17 Jan 2026 10:42:59 +0000 Subject: [PATCH 1/5] Initial plan From b2c19ff945094e4b847f83ebf92f2788e8770c16 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 17 Jan 2026 10:51:02 +0000 Subject: [PATCH 2/5] docs: Create missing specification documents (page, view, form, report, menu) Co-authored-by: huangyiirene <7665279+huangyiirene@users.noreply.github.com> --- docs/spec/form.md | 970 +++++++++++++++++++++++++++++++++++++++++ docs/spec/menu.md | 939 ++++++++++++++++++++++++++++++++++++++++ docs/spec/page.md | 629 +++++++++++++++++++++++++++ docs/spec/report.md | 1005 +++++++++++++++++++++++++++++++++++++++++++ docs/spec/view.md | 938 ++++++++++++++++++++++++++++++++++++++++ 5 files changed, 4481 insertions(+) create mode 100644 docs/spec/form.md create mode 100644 docs/spec/menu.md create mode 100644 docs/spec/page.md create mode 100644 docs/spec/report.md create mode 100644 docs/spec/view.md diff --git a/docs/spec/form.md b/docs/spec/form.md new file mode 100644 index 00000000..3f9c394e --- /dev/null +++ b/docs/spec/form.md @@ -0,0 +1,970 @@ +# Form Definition + +Forms define data entry layouts and configurations for creating and editing records. They control which fields are visible, their validation rules, and the user experience for data input. + +**File Naming Convention:** `.form.yml` + +The filename (without the `.form.yml` extension) automatically becomes the form's identifier. This eliminates the need for a redundant `name` property inside the file. + +**Examples:** +- `project_create.form.yml` → Form identifier: `project_create` +- `customer_edit.form.yml` → Form identifier: `customer_edit` +- `quick_task.form.yml` → Form identifier: `quick_task` + +Files should use **snake_case** for multi-word names. + +## 1. Root Properties + +| Property | Type | Required | Description | +| :--- | :--- | :--- | :--- | +| `label` | `string` | **Required** | Human-readable form title (e.g., "Create Project"). | +| `object` | `string` | **Required** | Object this form creates/edits. | +| `type` | `string` | Optional | Form type: `create`, `edit`, `clone`, `wizard`. Default: `create`. | +| `description` | `string` | Optional | Internal description of the form purpose. | +| `sections` | `array` | **Required** | Form sections containing fields. | +| `layout` | `object` | Optional | Layout configuration (columns, spacing, etc.). | +| `validation` | `object` | Optional | Additional validation rules. | +| `actions` | `object` | Optional | Form action buttons configuration. | +| `defaults` | `object` | Optional | Default field values. | +| `read_only_fields` | `array` | Optional | Fields that cannot be edited. | +| `hidden_fields` | `array` | Optional | Fields hidden from user but included in submission. | +| `permissions` | `object` | Optional | Access control for the form. | +| `ai_context` | `object` | Optional | AI-friendly context for understanding form purpose. | + +## 2. Form Types + +### 2.1 Create Form + +Form for creating new records. + +```yaml +# File: project_create.form.yml + +label: Create Project +object: project +type: create + +sections: + # Basic Information + - label: Project Information + fields: + - name: + required: true + placeholder: Enter project name + + - description: + type: textarea + rows: 4 + + - status: + default: planning + + - owner: + default: $current_user.id + + # Timeline + - label: Timeline + fields: + - start_date: + default: $today + + - end_date: + required: true + validation: + min: $field.start_date + + # Budget + - label: Budget + fields: + - budget_amount: + format: currency + required: true + + - budget_category: + type: select + options: + - capital + - operational + - research + +# Default values +defaults: + status: planning + priority: medium + owner_id: $current_user.id + +# Form actions +actions: + submit: + label: Create Project + on_success: + redirect: /projects/:id + message: Project created successfully + + cancel: + label: Cancel + redirect: /projects + +ai_context: + intent: "Form for creating new projects with timeline and budget" + domain: project_management +``` + +### 2.2 Edit Form + +Form for modifying existing records. + +```yaml +# File: customer_edit.form.yml + +label: Edit Customer +object: customer +type: edit + +sections: + - label: Basic Information + fields: + - name + - email + - phone + - company + + - label: Address + columns: 2 + fields: + - street + - city + - state + - zip_code + + - label: Classification + fields: + - industry + - tier + - account_manager + +# Read-only fields +read_only_fields: + - created_at + - created_by + - id + +# Actions +actions: + submit: + label: Save Changes + on_success: + message: Customer updated successfully + stay_on_page: true + + delete: + label: Delete Customer + confirm: Are you sure you want to delete this customer? + permission: delete_customer + +ai_context: + intent: "Edit existing customer information" + domain: crm +``` + +### 2.3 Clone Form + +Form for duplicating records with modifications. + +```yaml +# File: project_clone.form.yml + +label: Clone Project +object: project +type: clone + +# Fields to clone (others excluded) +clone_fields: + - name + - description + - status + - budget_amount + - owner + +sections: + - label: New Project Details + fields: + - name: + label: New Project Name + required: true + default: $source.name + " (Copy)" + + - description: + default: $source.description + + - start_date: + required: true + default: $today + + - end_date: + required: true + +# Exclude from clone +exclude_fields: + - id + - created_at + - created_by + - tasks # Don't clone related tasks + +ai_context: + intent: "Clone project with modified timeline and name" + domain: project_management +``` + +### 2.4 Wizard Form + +Multi-step form for complex data entry. + +```yaml +# File: employee_onboarding.form.yml + +label: Employee Onboarding +object: employee +type: wizard + +steps: + # Step 1: Personal Information + - label: Personal Information + description: Basic employee details + sections: + - fields: + - first_name + - last_name + - email + - phone + - date_of_birth + + # Step 2: Employment Details + - label: Employment Details + description: Job and compensation information + sections: + - label: Position + fields: + - job_title + - department + - manager + - start_date + + - label: Compensation + fields: + - salary + - employment_type + - pay_frequency + + # Step 3: Benefits + - label: Benefits Selection + description: Choose benefit options + sections: + - fields: + - health_insurance + - dental_insurance + - retirement_plan + - pto_days + + # Step 4: Documents + - label: Documents + description: Upload required documents + sections: + - fields: + - resume: + type: file + accept: .pdf,.doc,.docx + - id_document: + type: file + required: true + +# Wizard navigation +navigation: + show_progress: true + allow_back: true + validate_step: true # Validate before proceeding + +actions: + submit: + label: Complete Onboarding + on_success: + redirect: /employees/:id + message: Employee onboarding completed + +ai_context: + intent: "Multi-step wizard for comprehensive employee onboarding" + domain: hr +``` + +## 3. Form Sections + +Sections organize fields into logical groups. + +```yaml +sections: + # Basic section + - label: Contact Information + fields: + - name + - email + - phone + + # Section with columns + - label: Address + columns: 2 + fields: + - street + - city + - state + - zip_code + + # Collapsible section + - label: Additional Details + collapsible: true + collapsed: true + fields: + - notes + - tags + + # Conditional section + - label: Shipping Details + visible_when: + field: needs_shipping + operator: "=" + value: true + fields: + - shipping_address + - shipping_method +``` + +## 4. Field Configuration + +### 4.1 Field Properties + +```yaml +fields: + - name: + label: Project Name + required: true + placeholder: Enter project name + help_text: Choose a descriptive name + max_length: 100 + + - description: + type: textarea + rows: 4 + max_length: 1000 + + - status: + type: select + options: + - value: planning + label: Planning + - value: active + label: Active + - value: completed + label: Completed + default: planning + + - start_date: + type: date + required: true + min: $today + default: $today + + - budget: + type: number + format: currency + min: 0 + step: 100 +``` + +### 4.2 Field Types + +```yaml +fields: + # Text inputs + - name: + type: text + + - email: + type: email + + - phone: + type: phone + + - url: + type: url + + # Numeric inputs + - quantity: + type: number + min: 0 + max: 1000 + + - price: + type: currency + + - percentage: + type: percent + + # Date/Time + - due_date: + type: date + + - meeting_time: + type: datetime + + - duration: + type: time + + # Selection + - category: + type: select + options: [option1, option2] + + - tags: + type: multiselect + options: [tag1, tag2, tag3] + + - priority: + type: radio + options: [low, medium, high] + + - features: + type: checkbox_group + options: [feature1, feature2] + + # Boolean + - is_active: + type: checkbox + default: true + + - accept_terms: + type: toggle + + # Text areas + - description: + type: textarea + rows: 5 + + - notes: + type: richtext + + # Relationships + - owner: + type: lookup + reference_to: users + searchable: true + + - related_projects: + type: master_detail + reference_to: projects + + # Files + - attachment: + type: file + accept: .pdf,.doc + max_size: 5242880 # 5MB + + - photos: + type: file + multiple: true + accept: image/* +``` + +### 4.3 Conditional Fields + +Show/hide fields based on other field values. + +```yaml +fields: + - event_type: + type: select + options: + - in_person + - virtual + - hybrid + + - venue_address: + visible_when: + field: event_type + operator: in + value: [in_person, hybrid] + + - video_link: + visible_when: + field: event_type + operator: in + value: [virtual, hybrid] + required_when: + field: event_type + operator: "=" + value: virtual +``` + +## 5. Validation + +### 5.1 Field-Level Validation + +```yaml +fields: + - email: + type: email + required: true + validation: + format: email + message: Please enter a valid email address + + - age: + type: number + validation: + min: 18 + max: 120 + message: Age must be between 18 and 120 + + - username: + type: text + validation: + pattern: ^[a-z0-9_]{3,20}$ + message: Username must be 3-20 characters, lowercase letters, numbers, and underscores only +``` + +### 5.2 Cross-Field Validation + +```yaml +validation: + # End date must be after start date + - rule: date_range + fields: [start_date, end_date] + condition: + field: end_date + operator: ">" + compare_to: start_date + message: End date must be after start date + + # Conditional requirement + - rule: conditional_required + when: + field: needs_approval + operator: "=" + value: true + then: + required: [approver, approval_reason] +``` + +### 5.3 Custom Validation + +```yaml +validation: + # Custom validation function + - rule: custom + name: check_budget_limit + message: Budget exceeds department limit + function: | + async function validate(data, context) { + const dept = await context.repo.findOne('department', data.department_id); + return data.budget <= dept.budget_limit; + } +``` + +## 6. Layout Options + +### 6.1 Column Layout + +```yaml +layout: + columns: 2 + gap: 16 + +sections: + - label: Contact Details + fields: + - name # Spans 2 columns by default + - email: + columns: 1 # Takes 1 column + - phone: + columns: 1 # Takes 1 column +``` + +### 6.2 Responsive Layout + +```yaml +layout: + desktop: + columns: 2 + tablet: + columns: 1 + mobile: + columns: 1 +``` + +### 6.3 Custom Styling + +```yaml +sections: + - label: Important Notice + style: + background: warning + padding: 16 + border: true + fields: + - important_note +``` + +## 7. Form Actions + +### 7.1 Standard Actions + +```yaml +actions: + # Primary submit button + submit: + label: Save + icon: standard:save + variant: primary + on_success: + message: Record saved successfully + redirect: /objects/:object/:id + + # Secondary cancel button + cancel: + label: Cancel + variant: secondary + redirect: /objects/:object + + # Additional action + save_and_new: + label: Save & New + on_success: + message: Record saved + redirect: /objects/:object/create +``` + +### 7.2 Custom Actions + +```yaml +actions: + # Custom save with approval + submit_for_approval: + label: Submit for Approval + variant: primary + before_save: + - set_field: + status: pending_approval + - call_action: + action: send_approval_notification + on_success: + message: Submitted for approval + redirect: /objects/:object/:id +``` + +## 8. Complete Examples + +### Example 1: Contact Form + +```yaml +# File: contact_create.form.yml + +label: Create Contact +object: contact +type: create + +sections: + # Basic Information + - label: Basic Information + fields: + - first_name: + required: true + placeholder: First Name + + - last_name: + required: true + placeholder: Last Name + + - email: + type: email + required: true + validation: + format: email + + - phone: + type: phone + format: (###) ###-#### + + # Company Details + - label: Company + fields: + - account: + type: lookup + reference_to: accounts + required: true + searchable: true + + - title: + placeholder: Job Title + + - department: + type: select + options: + - Sales + - Marketing + - Engineering + - Support + + # Address + - label: Address + columns: 2 + collapsible: true + fields: + - street + - city + - state + - zip_code + +defaults: + status: active + owner_id: $current_user.id + +actions: + submit: + label: Create Contact + on_success: + message: Contact created successfully + redirect: /contacts/:id + + cancel: + label: Cancel + redirect: /contacts + +ai_context: + intent: "Create new business contact with company association" + domain: crm +``` + +### Example 2: Order Entry Form + +```yaml +# File: order_entry.form.yml + +label: New Order +object: order +type: create + +sections: + # Customer Selection + - label: Customer + fields: + - customer: + type: lookup + reference_to: customers + required: true + searchable: true + on_change: + - populate_field: + shipping_address: $selected.default_address + + # Order Items + - label: Order Items + type: line_items + relationship: order_items + fields: + - product: + type: lookup + reference_to: products + required: true + + - quantity: + type: number + min: 1 + default: 1 + + - unit_price: + type: currency + readonly: true + auto_populate: $product.price + + - total: + type: formula + formula: quantity * unit_price + readonly: true + + # Shipping + - label: Shipping + fields: + - shipping_address: + type: address + required: true + + - shipping_method: + type: select + options: + - Standard + - Express + - Overnight + default: Standard + + - requested_delivery: + type: date + min: $today + 2 + +# Validation +validation: + - rule: minimum_order + condition: + formula: order_items.sum(total) >= 100 + message: Minimum order amount is $100 + +# Totals (calculated) +calculated_fields: + subtotal: + formula: order_items.sum(total) + + tax: + formula: subtotal * 0.08 + + shipping_cost: + formula: | + shipping_method === 'Standard' ? 10 : + shipping_method === 'Express' ? 25 : 50 + + total: + formula: subtotal + tax + shipping_cost + +actions: + submit: + label: Place Order + on_success: + message: Order placed successfully + send_email: + to: $customer.email + template: order_confirmation + redirect: /orders/:id + +ai_context: + intent: "Create sales order with line items and shipping details" + domain: e-commerce +``` + +### Example 3: Task Quick Create + +```yaml +# File: task_quick.form.yml + +label: Quick Task +object: task +type: create +description: Simplified form for quick task creation + +# Single section, minimal fields +sections: + - fields: + - title: + required: true + placeholder: What needs to be done? + autofocus: true + + - due_date: + type: date + default: $today + 7 + + - priority: + type: select + options: [Low, Medium, High] + default: Medium + +# Auto-populate fields +defaults: + status: todo + assignee_id: $current_user.id + project_id: $context.project_id # From URL context + +# Quick save +actions: + submit: + label: Create Task + on_success: + message: Task created + close_modal: true + refresh_list: true + +ai_context: + intent: "Quick task creation form for minimal friction" + domain: task_management + use_cases: + - "Create task from email" + - "Add task during meeting" + - "Quick capture from mobile" +``` + +## 9. Best Practices + +### 9.1 User Experience + +- **Logical grouping**: Organize related fields into sections +- **Progressive disclosure**: Use collapsible sections for optional fields +- **Clear labels**: Use descriptive field labels and help text +- **Smart defaults**: Pre-fill fields when possible +- **Inline validation**: Validate as user types, not just on submit + +### 9.2 Performance + +- **Lazy load options**: Load lookup options on demand +- **Optimize dependencies**: Minimize field dependencies +- **Debounce validation**: Don't validate on every keystroke +- **Cache lookups**: Cache frequently used lookup data + +### 9.3 Accessibility + +- **Keyboard navigation**: Support tab order and keyboard shortcuts +- **Screen reader friendly**: Use proper labels and ARIA attributes +- **Focus management**: Set autofocus appropriately +- **Error messages**: Clear, actionable error messages + +### 9.4 Security + +- **Server validation**: Always validate on server, not just client +- **CSRF protection**: Include CSRF tokens in forms +- **Sanitize inputs**: Prevent XSS and injection attacks +- **Permission checks**: Verify user can create/edit before showing form + +## 10. Integration with Other Metadata + +Forms integrate with: + +- **Objects**: Use object field definitions +- **Validation**: Apply object validation rules +- **Permissions**: Respect field-level permissions +- **Actions**: Trigger actions on form events +- **Hooks**: Fire hooks on create/update +- **Formulas**: Calculate formula fields in real-time + +## 11. AI Context Guidelines + +```yaml +ai_context: + # Business purpose + intent: "Simplified lead capture form for trade shows" + + # Domain + domain: sales + + # Use cases + use_cases: + - "Capture leads at events" + - "Quick data entry from mobile" + - "Minimal friction lead generation" + + # Form characteristics + characteristics: + - "Minimal fields for speed" + - "Mobile-optimized layout" + - "Offline capable" +``` + +## See Also + +- [Objects](./object.md) - Data model definitions +- [Validation](./validation.md) - Validation rules +- [Pages](./page.md) - UI page definitions +- [Permissions](./permission.md) - Access control diff --git a/docs/spec/menu.md b/docs/spec/menu.md new file mode 100644 index 00000000..b8556c72 --- /dev/null +++ b/docs/spec/menu.md @@ -0,0 +1,939 @@ +# Menu Definition + +Menus define the navigation structure and organization of your application. They control how users access pages, objects, and features through a hierarchical menu system. + +**File Naming Convention:** `.menu.yml` + +The filename (without the `.menu.yml` extension) automatically becomes the menu's identifier. This eliminates the need for a redundant `name` property inside the file. + +**Examples:** +- `main_menu.menu.yml` → Menu identifier: `main_menu` +- `admin_menu.menu.yml` → Menu identifier: `admin_menu` +- `user_profile.menu.yml` → Menu identifier: `user_profile` + +Files should use **snake_case** for multi-word names. + +## 1. Root Properties + +| Property | Type | Required | Description | +| :--- | :--- | :--- | :--- | +| `label` | `string` | **Required** | Human-readable menu title. | +| `type` | `string` | Optional | Menu type: `main`, `sidebar`, `dropdown`, `toolbar`, `context`. Default: `main`. | +| `description` | `string` | Optional | Internal description of menu purpose. | +| `icon` | `string` | Optional | Icon identifier for the menu. | +| `items` | `array` | **Required** | Menu items and structure. | +| `position` | `string` | Optional | Menu placement: `top`, `left`, `right`. | +| `collapsible` | `boolean` | Optional | Whether menu can be collapsed. | +| `default_collapsed` | `boolean` | Optional | Initial collapse state. | +| `permissions` | `object` | Optional | Access control for the menu. | +| `ai_context` | `object` | Optional | AI-friendly context. | + +## 2. Menu Types + +### 2.1 Main Navigation Menu + +Primary application navigation. + +```yaml +# File: main_menu.menu.yml + +label: Main Navigation +type: main +position: left + +items: + # Dashboard + - label: Dashboard + icon: standard:home + path: /dashboard + + # CRM Section + - label: CRM + icon: standard:account + items: + - label: Accounts + icon: standard:account + object: account + path: /accounts + + - label: Contacts + icon: standard:contact + object: contact + path: /contacts + + - label: Opportunities + icon: standard:opportunity + object: opportunity + path: /opportunities + + - separator: true + + - label: Reports + icon: standard:reports + items: + - label: Sales Pipeline + path: /reports/sales_pipeline + + - label: Win/Loss Analysis + path: /reports/win_loss + + # Projects Section + - label: Projects + icon: standard:project + items: + - label: All Projects + object: project + path: /projects + + - label: My Projects + path: /projects/my + + - label: Project Templates + path: /projects/templates + + # Settings + - label: Settings + icon: standard:settings + path: /settings + permissions: + view: [admin] + +ai_context: + intent: "Main application navigation menu" + domain: application +``` + +### 2.2 Sidebar Menu + +Contextual sidebar navigation. + +```yaml +# File: admin_sidebar.menu.yml + +label: Administration +type: sidebar +position: left +collapsible: true + +items: + # User Management + - label: Users & Access + icon: standard:user + items: + - label: Users + object: user + path: /admin/users + + - label: Roles + object: role + path: /admin/roles + + - label: Permission Sets + object: permission_set + path: /admin/permissions + + # Data Management + - label: Data Management + icon: standard:data + items: + - label: Objects + path: /admin/objects + + - label: Fields + path: /admin/fields + + - label: Relationships + path: /admin/relationships + + - separator: true + + - label: Import Data + path: /admin/import + + - label: Export Data + path: /admin/export + + # System Configuration + - label: System + icon: standard:settings + items: + - label: Company Settings + path: /admin/company + + - label: Email Configuration + path: /admin/email + + - label: Integrations + path: /admin/integrations + + - label: API Keys + path: /admin/api_keys + +permissions: + view: [admin, system_admin] + +ai_context: + intent: "Administrative configuration and management menu" + domain: administration +``` + +### 2.3 Dropdown Menu + +User actions or context menu. + +```yaml +# File: user_profile.menu.yml + +label: User Profile +type: dropdown +trigger: avatar # What triggers the dropdown + +items: + # User info (non-clickable header) + - type: header + label: $current_user.name + subtitle: $current_user.email + + - separator: true + + # Profile actions + - label: My Profile + icon: standard:user + path: /profile + + - label: Account Settings + icon: standard:settings + path: /settings/account + + - label: Preferences + icon: standard:preferences + path: /settings/preferences + + - separator: true + + # Quick actions + - label: Switch Organization + icon: standard:organization + action: switch_org + + - label: Help & Support + icon: standard:help + path: /help + + - separator: true + + # Logout + - label: Logout + icon: standard:logout + action: logout + style: danger + +ai_context: + intent: "User profile dropdown with account actions" + domain: user_interface +``` + +### 2.4 Context Menu + +Right-click or action menu. + +```yaml +# File: record_actions.menu.yml + +label: Record Actions +type: context +description: Context menu for record operations + +items: + # View/Edit + - label: View Details + icon: standard:view + action: view_record + + - label: Edit + icon: standard:edit + action: edit_record + permission: update + + - separator: true + + # Record actions + - label: Clone + icon: standard:copy + action: clone_record + permission: create + + - label: Share + icon: standard:share + action: share_record + + - separator: true + + # Advanced actions + - label: Export + icon: standard:export + items: + - label: Export as PDF + action: export_pdf + + - label: Export as Excel + action: export_excel + + - separator: true + + # Delete + - label: Delete + icon: standard:delete + action: delete_record + permission: delete + confirm: Are you sure you want to delete this record? + style: danger + +ai_context: + intent: "Context menu for record-level operations" + domain: user_interface +``` + +### 2.5 Toolbar Menu + +Quick action toolbar. + +```yaml +# File: list_toolbar.menu.yml + +label: List Toolbar +type: toolbar +position: top + +items: + # Create button + - label: New + icon: standard:add + action: create_record + variant: primary + permission: create + + # Bulk actions + - label: Actions + icon: standard:actions + type: dropdown + items: + - label: Bulk Edit + action: bulk_edit + + - label: Bulk Delete + action: bulk_delete + confirm: Delete selected records? + + - label: Export Selected + action: export_selected + + # View options + - label: View + icon: standard:view + type: dropdown + items: + - label: List View + action: set_view_type + value: list + checked: true + + - label: Kanban View + action: set_view_type + value: kanban + + - label: Calendar View + action: set_view_type + value: calendar + + # Filters + - label: Filter + icon: standard:filter + action: show_filters + badge: 2 # Show active filter count + + # Refresh + - icon: standard:refresh + action: refresh + tooltip: Refresh data + +ai_context: + intent: "Toolbar with quick actions for list views" + domain: user_interface +``` + +## 3. Menu Items + +### 3.1 Basic Link Item + +```yaml +items: + - label: Dashboard + icon: standard:home + path: /dashboard + + - label: Customers + icon: standard:account + object: customer + path: /customers +``` + +### 3.2 Item with Submenu + +```yaml +items: + - label: Sales + icon: standard:opportunity + items: + - label: Opportunities + path: /opportunities + + - label: Quotes + path: /quotes + + - label: Orders + path: /orders +``` + +### 3.3 Action Item + +```yaml +items: + - label: Create Record + icon: standard:add + action: create_record + params: + object: customer + + - label: Run Report + icon: standard:report + action: run_report + params: + report_id: sales_summary +``` + +### 3.4 Separator + +```yaml +items: + - label: Item 1 + path: /item1 + + - separator: true + + - label: Item 2 + path: /item2 +``` + +### 3.5 Header + +```yaml +items: + - type: header + label: Recent Items + + - label: Recent Item 1 + path: /items/1 + + - label: Recent Item 2 + path: /items/2 +``` + +### 3.6 Dynamic Items + +```yaml +items: + # Static item + - label: All Projects + path: /projects + + # Dynamic items from database + - type: dynamic + label: Recent Projects + source: + object: project + filters: + - field: owner_id + operator: "=" + value: $current_user.id + sort: + - field: modified_at + direction: desc + limit: 5 + template: + label: $record.name + path: /projects/$record.id + icon: standard:project +``` + +## 4. Item Properties + +### 4.1 Core Properties + +```yaml +- label: Menu Item # Display text + icon: standard:home # Icon + path: /home # Navigation path + badge: 5 # Badge count + tooltip: Tooltip text # Hover text +``` + +### 4.2 Appearance + +```yaml +- label: Delete + icon: standard:delete + style: danger # primary, secondary, success, danger, warning + variant: outline # solid, outline, ghost + size: medium # small, medium, large +``` + +### 4.3 State + +```yaml +- label: Option 1 + checked: true # Checkbox/radio state + disabled: false # Disabled state + active: true # Active/selected state + loading: false # Loading state +``` + +### 4.4 Behavior + +```yaml +- label: Item + path: /path + target: _blank # Link target + external: true # External link + download: true # Trigger download +``` + +## 5. Permissions + +Control menu visibility based on user permissions. + +### 5.1 Role-Based + +```yaml +items: + - label: Admin Panel + path: /admin + permissions: + view: [admin, system_admin] + + - label: Reports + path: /reports + permissions: + view: [admin, manager, analyst] +``` + +### 5.2 Object-Based + +```yaml +items: + - label: Customers + object: customer + path: /customers + permissions: + object: customer + operation: read +``` + +### 5.3 Dynamic Permissions + +```yaml +items: + - label: Sensitive Data + path: /sensitive + permissions: + condition: + field: $current_user.clearance_level + operator: ">=" + value: 3 +``` + +## 6. Styling and Theming + +### 6.1 Menu Styling + +```yaml +# Menu-level styling +style: + background: white + color: text-primary + border: true + shadow: true + rounded: true + width: 250 # pixels + +# Item styling +items: + - label: Item + style: + background: blue-500 + color: white + padding: 8 + margin: 4 +``` + +### 6.2 Active State + +```yaml +active_style: + background: blue-100 + color: blue-700 + border_left: 3px solid blue-700 + font_weight: bold +``` + +### 6.3 Hover State + +```yaml +hover_style: + background: gray-100 + color: gray-900 +``` + +## 7. Complete Examples + +### Example 1: Application Main Menu + +```yaml +# File: app_main_menu.menu.yml + +label: Application Menu +type: main +position: left +collapsible: true +default_collapsed: false + +style: + width: 260 + background: white + shadow: true + +items: + # Dashboard + - label: Dashboard + icon: standard:home + path: / + exact: true # Only active on exact match + + # Sales Section + - type: header + label: SALES + + - label: Leads + icon: standard:lead + object: lead + path: /leads + badge: $count.leads_unqualified + + - label: Opportunities + icon: standard:opportunity + object: opportunity + path: /opportunities + + - label: Accounts + icon: standard:account + object: account + path: /accounts + + - label: Contacts + icon: standard:contact + object: contact + path: /contacts + + # Marketing Section + - type: header + label: MARKETING + + - label: Campaigns + icon: standard:campaign + object: campaign + path: /campaigns + + - label: Email Templates + icon: standard:email + path: /email_templates + + # Service Section + - type: header + label: SERVICE + + - label: Cases + icon: standard:case + object: case + path: /cases + badge: $count.cases_open + badge_style: danger + + - label: Knowledge Base + icon: standard:knowledge + path: /knowledge + + # Separator + - separator: true + + # Analytics + - label: Reports & Dashboards + icon: standard:reports + items: + - label: Sales Reports + path: /reports/sales + + - label: Service Reports + path: /reports/service + + - separator: true + + - label: Dashboards + path: /dashboards + + # Separator + - separator: true + + # Admin (conditional) + - label: Setup + icon: standard:settings + path: /setup + permissions: + view: [admin] + +ai_context: + intent: "Main navigation for CRM application" + domain: crm +``` + +### Example 2: Record Detail Actions Menu + +```yaml +# File: opportunity_actions.menu.yml + +label: Opportunity Actions +type: dropdown +description: Actions available on opportunity records + +items: + # Quick actions + - label: Edit + icon: standard:edit + action: edit_record + keyboard_shortcut: e + + - label: Clone + icon: standard:copy + action: clone_record + + - label: Share + icon: standard:share + action: share_record + + - separator: true + + # Stage progression + - label: Advance Stage + icon: standard:forward + action: advance_stage + disabled_when: + field: stage + operator: "=" + value: closed_won + + - label: Mark as Won + icon: standard:success + action: mark_won + style: success + + - label: Mark as Lost + icon: standard:close + action: mark_lost + style: danger + + - separator: true + + # Related actions + - label: Create Quote + icon: standard:quote + action: create_related + params: + object: quote + + - label: Schedule Meeting + icon: standard:event + action: create_related + params: + object: event + + - separator: true + + # Export + - label: Export + icon: standard:export + items: + - label: PDF Summary + action: export_pdf + + - label: Excel Details + action: export_excel + + - separator: true + + # Delete + - label: Delete + icon: standard:delete + action: delete_record + style: danger + confirm: Delete this opportunity? + permission: delete + +ai_context: + intent: "Contextual actions for opportunity records" + domain: sales +``` + +### Example 3: Quick Create Menu + +```yaml +# File: quick_create.menu.yml + +label: Create New +type: dropdown +description: Quick create menu for common objects + +trigger: + type: button + icon: standard:add + label: New + variant: primary + +items: + # Frequently used + - type: header + label: QUICK CREATE + + - label: Lead + icon: standard:lead + action: create_record + params: + object: lead + keyboard_shortcut: "cmd+shift+l" + + - label: Contact + icon: standard:contact + action: create_record + params: + object: contact + keyboard_shortcut: "cmd+shift+c" + + - label: Opportunity + icon: standard:opportunity + action: create_record + params: + object: opportunity + keyboard_shortcut: "cmd+shift+o" + + - label: Task + icon: standard:task + action: create_record + params: + object: task + defaults: + assignee_id: $current_user.id + due_date: $tomorrow + keyboard_shortcut: "cmd+shift+t" + + - separator: true + + # More options + - label: More... + icon: standard:more + items: + - label: Account + icon: standard:account + action: create_record + params: + object: account + + - label: Case + icon: standard:case + action: create_record + params: + object: case + + - label: Campaign + icon: standard:campaign + action: create_record + params: + object: campaign + +ai_context: + intent: "Quick access to create common records" + domain: productivity +``` + +## 8. Best Practices + +### 8.1 Organization + +- **Logical grouping**: Group related items together +- **Limit depth**: Keep menu hierarchy shallow (max 3 levels) +- **Use separators**: Visually separate different groups +- **Meaningful labels**: Use clear, descriptive labels + +### 8.2 Performance + +- **Lazy load**: Load submenu items on demand +- **Cache permissions**: Cache permission checks +- **Optimize queries**: Efficient database queries for dynamic items +- **Debounce search**: Debounce search in large menus + +### 8.3 Usability + +- **Keyboard shortcuts**: Support keyboard navigation +- **Search functionality**: Add search for large menus +- **Highlight active**: Clearly show current location +- **Responsive design**: Adapt to different screen sizes + +### 8.4 Accessibility + +- **ARIA labels**: Use proper ARIA attributes +- **Keyboard navigation**: Full keyboard support +- **Focus management**: Proper focus handling +- **Screen reader**: Ensure screen reader compatibility + +## 9. Integration with Other Metadata + +Menus integrate with: + +- **Pages**: Navigate to page definitions +- **Objects**: Link to object list/detail pages +- **Actions**: Trigger custom actions +- **Permissions**: Respect access control +- **Apps**: Organize by application context + +## 10. Dynamic Menu Generation + +```yaml +items: + # Generate menu from app definitions + - type: dynamic + source: apps + template: + label: $app.label + icon: $app.icon + items: + type: dynamic + source: $app.objects + template: + label: $object.label_plural + icon: $object.icon + path: /objects/$object.name +``` + +## See Also + +- [Pages](./page.md) - UI page definitions +- [Apps](./app.md) - Application definitions +- [Permissions](./permission.md) - Access control +- [Actions](./action.md) - Custom actions diff --git a/docs/spec/page.md b/docs/spec/page.md new file mode 100644 index 00000000..7eb25c2e --- /dev/null +++ b/docs/spec/page.md @@ -0,0 +1,629 @@ +# Page Definition + +Pages define the user interface views and layouts for your application. They control how data is displayed and how users interact with your objects. + +**File Naming Convention:** `.page.yml` + +The filename (without the `.page.yml` extension) automatically becomes the page's identifier. This eliminates the need for a redundant `name` property inside the file. + +**Examples:** +- `project_list.page.yml` → Page identifier: `project_list` +- `dashboard.page.yml` → Page identifier: `dashboard` +- `customer_detail.page.yml` → Page identifier: `customer_detail` + +Files should use **snake_case** for multi-word names. + +## 1. Root Properties + +| Property | Type | Required | Description | +| :--- | :--- | :--- | :--- | +| `label` | `string` | Recommended | Human-readable title (e.g., "Project Dashboard"). | +| `type` | `string` | **Required** | Page type: `list`, `detail`, `dashboard`, `custom`. | +| `object` | `string` | Conditional | Object name this page displays. Required for `list` and `detail` types. | +| `icon` | `string` | Optional | Icon identifier (e.g., `standard:home`). | +| `description` | `string` | Optional | Internal description of the page purpose. | +| `layout` | `object` | Optional | Layout configuration for the page. | +| `sections` | `array` | Optional | Page sections and components. | +| `filters` | `array` | Optional | Default filters applied to data. | +| `permissions` | `object` | Optional | Access control for the page. | +| `ai_context` | `object` | Optional | AI-friendly context for understanding page purpose. | + +## 2. Page Types + +### 2.1 List Page + +Displays a collection of records in a table or grid view. + +```yaml +# File: project_list.page.yml + +label: Projects +type: list +object: project +icon: standard:project + +# Default view configuration +view: + # Columns to display + columns: + - name + - status + - owner + - created_at + + # Default sorting + sort: + - field: created_at + direction: desc + + # Quick filters + filters: + - field: status + operator: "=" + value: active + +# Actions available on this page +actions: + - create_project + - bulk_update_status + - export_to_excel + +# AI Context +ai_context: + intent: "Display all projects with filtering and sorting capabilities" + common_use_cases: + - "View all active projects" + - "Search projects by name" + - "Filter projects by owner" +``` + +### 2.2 Detail Page + +Displays a single record with full details and related records. + +```yaml +# File: project_detail.page.yml + +label: Project Details +type: detail +object: project + +# Layout sections +sections: + # Basic information section + - label: Project Information + columns: 2 + fields: + - name + - status + - owner + - start_date + - end_date + - budget + + # Related lists section + - label: Tasks + type: related_list + relationship: tasks + columns: + - title + - status + - assignee + - due_date + + # Activity timeline + - label: Activity + type: timeline + events: + - comments + - status_changes + - task_updates + +# Actions available on detail page +actions: + - edit + - delete + - clone_project + - archive + +ai_context: + intent: "Display comprehensive project details with related tasks and activity" +``` + +### 2.3 Dashboard Page + +Aggregated views with charts, metrics, and widgets. + +```yaml +# File: sales_dashboard.page.yml + +label: Sales Dashboard +type: dashboard +icon: standard:dashboard + +# Dashboard layout +layout: + columns: 12 + +# Widgets +widgets: + # Revenue chart + - type: chart + title: Monthly Revenue + position: { row: 0, col: 0, width: 8, height: 4 } + source: + object: order + aggregation: + field: amount + function: sum + group_by: created_month + chart_type: line + + # KPI metric + - type: metric + title: Total Deals Closed + position: { row: 0, col: 8, width: 4, height: 2 } + source: + object: deal + aggregation: + function: count + filters: + - field: status + operator: "=" + value: closed_won + + # Recent activity list + - type: list + title: Recent Opportunities + position: { row: 4, col: 0, width: 12, height: 4 } + source: + object: opportunity + limit: 10 + sort: + - field: created_at + direction: desc + +# Refresh interval (seconds) +refresh_interval: 300 + +ai_context: + intent: "Executive dashboard showing key sales metrics and trends" + domain: sales +``` + +### 2.4 Custom Page + +Fully custom pages with embedded components or external integrations. + +```yaml +# File: custom_report.page.yml + +label: Custom Analytics +type: custom +icon: standard:report + +# Custom component configuration +component: + # Reference to custom React/Vue component + path: ./components/CustomAnalytics.tsx + + # Props passed to component + props: + dataSource: sales_data + dateRange: last_90_days + +# Data sources for the custom component +data_sources: + sales_data: + object: order + fields: + - amount + - created_at + - status + - customer_id + filters: + - field: status + operator: "=" + value: completed + +permissions: + view: [admin, sales_manager] + +ai_context: + intent: "Custom analytics page with specialized visualizations" +``` + +## 3. Layout Configuration + +### 3.1 Grid Layout + +```yaml +layout: + type: grid + columns: 12 # 12-column grid system + gap: 16 # Gap between items in pixels + +sections: + - type: fields + position: { row: 0, col: 0, width: 6, height: 4 } + fields: [name, status, owner] + + - type: related_list + position: { row: 0, col: 6, width: 6, height: 4 } + relationship: tasks +``` + +### 3.2 Tab Layout + +```yaml +layout: + type: tabs + +tabs: + - label: Details + sections: + - fields: [name, description, status] + + - label: Related + sections: + - type: related_list + relationship: tasks + + - label: History + sections: + - type: timeline +``` + +## 4. Filters and Search + +```yaml +# Quick filters (displayed as buttons) +quick_filters: + - label: My Projects + filters: + - field: owner_id + operator: "=" + value: $current_user.id + + - label: Active + filters: + - field: status + operator: "=" + value: active + +# Advanced search configuration +search: + # Enable full-text search + enabled: true + + # Fields to search across + fields: + - name + - description + - owner.name + + # Search placeholder + placeholder: "Search projects..." +``` + +## 5. Permissions + +Control who can access the page. + +```yaml +permissions: + # Roles that can view this page + view: [admin, manager, user] + + # Dynamic visibility rules + visibility_rules: + - condition: + field: status + operator: "=" + value: archived + roles: [admin] +``` + +## 6. Responsive Behavior + +```yaml +responsive: + # Mobile configuration + mobile: + # Hide certain columns on mobile + hidden_columns: + - created_at + - modified_at + + # Mobile-specific layout + layout: stack + + # Tablet configuration + tablet: + columns: 2 +``` + +## 7. Complete Examples + +### Example 1: Customer List Page + +```yaml +# File: customer_list.page.yml + +label: Customers +type: list +object: customer +icon: standard:account + +view: + columns: + - name + - email + - phone + - industry + - status + - owner + + sort: + - field: name + direction: asc + +quick_filters: + - label: My Customers + filters: + - field: owner_id + operator: "=" + value: $current_user.id + + - label: Active + filters: + - field: status + operator: "=" + value: active + + - label: VIP + filters: + - field: tier + operator: "=" + value: vip + +search: + enabled: true + fields: + - name + - email + - company + placeholder: "Search customers..." + +actions: + - create_customer + - import_customers + - export_to_csv + +permissions: + view: [admin, sales_rep, support] + +ai_context: + intent: "Manage customer records with filtering and search" + domain: crm + common_queries: + - "Show all VIP customers" + - "Find customers in technology industry" + - "List my active customers" +``` + +### Example 2: Order Detail Page + +```yaml +# File: order_detail.page.yml + +label: Order Details +type: detail +object: order +icon: standard:orders + +sections: + # Order Information + - label: Order Information + type: fields + columns: 2 + fields: + - order_number + - status + - customer + - order_date + - total_amount + - payment_status + + # Line Items + - label: Order Items + type: related_list + relationship: order_items + columns: + - product + - quantity + - unit_price + - total_price + actions: + - add_item + - remove_item + + # Shipping Information + - label: Shipping + type: fields + columns: 1 + fields: + - shipping_address + - shipping_method + - tracking_number + - estimated_delivery + + # Activity Timeline + - label: Activity + type: timeline + events: + - status_changes + - comments + - email_notifications + +actions: + - edit + - delete + - clone_order + - cancel_order + - process_refund + - send_invoice + +permissions: + view: [admin, sales, customer_service] + edit: [admin, sales] + delete: [admin] + +ai_context: + intent: "Display complete order details with line items and shipping information" + domain: e-commerce +``` + +## 8. Best Practices + +### 8.1 Performance + +- **Limit initial data load**: Use pagination and lazy loading +- **Index searchable fields**: Ensure fields used in filters have database indexes +- **Optimize related lists**: Limit initial records displayed +- **Cache dashboard widgets**: Use appropriate refresh intervals + +### 8.2 User Experience + +- **Meaningful defaults**: Set sensible default filters and sorts +- **Progressive disclosure**: Show most important information first +- **Consistent layouts**: Use similar layouts for similar page types +- **Mobile-first design**: Consider mobile users in layout decisions + +### 8.3 Security + +- **Page-level permissions**: Control access to sensitive pages +- **Field-level security**: Respect field permissions in page layouts +- **Record-level rules**: Apply sharing rules consistently +- **Audit sensitive actions**: Log access to confidential pages + +### 8.4 Maintainability + +- **Clear naming**: Use descriptive page identifiers +- **Reusable components**: Create reusable section templates +- **Version control**: Track page changes in Git +- **Documentation**: Add `ai_context` for future maintenance + +## 9. Advanced Features + +### 9.1 Dynamic Pages + +Pages that adapt based on context or user. + +```yaml +# Conditional sections based on record state +sections: + - label: Approval Section + type: fields + fields: [approver, approval_date] + visibility: + condition: + field: status + operator: in + value: [pending_approval, approved] +``` + +### 9.2 Embedded Actions + +```yaml +sections: + - label: Quick Actions + type: action_group + actions: + - approve + - reject + - request_more_info + layout: horizontal +``` + +### 9.3 Custom Renderers + +```yaml +view: + columns: + - name + - amount + - status: + # Custom renderer for status field + renderer: badge + color_map: + active: green + pending: yellow + closed: gray +``` + +## 10. Integration with Other Metadata + +Pages work seamlessly with other metadata types: + +- **Objects**: Pages display data from object definitions +- **Views**: Pages can embed saved views +- **Forms**: Detail pages use forms for data entry +- **Actions**: Pages expose actions as buttons +- **Permissions**: Pages respect object and field permissions +- **Workflows**: Pages show workflow states and actions + +## 11. AI Context Guidelines + +Include `ai_context` to help AI understand: + +```yaml +ai_context: + # Business purpose + intent: "Dashboard for sales managers to track team performance" + + # Business domain + domain: sales + + # Common user goals + common_use_cases: + - "View team quota attainment" + - "Track pipeline health" + - "Monitor deal progression" + + # Related pages + related_pages: + - opportunity_list + - sales_forecast +``` + +## 12. Migration from Code + +### Before (React Component): +```typescript +function ProjectList() { + const [projects, setProjects] = useState([]); + const [filters, setFilters] = useState({}); + + // 200+ lines of component code... +} +``` + +### After (Metadata): +```yaml +# File: project_list.page.yml +label: Projects +type: list +object: project +view: + columns: [name, status, owner] +``` + +The ObjectQL runtime automatically generates the UI from metadata! + +## See Also + +- [Views](./view.md) - Saved data views and filters +- [Forms](./form.md) - Data entry layouts +- [Objects](./object.md) - Data model definitions +- [Permissions](./permission.md) - Access control diff --git a/docs/spec/report.md b/docs/spec/report.md new file mode 100644 index 00000000..adb7c698 --- /dev/null +++ b/docs/spec/report.md @@ -0,0 +1,1005 @@ +# Report Definition + +Reports define analytics, visualizations, and data exports for business intelligence and decision-making. They provide aggregated views, charts, and formatted output of your data. + +**File Naming Convention:** `.report.yml` + +The filename (without the `.report.yml` extension) automatically becomes the report's identifier. This eliminates the need for a redundant `name` property inside the file. + +**Examples:** +- `sales_summary.report.yml` → Report identifier: `sales_summary` +- `revenue_forecast.report.yml` → Report identifier: `revenue_forecast` +- `inventory_status.report.yml` → Report identifier: `inventory_status` + +Files should use **snake_case** for multi-word names. + +## 1. Root Properties + +| Property | Type | Required | Description | +| :--- | :--- | :--- | :--- | +| `label` | `string` | **Required** | Human-readable report title. | +| `description` | `string` | Optional | Internal description of report purpose. | +| `type` | `string` | **Required** | Report type: `tabular`, `summary`, `matrix`, `chart`, `dashboard`. | +| `object` | `string` | Conditional | Primary object for the report. Required for most types. | +| `data_source` | `object` | **Required** | Query configuration for report data. | +| `columns` | `array` | Conditional | Columns to display (for tabular reports). | +| `grouping` | `object` | Optional | Grouping configuration. | +| `aggregations` | `object` | Optional | Aggregate calculations. | +| `filters` | `array` | Optional | Default filters for the report. | +| `parameters` | `object` | Optional | User-configurable parameters. | +| `sorting` | `array` | Optional | Default sort order. | +| `visualization` | `object` | Optional | Chart/graph configuration. | +| `format` | `object` | Optional | Formatting and styling options. | +| `schedule` | `object` | Optional | Automated report generation schedule. | +| `export` | `object` | Optional | Export configuration (PDF, Excel, CSV). | +| `permissions` | `object` | Optional | Access control for the report. | +| `ai_context` | `object` | Optional | AI-friendly context. | + +## 2. Report Types + +### 2.1 Tabular Report + +Simple list of records with columns. + +```yaml +# File: customer_list.report.yml + +label: Customer List Report +type: tabular +object: customer +description: Complete list of all customers with contact details + +# Data source +data_source: + object: customer + fields: + - name + - email + - phone + - industry + - status + - created_at + +# Columns +columns: + - field: name + label: Customer Name + width: 200 + + - field: email + label: Email Address + width: 250 + + - field: phone + label: Phone + width: 150 + format: phone + + - field: industry + label: Industry + width: 150 + + - field: status + label: Status + width: 100 + + - field: created_at + label: Created Date + width: 150 + format: date + +# Default filters +filters: + - field: status + operator: "=" + value: active + +# Sorting +sorting: + - field: name + direction: asc + +# Export options +export: + formats: [pdf, excel, csv] + +ai_context: + intent: "Complete customer list for marketing and outreach" + domain: crm +``` + +### 2.2 Summary Report + +Aggregated data grouped by dimensions. + +```yaml +# File: sales_by_region.report.yml + +label: Sales by Region +type: summary +object: order +description: Total sales aggregated by region and sales rep + +# Data source +data_source: + object: order + fields: + - region + - sales_rep.name + - amount + - status + filters: + - field: status + operator: "=" + value: completed + +# Grouping +grouping: + # Primary grouping + - field: region + label: Region + sort: asc + + # Secondary grouping + - field: sales_rep.name + label: Sales Representative + sort: asc + +# Aggregations +aggregations: + # Count orders + order_count: + function: count + label: Number of Orders + + # Sum amount + total_sales: + field: amount + function: sum + label: Total Sales + format: currency + + # Average order value + avg_order_value: + field: amount + function: avg + label: Average Order Value + format: currency + + # Min/Max + smallest_order: + field: amount + function: min + format: currency + + largest_order: + field: amount + function: max + format: currency + +# Parameters +parameters: + date_range: + type: date_range + label: Date Range + default: this_quarter + filter: + field: order_date + operator: between + +# Visualization +visualization: + type: bar_chart + x_axis: region + y_axis: total_sales + series: sales_rep.name + +ai_context: + intent: "Analyze sales performance by geographic region and rep" + domain: sales +``` + +### 2.3 Matrix Report + +Two-dimensional grouped data. + +```yaml +# File: product_sales_matrix.report.yml + +label: Product Sales Matrix +type: matrix +object: order_item +description: Sales by product and quarter + +# Data source +data_source: + object: order_item + fields: + - product.name + - order.order_date + - quantity + - total_amount + +# Matrix configuration +matrix: + # Rows + rows: + - field: product.name + label: Product + sort: asc + + # Columns (time periods) + columns: + - field: order.order_date + label: Quarter + group_by: quarter + format: Q# YYYY + + # Values (aggregations) + values: + - field: quantity + function: sum + label: Units Sold + + - field: total_amount + function: sum + label: Revenue + format: currency + +# Row subtotals +row_totals: true + +# Column subtotals +column_totals: true + +# Grand total +grand_total: true + +ai_context: + intent: "Cross-tabulation of product sales by time period" + domain: sales +``` + +### 2.4 Chart Report + +Visual data representation. + +```yaml +# File: revenue_trend.report.yml + +label: Revenue Trend +type: chart +object: order +description: Monthly revenue trend with year-over-year comparison + +# Data source +data_source: + object: order + fields: + - order_date + - amount + - status + filters: + - field: status + operator: "=" + value: completed + - and + - field: order_date + operator: ">=" + value: $start_of_last_year + +# Chart configuration +visualization: + chart_type: line # line, bar, pie, donut, area, scatter + + # X-axis (time) + x_axis: + field: order_date + group_by: month + label: Month + format: MMM YYYY + + # Y-axis (metric) + y_axis: + field: amount + function: sum + label: Revenue + format: currency + + # Series (for comparison) + series: + field: order_date + group_by: year + label: Year + + # Chart options + options: + show_legend: true + show_grid: true + show_data_labels: false + smooth: true + fill: true + colors: [#3498db, #2ecc71, #f39c12] + +# Parameters +parameters: + time_period: + type: select + label: Time Period + options: + - value: last_6_months + label: Last 6 Months + - value: last_12_months + label: Last 12 Months + - value: last_2_years + label: Last 2 Years + default: last_12_months + +ai_context: + intent: "Visualize revenue trends and identify patterns" + domain: sales +``` + +### 2.5 Dashboard Report + +Multiple visualizations and metrics. + +```yaml +# File: executive_dashboard.report.yml + +label: Executive Dashboard +type: dashboard +description: High-level business metrics and KPIs + +# Dashboard layout +layout: + columns: 12 + gap: 16 + +# Widgets +widgets: + # KPI: Total Revenue + - type: metric + title: Total Revenue + position: { row: 0, col: 0, width: 3, height: 2 } + data_source: + object: order + aggregation: + field: amount + function: sum + filters: + - field: status + operator: "=" + value: completed + - and + - field: order_date + operator: ">=" + value: $start_of_quarter + format: currency + comparison: + previous_period: true + show_trend: true + + # KPI: New Customers + - type: metric + title: New Customers + position: { row: 0, col: 3, width: 3, height: 2 } + data_source: + object: customer + aggregation: + function: count + filters: + - field: created_at + operator: ">=" + value: $start_of_month + comparison: + previous_period: true + + # Chart: Revenue by Region + - type: chart + title: Revenue by Region + position: { row: 2, col: 0, width: 6, height: 4 } + data_source: + object: order + fields: [region, amount] + filters: + - field: status + operator: "=" + value: completed + visualization: + chart_type: pie + dimension: region + metric: + field: amount + function: sum + + # Chart: Sales Trend + - type: chart + title: Sales Trend + position: { row: 2, col: 6, width: 6, height: 4 } + data_source: + object: order + fields: [order_date, amount] + visualization: + chart_type: line + x_axis: + field: order_date + group_by: month + y_axis: + field: amount + function: sum + + # Table: Top Products + - type: table + title: Top 10 Products + position: { row: 6, col: 0, width: 6, height: 4 } + data_source: + object: order_item + fields: + - product.name + - quantity + - total_amount + limit: 10 + sort: + - field: total_amount + direction: desc + + # Table: Pipeline + - type: table + title: Sales Pipeline + position: { row: 6, col: 6, width: 6, height: 4 } + data_source: + object: opportunity + fields: + - name + - stage + - amount + - close_date + filters: + - field: is_closed + operator: "=" + value: false + +# Refresh interval (seconds) +refresh_interval: 300 + +# Parameters +parameters: + region_filter: + type: multiselect + label: Regions + options_from: regions + default: all + +ai_context: + intent: "Executive dashboard showing key business metrics" + domain: business_intelligence +``` + +## 3. Data Source Configuration + +### 3.1 Single Object + +```yaml +data_source: + object: customer + fields: + - name + - email + - status + filters: + - field: status + operator: "=" + value: active +``` + +### 3.2 Joined Objects + +```yaml +data_source: + object: order + fields: + - order_number + - amount + - customer.name + - customer.industry + - sales_rep.name + joins: + - object: customer + type: left + on: + local: customer_id + foreign: id + + - object: user + alias: sales_rep + type: left + on: + local: sales_rep_id + foreign: id +``` + +### 3.3 Custom Query + +```yaml +data_source: + type: custom_query + query: | + SELECT + c.name, + COUNT(o.id) as order_count, + SUM(o.amount) as total_spent + FROM customers c + LEFT JOIN orders o ON c.id = o.customer_id + WHERE c.status = 'active' + GROUP BY c.id, c.name +``` + +## 4. Filters and Parameters + +### 4.1 Static Filters + +```yaml +filters: + - field: status + operator: "=" + value: completed + + - and + + - field: amount + operator: ">" + value: 1000 +``` + +### 4.2 User Parameters + +```yaml +parameters: + # Date range parameter + date_range: + type: date_range + label: Report Period + default: this_month + filter: + field: order_date + operator: between + + # Select parameter + region: + type: select + label: Region + options: + - All Regions + - North + - South + - East + - West + default: All Regions + filter: + field: region + operator: "=" + skip_if: All Regions + + # Multi-select parameter + product_categories: + type: multiselect + label: Product Categories + options_from: + object: product + field: category + distinct: true + filter: + field: product.category + operator: in + + # Number parameter + min_amount: + type: number + label: Minimum Amount + default: 0 + filter: + field: amount + operator: ">=" +``` + +## 5. Formatting + +### 5.1 Column Formatting + +```yaml +columns: + - field: amount + label: Revenue + format: currency + alignment: right + + - field: conversion_rate + label: Conversion % + format: percent + decimals: 2 + + - field: order_date + label: Date + format: date + pattern: MM/DD/YYYY + + - field: status + label: Status + format: badge + color_map: + active: green + pending: yellow + cancelled: red +``` + +### 5.2 Conditional Formatting + +```yaml +columns: + - field: revenue + label: Revenue + format: currency + conditional_format: + # Highlight high revenue + - condition: + operator: ">" + value: 100000 + style: + background: green + color: white + bold: true + + # Highlight low revenue + - condition: + operator: "<" + value: 10000 + style: + background: red + color: white +``` + +## 6. Export Configuration + +```yaml +export: + # Supported formats + formats: + - pdf + - excel + - csv + - json + + # PDF options + pdf: + page_size: letter # letter, legal, a4 + orientation: portrait # portrait, landscape + header: Company Name - {report_title} + footer: Page {page} of {total_pages} + include_logo: true + + # Excel options + excel: + sheet_name: Report Data + include_filters: true + freeze_header: true + auto_filter: true + + # CSV options + csv: + delimiter: "," + encoding: utf-8 + include_headers: true +``` + +## 7. Scheduling + +```yaml +schedule: + # Enable scheduled generation + enabled: true + + # Frequency + frequency: daily # daily, weekly, monthly, quarterly + + # Time + time: "08:00" + timezone: America/New_York + + # Days (for weekly) + days: [monday, friday] + + # Day of month (for monthly) + day_of_month: 1 # 1-31, or 'last' + + # Recipients + recipients: + - email: manager@company.com + format: pdf + + - email: analyst@company.com + format: excel + + # Subject + email_subject: "{report_title} - {date}" + + # Message + email_body: | + Please find attached the {report_title} for {date}. +``` + +## 8. Complete Examples + +### Example 1: Sales Performance Report + +```yaml +# File: sales_performance.report.yml + +label: Sales Performance Report +type: summary +object: order +description: Comprehensive sales analysis by rep and product + +data_source: + object: order + fields: + - sales_rep.name + - product.category + - amount + - quantity + - order_date + filters: + - field: status + operator: "=" + value: completed + +grouping: + - field: sales_rep.name + label: Sales Representative + + - field: product.category + label: Product Category + +aggregations: + order_count: + function: count + label: Orders + + units_sold: + field: quantity + function: sum + label: Units + + total_revenue: + field: amount + function: sum + label: Revenue + format: currency + + avg_order_value: + field: amount + function: avg + label: Avg Order + format: currency + +parameters: + quarter: + type: select + label: Quarter + options: + - Q1 2026 + - Q2 2026 + - Q3 2026 + - Q4 2026 + default: Q1 2026 + +sorting: + - field: total_revenue + direction: desc + +export: + formats: [pdf, excel] + +schedule: + enabled: true + frequency: monthly + day_of_month: 1 + recipients: + - email: sales@company.com + +ai_context: + intent: "Monthly sales performance analysis by rep and product" + domain: sales +``` + +### Example 2: Inventory Status Report + +```yaml +# File: inventory_status.report.yml + +label: Inventory Status Report +type: tabular +object: product +description: Current inventory levels with reorder alerts + +data_source: + object: product + fields: + - sku + - name + - category + - quantity_on_hand + - quantity_committed + - quantity_available + - reorder_point + - reorder_quantity + - unit_cost + - total_value + +columns: + - field: sku + label: SKU + width: 100 + + - field: name + label: Product + width: 250 + + - field: category + label: Category + width: 150 + + - field: quantity_available + label: Available + width: 100 + alignment: right + conditional_format: + - condition: + field: quantity_available + operator: "<=" + compare_to: reorder_point + style: + background: red + color: white + bold: true + + - field: reorder_point + label: Reorder Point + width: 100 + alignment: right + + - field: total_value + label: Total Value + width: 150 + format: currency + alignment: right + +filters: + - field: is_active + operator: "=" + value: true + +sorting: + - field: quantity_available + direction: asc + +export: + formats: [excel, pdf] + +ai_context: + intent: "Monitor inventory levels and identify reorder needs" + domain: inventory_management +``` + +### Example 3: Customer Lifetime Value + +```yaml +# File: customer_ltv.report.yml + +label: Customer Lifetime Value Report +type: summary +object: customer +description: Customer value analysis with segmentation + +data_source: + object: customer + fields: + - name + - industry + - tier + - created_at + - orders.count + - orders.amount_sum + - orders.last_order_date + +grouping: + - field: tier + label: Customer Tier + + - field: industry + label: Industry + +aggregations: + customer_count: + function: count + label: Customers + + total_revenue: + field: orders.amount_sum + function: sum + label: Total Revenue + format: currency + + avg_customer_value: + field: orders.amount_sum + function: avg + label: Avg Customer Value + format: currency + + avg_order_count: + field: orders.count + function: avg + label: Avg Orders per Customer + decimals: 1 + +# Visualization +visualization: + type: bar_chart + x_axis: tier + y_axis: avg_customer_value + series: industry + +parameters: + cohort_year: + type: select + label: Customer Cohort + options: + - 2024 + - 2025 + - 2026 + filter: + field: created_at + operator: ">=" + value: ${value}-01-01 + +ai_context: + intent: "Analyze customer lifetime value by tier and industry" + domain: analytics +``` + +## 9. Best Practices + +### 9.1 Performance + +- **Limit data**: Use filters to reduce dataset size +- **Index fields**: Ensure filtered/grouped fields have indexes +- **Aggregate at database**: Use database aggregations, not application-level +- **Cache results**: Cache frequently run reports + +### 9.2 Usability + +- **Clear naming**: Use descriptive report and column names +- **Appropriate format**: Choose the right report type for the data +- **Default filters**: Set sensible default filters +- **Visual hierarchy**: Use grouping and formatting effectively + +### 9.3 Accuracy + +- **Validate logic**: Test calculations and aggregations +- **Document assumptions**: Explain any business logic +- **Handle nulls**: Account for missing data +- **Date boundaries**: Be clear about date range inclusivity + +### 9.4 Security + +- **Row-level security**: Respect object permissions +- **Field-level security**: Honor field permissions +- **Parameter validation**: Validate user input +- **Audit access**: Log report access for sensitive data + +## See Also + +- [Objects](./object.md) - Data model definitions +- [Query Language](./query-language.md) - Query syntax +- [Views](./view.md) - Saved data views +- [Permissions](./permission.md) - Access control diff --git a/docs/spec/view.md b/docs/spec/view.md new file mode 100644 index 00000000..f2420d50 --- /dev/null +++ b/docs/spec/view.md @@ -0,0 +1,938 @@ +# View Definition + +Views define saved queries, filters, and display configurations for data collections. They allow users to create and share custom perspectives on object data without modifying the underlying page definitions. + +**File Naming Convention:** `.view.yml` + +The filename (without the `.view.yml` extension) automatically becomes the view's identifier. This eliminates the need for a redundant `name` property inside the file. + +**Examples:** +- `active_projects.view.yml` → View identifier: `active_projects` +- `my_tasks.view.yml` → View identifier: `my_tasks` +- `high_priority_leads.view.yml` → View identifier: `high_priority_leads` + +Files should use **snake_case** for multi-word names. + +## 1. Root Properties + +| Property | Type | Required | Description | +| :--- | :--- | :--- | :--- | +| `label` | `string` | **Required** | Human-readable view name (e.g., "My Active Projects"). | +| `object` | `string` | **Required** | Object this view queries. | +| `description` | `string` | Optional | Internal description of the view purpose. | +| `type` | `string` | Optional | View type: `list`, `kanban`, `calendar`, `table`, `chart`. Default: `list`. | +| `filters` | `array` | Optional | Query filters applied to records. | +| `columns` | `array` | Optional | Fields to display (for list/table views). | +| `sort` | `array` | Optional | Default sorting configuration. | +| `group_by` | `string` | Optional | Field to group records by (for kanban/grouped views). | +| `aggregations` | `object` | Optional | Aggregate calculations (sum, count, avg, etc.). | +| `owner` | `string` | Optional | User who created this view. | +| `visibility` | `string` | Optional | `public`, `private`, `shared`. Default: `private`. | +| `shared_with` | `array` | Optional | Users/roles who can access this view. | +| `is_default` | `boolean` | Optional | Whether this is the default view for the object. | +| `ai_context` | `object` | Optional | AI-friendly context for understanding view purpose. | + +## 2. View Types + +### 2.1 List View + +Standard table/list display of records. + +```yaml +# File: active_projects.view.yml + +label: Active Projects +object: project +type: list + +# Filter criteria +filters: + - field: status + operator: "=" + value: active + - and + - field: end_date + operator: ">=" + value: $today + +# Columns to display +columns: + - name + - owner + - start_date + - end_date + - budget + - progress + +# Default sorting +sort: + - field: end_date + direction: asc + +# Visibility +visibility: public + +ai_context: + intent: "Show all currently active projects sorted by end date" + common_use_cases: + - "View projects due soon" + - "Track active project status" +``` + +### 2.2 Kanban View + +Card-based view grouped by status or category. + +```yaml +# File: task_board.view.yml + +label: Task Board +object: task +type: kanban + +# Kanban configuration +group_by: status + +# Swimlanes (status columns) +swimlanes: + - value: todo + label: To Do + color: gray + + - value: in_progress + label: In Progress + color: blue + + - value: review + label: In Review + color: yellow + + - value: done + label: Done + color: green + +# Card display fields +card_fields: + - title + - assignee + - due_date + - priority + +# Filters +filters: + - field: archived + operator: "=" + value: false + +# Sorting within columns +sort: + - field: priority + direction: desc + - field: due_date + direction: asc + +ai_context: + intent: "Kanban board for task management with drag-and-drop status updates" + domain: project_management +``` + +### 2.3 Calendar View + +Time-based visualization of records. + +```yaml +# File: project_timeline.view.yml + +label: Project Timeline +object: project +type: calendar + +# Calendar configuration +date_field: start_date +end_date_field: end_date + +# Display mode +display_mode: month # day, week, month, year + +# Event display +event_label: name +event_color_field: status + +# Color mapping +color_map: + planning: blue + active: green + on_hold: yellow + completed: gray + +# Filters +filters: + - field: start_date + operator: ">=" + value: $first_of_year + +ai_context: + intent: "Calendar view showing project timelines and durations" + domain: project_management +``` + +### 2.4 Chart View + +Data visualization with charts and graphs. + +```yaml +# File: revenue_by_month.view.yml + +label: Monthly Revenue +object: order +type: chart + +# Chart configuration +chart_type: bar # line, bar, pie, donut, area + +# Data aggregation +aggregations: + # Y-axis metric + metric: + field: amount + function: sum + label: Total Revenue + + # X-axis grouping + dimension: + field: created_at + group_by: month + label: Month + +# Filters +filters: + - field: status + operator: "=" + value: completed + - and + - field: created_at + operator: ">=" + value: $start_of_year + +# Time range +time_range: + field: created_at + period: last_12_months + +ai_context: + intent: "Visualize monthly revenue trends from completed orders" + domain: sales +``` + +### 2.5 Pivot Table View + +Multi-dimensional data analysis. + +```yaml +# File: sales_analysis.view.yml + +label: Sales Analysis +object: deal +type: pivot + +# Pivot configuration +rows: + - sales_rep + - region + +columns: + - quarter + +values: + - field: amount + function: sum + label: Total Deal Value + + - field: id + function: count + label: Number of Deals + +# Filters +filters: + - field: stage + operator: "=" + value: closed_won + - and + - field: close_date + operator: ">=" + value: $start_of_year + +ai_context: + intent: "Analyze sales performance by rep, region, and quarter" + domain: sales +``` + +## 3. Filters + +Views use the same filter syntax as the [Query Language](./query-language.md). + +### 3.1 Basic Filters + +```yaml +filters: + # Single condition + - field: status + operator: "=" + value: active + + # Logical operator + - and + + # Another condition + - field: priority + operator: in + value: [high, urgent] +``` + +### 3.2 Dynamic Filters + +Use dynamic values for user-specific or time-based filters. + +```yaml +filters: + # Current user + - field: owner_id + operator: "=" + value: $current_user.id + + # Date functions + - and + - field: due_date + operator: between + value: [$today, $end_of_week] + + # User attributes + - and + - field: region + operator: "=" + value: $current_user.region +``` + +### 3.3 Advanced Filters + +```yaml +filters: + # Nested conditions + - or: + - field: priority + operator: "=" + value: urgent + - and: + - field: priority + operator: "=" + value: high + - field: due_date + operator: "<" + value: $tomorrow + + # Related object filters + - field: customer.industry + operator: "=" + value: technology + + # Formula-based filters + - field: days_overdue + operator: ">" + value: 0 +``` + +## 4. Display Configuration + +### 4.1 Columns + +Define which fields to display and how. + +```yaml +columns: + # Simple field reference + - name + - status + + # Column with custom configuration + - field: amount + label: Deal Value + width: 150 + alignment: right + format: currency + + # Related field + - field: owner.name + label: Owner + width: 200 + + # Formula field + - field: days_until_due + label: Days Remaining + format: number +``` + +### 4.2 Sorting + +```yaml +sort: + # Primary sort + - field: priority + direction: desc + + # Secondary sort + - field: created_at + direction: asc +``` + +### 4.3 Pagination + +```yaml +pagination: + page_size: 50 # Records per page + default_page: 1 + show_total: true +``` + +## 5. Aggregations + +Calculate summary statistics for the view. + +```yaml +aggregations: + # Count records + total_count: + function: count + + # Sum numeric field + total_revenue: + field: amount + function: sum + + # Average + average_deal_size: + field: amount + function: avg + + # Min/Max + earliest_date: + field: created_at + function: min + + latest_date: + field: created_at + function: max + + # Group by + by_status: + field: status + function: count + group_by: status +``` + +## 6. Visibility and Sharing + +### 6.1 Private View + +Only visible to the creator. + +```yaml +label: My Private Tasks +object: task +visibility: private + +filters: + - field: assignee_id + operator: "=" + value: $current_user.id +``` + +### 6.2 Public View + +Visible to all users who can access the object. + +```yaml +label: All Active Projects +object: project +visibility: public + +filters: + - field: status + operator: "=" + value: active +``` + +### 6.3 Shared View + +Visible to specific users or roles. + +```yaml +label: Executive Dashboard View +object: opportunity +visibility: shared + +shared_with: + roles: + - executive + - sales_manager + users: + - ceo@company.com + - cfo@company.com + +filters: + - field: stage + operator: "=" + value: negotiation +``` + +## 7. Complete Examples + +### Example 1: My Open Tasks View + +```yaml +# File: my_open_tasks.view.yml + +label: My Open Tasks +object: task +type: list +description: Tasks assigned to me that are not yet completed + +# Filter to current user's open tasks +filters: + - field: assignee_id + operator: "=" + value: $current_user.id + - and + - field: status + operator: not in + value: [completed, cancelled] + +# Display columns +columns: + - title + - priority + - project.name + - due_date + - status + +# Sort by priority then due date +sort: + - field: priority + direction: desc + - field: due_date + direction: asc + +# Aggregations +aggregations: + total_tasks: + function: count + + overdue_count: + function: count + filters: + - field: due_date + operator: "<" + value: $today + +# Private view +visibility: private + +ai_context: + intent: "Personal task list showing open assignments sorted by priority" + domain: task_management + common_use_cases: + - "Check daily tasks" + - "See overdue tasks" + - "Plan work priorities" +``` + +### Example 2: Sales Pipeline View + +```yaml +# File: sales_pipeline.view.yml + +label: Sales Pipeline +object: opportunity +type: kanban +description: Visual pipeline of all sales opportunities + +# Group by stage +group_by: stage + +# Pipeline stages +swimlanes: + - value: prospecting + label: Prospecting + color: gray + + - value: qualification + label: Qualification + color: blue + + - value: proposal + label: Proposal + color: purple + + - value: negotiation + label: Negotiation + color: yellow + + - value: closed_won + label: Closed Won + color: green + + - value: closed_lost + label: Closed Lost + color: red + +# Card display +card_fields: + - name + - account.name + - amount + - close_date + - probability + +# Only show open opportunities +filters: + - field: is_closed + operator: "=" + value: false + +# Sort within stages +sort: + - field: amount + direction: desc + +# Aggregations +aggregations: + total_pipeline: + field: amount + function: sum + + weighted_pipeline: + field: weighted_amount + function: sum + + opportunity_count: + function: count + +# Public to sales team +visibility: public + +ai_context: + intent: "Kanban board showing sales pipeline with drag-and-drop stage updates" + domain: sales + related_views: + - forecast_view + - closed_deals +``` + +### Example 3: Overdue Invoices Report + +```yaml +# File: overdue_invoices.view.yml + +label: Overdue Invoices +object: invoice +type: list +description: Invoices past due date that haven't been paid + +# Overdue filter +filters: + - field: due_date + operator: "<" + value: $today + - and + - field: status + operator: "!=" + value: paid + +# Display columns +columns: + - invoice_number + - customer.name + - amount + - due_date + - days_overdue + - status + +# Sort by days overdue +sort: + - field: days_overdue + direction: desc + +# Aggregations +aggregations: + total_overdue: + field: amount + function: sum + label: Total Overdue Amount + + count_by_age: + function: count + group_by: aging_bucket + label: Invoices by Age + +# Shared with finance team +visibility: shared +shared_with: + roles: + - finance + - accounting + - collections + +ai_context: + intent: "Track overdue invoices for collections follow-up" + domain: finance + alerts: + - "Highlight invoices over 90 days old" + - "Notify collections team of new overdue invoices" +``` + +### Example 4: Revenue Trend Chart + +```yaml +# File: revenue_trend.view.yml + +label: Revenue Trend +object: order +type: chart +description: Monthly revenue trend over the last 12 months + +# Chart configuration +chart_type: line + +# Aggregation +aggregations: + metric: + field: total_amount + function: sum + label: Revenue + + dimension: + field: order_date + group_by: month + label: Month + +# Only completed orders +filters: + - field: status + operator: "=" + value: completed + - and + - field: order_date + operator: ">=" + value: $start_of_last_year + +# Time range +time_range: + field: order_date + period: last_12_months + +# Public view +visibility: public + +ai_context: + intent: "Visualize revenue trends to identify seasonal patterns" + domain: sales + insights: + - "Track month-over-month growth" + - "Identify seasonal trends" + - "Compare with previous year" +``` + +## 8. Best Practices + +### 8.1 Performance + +- **Limit initial data**: Use filters to reduce result set +- **Index filter fields**: Ensure filtered fields have indexes +- **Optimize aggregations**: Use database-level aggregations +- **Paginate large results**: Use reasonable page sizes + +### 8.2 User Experience + +- **Meaningful defaults**: Set sensible filters and sorts +- **Clear naming**: Use descriptive view names +- **Appropriate type**: Choose the right view type for the data +- **Save user preferences**: Remember user's customizations + +### 8.3 Maintainability + +- **Document intent**: Use `ai_context` to explain purpose +- **Reusable views**: Create views others can leverage +- **Version control**: Track view changes in Git +- **Regular review**: Clean up unused views + +### 8.4 Security + +- **Respect permissions**: Views honor object/field security +- **Careful sharing**: Consider who should access each view +- **Filter sensitive data**: Exclude confidential records +- **Audit access**: Log view usage for sensitive data + +## 9. Dynamic Values + +Views support dynamic values that evaluate at runtime. + +### 9.1 User Context + +```yaml +# Current user values +$current_user.id +$current_user.email +$current_user.role +$current_user.region +$current_user.manager_id +``` + +### 9.2 Date Functions + +```yaml +# Relative dates +$today +$yesterday +$tomorrow +$start_of_week +$end_of_week +$start_of_month +$end_of_month +$start_of_quarter +$end_of_quarter +$start_of_year +$end_of_year + +# Relative periods +$last_7_days +$last_30_days +$last_90_days +$last_12_months +$next_7_days +$next_30_days +``` + +### 9.3 Computed Values + +```yaml +# Formulas +$computed.field_name + +# Record counts +$count.related_object + +# Aggregates +$sum.field_name +$avg.field_name +``` + +## 10. View Composition + +Views can reference other views for composition. + +```yaml +# File: executive_pipeline.view.yml + +label: Executive Pipeline View +object: opportunity + +# Inherit from base view +extends: sales_pipeline + +# Add additional filters +filters: + - field: amount + operator: ">" + value: 100000 + +# Override columns +columns: + - name + - account.name + - amount + - stage + - owner.name + +ai_context: + intent: "Executive view of large opportunities in pipeline" + extends: sales_pipeline +``` + +## 11. Integration with Other Metadata + +Views integrate seamlessly with: + +- **Objects**: Query object data with full field access +- **Pages**: Pages can display views as tabs or sections +- **Permissions**: Views respect object and field permissions +- **Actions**: Views can expose actions for bulk operations +- **Formulas**: Views can display calculated formula fields + +## 12. AI Context Guidelines + +Include `ai_context` to help AI understand: + +```yaml +ai_context: + # Business purpose + intent: "Track high-priority tasks due this week" + + # Business domain + domain: project_management + + # Common scenarios + common_use_cases: + - "Daily standup review" + - "Weekly planning" + - "Urgent task tracking" + + # Related views + related_views: + - all_tasks + - overdue_tasks + + # Insights provided + insights: + - "Shows task distribution by priority" + - "Highlights overdue items" +``` + +## 13. Migration from Code + +### Before (SQL Query): +```sql +SELECT t.*, u.name as owner_name +FROM tasks t +JOIN users u ON t.owner_id = u.id +WHERE t.status NOT IN ('completed', 'cancelled') + AND t.owner_id = ? +ORDER BY t.priority DESC, t.due_date ASC; +``` + +### After (Metadata): +```yaml +# File: my_open_tasks.view.yml +object: task +filters: + - field: status + operator: not in + value: [completed, cancelled] + - and + - field: owner_id + operator: "=" + value: $current_user.id +columns: [title, priority, due_date, status] +sort: + - field: priority + direction: desc + - field: due_date + direction: asc +``` + +The ObjectQL engine automatically generates optimized queries! + +## See Also + +- [Query Language](./query-language.md) - Filter and query syntax +- [Pages](./page.md) - UI page definitions +- [Objects](./object.md) - Data model definitions +- [Permissions](./permission.md) - Access control From e3ee917f09a5b4a7acc0f32d15f37218372e2672 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 17 Jan 2026 10:52:49 +0000 Subject: [PATCH 3/5] docs: Update index and metadata-standard with new UI layer specs Co-authored-by: huangyiirene <7665279+huangyiirene@users.noreply.github.com> --- docs/spec/index.md | 13 ++ docs/spec/metadata-standard.md | 222 ++++++++++++++++++++++++++++++++- 2 files changed, 233 insertions(+), 2 deletions(-) diff --git a/docs/spec/index.md b/docs/spec/index.md index f91e492c..63a3105f 100644 --- a/docs/spec/index.md +++ b/docs/spec/index.md @@ -12,6 +12,7 @@ This section contains the complete metadata specifications for the ObjectQL plat * [**Query Language (JSON-DSL)**](./query-language.md) - Unified query protocol for database-agnostic data access ✅ * [**Validation Rules**](./validation.md) - Data quality and business rule enforcement ✅ * [**Formula Fields**](./formula.md) - Read-only calculated fields with JavaScript expressions ✅ +* [**Initial Data**](./data.md) - Seed data and default records for initialization ✅ ## Business Logic Layer @@ -19,6 +20,18 @@ This section contains the complete metadata specifications for the ObjectQL plat * [**Actions (RPC)**](./action.md) - Custom server-side functions and APIs ✅ * [**Workflows & Processes**](./workflow.md) - Automated business processes and approval chains ⚠️ *Spec complete, implementation pending* +## User Interface Layer + +* [**Pages**](./page.md) - UI page definitions, layouts, and navigation ✅ +* [**Views**](./view.md) - Saved data queries, filters, and display configurations ✅ +* [**Forms**](./form.md) - Data entry layouts and field configurations ✅ +* [**Reports**](./report.md) - Analytics, visualizations, and data exports ✅ +* [**Menus**](./menu.md) - Navigation structure and menu organization ✅ + +## Application Organization + +* [**Apps**](./app.md) - Application grouping, branding, and menu structure ✅ + ## Security & Access Control * [**Permissions**](./permission.md) - Role-based access control, field-level security, and record-level rules ✅ diff --git a/docs/spec/metadata-standard.md b/docs/spec/metadata-standard.md index 65abec8c..950fa906 100644 --- a/docs/spec/metadata-standard.md +++ b/docs/spec/metadata-standard.md @@ -198,7 +198,184 @@ steps: field: manager_id ``` -### 3. Security & Access Control +### 3. User Interface Layer + +#### [Pages](./page.md) +**Purpose**: Define UI layouts and page structures. + +**What you define**: +- List pages (table/grid views) +- Detail pages (record details) +- Dashboard pages (metrics and charts) +- Custom pages (specialized UI) +- Page sections and components +- Responsive layouts + +**Example** (`project_list.page.yml`): +```yaml +# File: project_list.page.yml +# Page name is inferred from filename! + +label: Projects +type: list +object: project + +view: + columns: + - name + - status + - owner + - end_date + + sort: + - field: end_date + direction: asc + +actions: + - create_project + - export_to_excel +``` + +#### [Views](./view.md) +**Purpose**: Saved queries and display configurations. + +**What you define**: +- Filters and sorting +- Column selections +- Grouping and aggregations +- Chart visualizations +- Kanban boards +- Calendar views + +**Example** (`active_projects.view.yml`): +```yaml +# File: active_projects.view.yml +# View name is inferred from filename! + +label: Active Projects +object: project +type: list + +filters: + - field: status + operator: "=" + value: active + +columns: + - name + - owner + - end_date + - progress + +sort: + - field: end_date + direction: asc +``` + +#### [Forms](./form.md) +**Purpose**: Data entry layouts and configurations. + +**What you define**: +- Field layouts (sections, columns) +- Field configurations (required, defaults) +- Validation rules +- Conditional fields +- Form actions +- Wizard forms (multi-step) + +**Example** (`project_create.form.yml`): +```yaml +# File: project_create.form.yml +# Form name is inferred from filename! + +label: Create Project +object: project +type: create + +sections: + - label: Project Information + fields: + - name: + required: true + - status: + default: planning + - owner: + default: $current_user.id + +defaults: + priority: medium + status: planning +``` + +#### [Reports](./report.md) +**Purpose**: Analytics and data exports. + +**What you define**: +- Report types (tabular, summary, matrix, chart) +- Data sources and joins +- Grouping and aggregations +- Visualizations +- Export formats (PDF, Excel, CSV) +- Scheduled distribution + +**Example** (`sales_summary.report.yml`): +```yaml +# File: sales_summary.report.yml +# Report name is inferred from filename! + +label: Sales Summary +type: summary +object: order + +grouping: + - field: sales_rep + label: Sales Rep + +aggregations: + total_revenue: + field: amount + function: sum + format: currency + + order_count: + function: count +``` + +#### [Menus](./menu.md) +**Purpose**: Navigation structure and organization. + +**What you define**: +- Menu items and hierarchy +- Navigation paths +- Icons and labels +- Permissions per item +- Dynamic menu generation +- Contextual actions + +**Example** (`main_menu.menu.yml`): +```yaml +# File: main_menu.menu.yml +# Menu name is inferred from filename! + +label: Main Navigation +type: main +position: left + +items: + - label: Dashboard + icon: standard:home + path: /dashboard + + - label: CRM + icon: standard:account + items: + - label: Accounts + path: /accounts + - label: Contacts + path: /contacts +``` + +### 4. Security & Access Control #### [Permissions](./permission.md) **Purpose**: Control who can access what data and operations. @@ -277,6 +454,32 @@ src/ workflows/ # Business processes order_approval.workflow.yml customer_onboarding.workflow.yml + + ui/ # User interface + pages/ + customer_list.page.yml + customer_detail.page.yml + views/ + my_customers.view.yml + vip_customers.view.yml + forms/ + customer_create.form.yml + customer_edit.form.yml + menus/ + main_menu.menu.yml + admin_menu.menu.yml + + reports/ # Analytics + sales_summary.report.yml + customer_ltv.report.yml + + data/ # Initial data + default_users.data.yml + sample_customers.data.yml + + apps/ # Application definitions + crm.app.yml + sales.app.yml ``` ## Development Workflow @@ -321,6 +524,11 @@ ObjectQL provides a universal loader and generic API for all metadata types. | Permission | `*.permission.yml` | Filename = Object name | `project.permission.yml` → applies to: `project` | | Validation | `*.validation.yml` | Filename = Object name | `project.validation.yml` → applies to: `project` | | Initial Data | `*.data.yml` | Filename = Object name | `users.data.yml` → applies to: `users` | +| Page | `*.page.yml` | Filename = Page name | `dashboard.page.yml` → page: `dashboard` | +| View | `*.view.yml` | Filename = View name | `active_projects.view.yml` → view: `active_projects` | +| Form | `*.form.yml` | Filename = Form name | `customer_create.form.yml` → form: `customer_create` | +| Report | `*.report.yml` | Filename = Report name | `sales_summary.report.yml` → report: `sales_summary` | +| Menu | `*.menu.yml` | Filename = Menu name | `main_menu.menu.yml` → menu: `main_menu` | **Benefits:** - ✅ **Less redundancy** - No need to repeat the name inside the file @@ -394,15 +602,25 @@ fields: ## Reference +### Core Data Layer - [Objects & Fields](./object.md) - Data modeling - [Query Language](./query-language.md) - Data access - [Validation](./validation.md) - Data quality +- [Formula Fields](./formula.md) - Calculated fields +- [Initial Data](./data.md) - Seed data + +### Business Logic Layer - [Hooks](./hook.md) - Event triggers - [Actions](./action.md) - Custom operations - [Workflows](./workflow.md) - Process automation + +### User Interface Layer - [Pages](./page.md) - UI pages and components - [Views](./view.md) - Data presentation - [Forms](./form.md) - Data entry - [Reports](./report.md) - Analytics - [Menus](./menu.md) - Navigation -- [Permissions](./permission.md) - Security + +### Application & Security +- [Apps](./app.md) - Application organization +- [Permissions](./permission.md) - Security and access control From 51ead53ed7b787be3c432e5182f3150fa7d2391d Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 17 Jan 2026 10:54:12 +0000 Subject: [PATCH 4/5] docs: Expand app.md specification with comprehensive examples and guidance Co-authored-by: huangyiirene <7665279+huangyiirene@users.noreply.github.com> --- docs/spec/app.md | 776 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 744 insertions(+), 32 deletions(-) diff --git a/docs/spec/app.md b/docs/spec/app.md index 66869ab0..2a228859 100644 --- a/docs/spec/app.md +++ b/docs/spec/app.md @@ -1,46 +1,758 @@ -# Application Metadata +# Application Definition -Application metadata defines the high-level container for a specific set of functionality (e.g., "Sales", "HR", "Admin"). It serves effectively as a grouping mechanism for menus and other resources. +Applications define high-level containers for organizing related functionality, objects, and features. They provide logical grouping, navigation structure, and branding for distinct areas of your system. -## 1. File Naming +**File Naming Convention:** `.app.yml` -**Convention:** `[app_name].app.yml` +The filename (without the `.app.yml` extension) automatically becomes the application's identifier. This eliminates the need for a redundant `name` property inside the file. **Examples:** -- `sales.app.yml` -- `admin.app.yml` +- `crm.app.yml` → Application identifier: `crm` +- `sales.app.yml` → Application identifier: `sales` +- `hr_management.app.yml` → Application identifier: `hr_management` -## 2. Structure +Files should use **snake_case** for multi-word names. -The structure is intentionally kept simple to allow for flexibility in frontend plugins and extensions. +## 1. Root Properties + +| Property | Type | Required | Description | +| :--- | :--- | :--- | :--- | +| `label` | `string` | **Required** | Human-readable application name (e.g., "Customer Relationship Management"). | +| `description` | `string` | Optional | Brief description of the application's purpose. | +| `icon` | `string` | Optional | Icon identifier for the app launcher. | +| `logo` | `string` | Optional | URL or path to custom logo image. | +| `color` | `string` | Optional | Brand color for the app (hex code). | +| `homepage` | `string` | Optional | Default landing page path when app is opened. | +| `objects` | `array` | Optional | Objects that belong to this application. | +| `menus` | `array` | Optional | Navigation menus for this application. | +| `pages` | `array` | Optional | Pages associated with this application. | +| `sort_order` | `number` | Optional | Sort order in app launcher (lower = first). | +| `is_active` | `boolean` | Optional | Whether the app is visible to users. Default: `true`. | +| `permissions` | `object` | Optional | Access control for the application. | +| `features` | `object` | Optional | Feature flags and configuration. | +| `settings` | `object` | Optional | Application-specific settings. | +| `ai_context` | `object` | Optional | AI-friendly context for understanding app purpose. | + +## 2. Basic Application Definition + +### 2.1 Minimal Application + +```yaml +# File: crm.app.yml + +label: Customer Relationship Management +description: Manage customer relationships, sales pipeline, and opportunities +icon: standard:account +homepage: /crm/dashboard +``` + +### 2.2 Complete Application ```yaml -name: sales -label: Sales App -description: Manage leads, opportunities, and customers. -icon: currency +# File: sales.app.yml + +label: Sales Management +description: Complete sales lifecycle management from lead to close +icon: standard:opportunity logo: /assets/sales-logo.png -homepage: /app/sales -sort_no: 10 +color: "#3498db" +homepage: /sales/dashboard + +# Objects included in this app +objects: + - lead + - opportunity + - account + - contact + - quote + - order + +# Navigation menus +menus: + - sales_main_menu + - sales_actions_menu + +# Key pages +pages: + - sales_dashboard + - pipeline_view + - forecast_view + +# Sort order in app launcher +sort_order: 10 + +# Active state is_active: true + +# Access control +permissions: + view: [sales_rep, sales_manager, admin] + configure: [sales_manager, admin] + +# Application features +features: + forecasting: + enabled: true + settings: + forecast_periods: [monthly, quarterly] + + territory_management: + enabled: true + + pipeline_analytics: + enabled: true + +# Application settings +settings: + currency: USD + fiscal_year_start: january + quota_period: quarterly + + stages: + - prospecting + - qualification + - proposal + - negotiation + - closed_won + - closed_lost + +ai_context: + intent: "Complete sales lifecycle management application" + domain: sales + key_features: + - "Lead management and qualification" + - "Opportunity pipeline tracking" + - "Sales forecasting" + - "Quote and order generation" ``` -## 3. Properties +## 3. Application Components -| Property | Type | Required | Description | -| :--- | :--- | :--- | :--- | -| `name` | string | **Yes** | Unique identifier for the application. | -| `label` | string | **Yes** | Human-readable name displayed in the UI launcher. | -| `description` | string | No | Description of the application's purpose. | -| `icon` | string | No | Icon name (e.g., standard icon set name) for the app launcher. | -| `logo` | string | No | URL or path to a custom logo image. | -| `homepage` | string | No | The default path to navigate to when the app is opened. | -| `sort_no` | number | No | Integer for sorting applications in the launcher. | -| `is_active` | boolean | No | Whether the app is visible to users. Defaults to `true`. | - -## 4. Application Usage - -Application metadata serves as a container for grouping related functionality. The application definition is intentionally kept simple and lightweight to allow for: -- Organizing related objects, workflows, and actions -- Defining application-level configuration -- Frontend plugins to dynamically integrate with the application without modifying core definitions +### 3.1 Objects + +Define which objects belong to this application. + +```yaml +# File: hr.app.yml + +label: Human Resources +icon: standard:people + +# Objects in this app +objects: + - employee + - department + - position + - leave_request + - performance_review + - training_program + +# Object grouping +object_groups: + - label: Employee Management + objects: + - employee + - department + - position + + - label: Leave & Attendance + objects: + - leave_request + - attendance_record + + - label: Performance + objects: + - performance_review + - goal +``` + +### 3.2 Menus + +Define navigation structure for the application. + +```yaml +menus: + # Main navigation menu + - id: crm_main_menu + type: main + position: left + + # Quick actions menu + - id: crm_quick_actions + type: toolbar + position: top + + # Admin menu (conditional) + - id: crm_admin_menu + type: sidebar + permissions: + view: [admin] +``` + +### 3.3 Pages and Dashboards + +```yaml +pages: + # Dashboard + - id: sales_dashboard + label: Sales Dashboard + type: dashboard + is_default: true + + # List pages + - id: opportunity_list + label: Opportunities + type: list + + # Detail pages + - id: account_detail + label: Account Details + type: detail + + # Custom pages + - id: forecast_view + label: Sales Forecast + type: custom +``` + +## 4. Multi-App Organization + +### 4.1 App Grouping + +Organize multiple related apps. + +```yaml +# File: suite.app.yml + +label: Business Suite +description: Complete business management suite +type: suite + +# Child applications +apps: + - crm + - sales + - service + - marketing + +# Shared resources +shared: + objects: + - user + - account + - contact + + menus: + - main_navigation +``` + +### 4.2 App Dependencies + +```yaml +# File: service.app.yml + +label: Customer Service +icon: standard:case + +# Dependencies on other apps +dependencies: + - crm # Requires CRM app for accounts/contacts + + # Shared objects from CRM + shared_from: + crm: + - account + - contact + +# Service-specific objects +objects: + - case + - knowledge_article + - service_contract +``` + +## 5. Permissions and Access Control + +### 5.1 App-Level Permissions + +```yaml +permissions: + # Who can view this app + view: [sales_rep, sales_manager, admin] + + # Who can configure app settings + configure: [sales_manager, admin] + + # Who can access admin features + admin: [admin] + +# Permission sets +permission_sets: + - name: sales_user + grants: + view: true + create_records: true + edit_own_records: true + + - name: sales_manager + grants: + view: true + create_records: true + edit_all_records: true + delete_records: true + configure: true +``` + +### 5.2 Feature-Based Access + +```yaml +features: + forecasting: + enabled: true + permissions: + access: [sales_manager, admin] + + advanced_reporting: + enabled: true + permissions: + access: [analyst, sales_manager, admin] + + data_export: + enabled: true + permissions: + access: [admin] +``` + +## 6. Application Settings + +### 6.1 Business Configuration + +```yaml +settings: + # Locale settings + locale: + currency: USD + date_format: MM/DD/YYYY + timezone: America/New_York + + # Business calendar + fiscal_year_start: january + business_hours: + start: "09:00" + end: "17:00" + timezone: America/New_York + + # Workflow settings + approvals: + required_for_high_value: true + high_value_threshold: 50000 + + # Notification settings + notifications: + email_enabled: true + slack_enabled: true + mobile_push_enabled: true +``` + +### 6.2 Integration Settings + +```yaml +settings: + integrations: + # Email integration + email: + provider: gmail + sync_enabled: true + sync_interval: 300 # seconds + + # Calendar integration + calendar: + provider: google_calendar + sync_events: true + + # Third-party apps + external: + salesforce: + enabled: true + sync_direction: bidirectional + + slack: + enabled: true + channels: + - sales-team + - deals +``` + +## 7. Feature Flags + +Control application features dynamically. + +```yaml +features: + # AI-powered features + ai_assistant: + enabled: true + settings: + model: gpt-4 + suggestions_enabled: true + + # Analytics + advanced_analytics: + enabled: true + settings: + retention_days: 90 + + # Mobile app + mobile_app: + enabled: true + platforms: [ios, android] + + # Experimental features + beta_features: + enabled: false + available_to: [admin] +``` + +## 8. Complete Examples + +### Example 1: CRM Application + +```yaml +# File: crm.app.yml + +label: Customer Relationship Management +description: Unified platform for managing customer relationships and sales +icon: standard:account +logo: /assets/crm-logo.png +color: "#2ecc71" +homepage: /crm/dashboard + +# Core objects +objects: + - account + - contact + - lead + - opportunity + +# Object grouping +object_groups: + - label: Customers + objects: [account, contact] + + - label: Sales Pipeline + objects: [lead, opportunity] + +# Navigation +menus: + - crm_main_menu + - crm_quick_create + +# Key pages +pages: + - crm_dashboard + - sales_pipeline + - account_360_view + +# Permissions +permissions: + view: [sales_rep, sales_manager, admin] + configure: [sales_manager, admin] + +# Features +features: + lead_scoring: + enabled: true + settings: + model: engagement_based + + duplicate_detection: + enabled: true + + email_tracking: + enabled: true + +# Settings +settings: + locale: + currency: USD + timezone: America/New_York + + sales_process: + stages: [prospecting, qualification, proposal, negotiation, closed] + required_fields_by_stage: + qualification: [budget, timeline, decision_maker] + proposal: [quote_sent_date, proposal_document] + +sort_order: 1 +is_active: true + +ai_context: + intent: "Comprehensive CRM for managing customer relationships and sales pipeline" + domain: crm + key_workflows: + - "Lead capture and qualification" + - "Opportunity management" + - "Account relationship tracking" +``` + +### Example 2: Project Management Application + +```yaml +# File: project_management.app.yml + +label: Project Management +description: Plan, track, and deliver projects on time +icon: standard:project +color: "#9b59b6" +homepage: /projects/dashboard + +objects: + - project + - task + - milestone + - project_resource + - time_entry + +object_groups: + - label: Planning + objects: [project, milestone] + + - label: Execution + objects: [task, time_entry] + + - label: Resources + objects: [project_resource] + +menus: + - projects_main_menu + - project_actions_menu + +pages: + - projects_dashboard + - project_gantt_view + - project_kanban_board + - resource_allocation + +permissions: + view: [team_member, project_manager, admin] + create_projects: [project_manager, admin] + configure: [admin] + +features: + gantt_charts: + enabled: true + + time_tracking: + enabled: true + billable: true + + resource_planning: + enabled: true + + budgeting: + enabled: true + settings: + track_costs: true + track_revenue: true + +settings: + work_days: [monday, tuesday, wednesday, thursday, friday] + work_hours_per_day: 8 + + project_statuses: + - planning + - active + - on_hold + - completed + - cancelled + + task_priorities: + - low + - medium + - high + - urgent + + notifications: + task_assigned: true + deadline_approaching: true + milestone_completed: true + +sort_order: 20 + +ai_context: + intent: "Project management application for planning and execution" + domain: project_management + methodologies: + - Agile + - Waterfall + - Hybrid +``` + +### Example 3: Admin Console Application + +```yaml +# File: admin.app.yml + +label: Administration +description: System administration and configuration +icon: standard:settings +color: "#34495e" +homepage: /admin/overview + +objects: + - user + - role + - permission_set + - profile + - system_log + - audit_trail + +object_groups: + - label: User Management + objects: [user, role, profile] + + - label: Security + objects: [permission_set, audit_trail] + + - label: System + objects: [system_log, background_job] + +menus: + - admin_sidebar_menu + +pages: + - admin_dashboard + - user_management + - system_health + - audit_logs + +permissions: + view: [admin, system_admin] + configure: [system_admin] + +features: + user_impersonation: + enabled: true + permissions: + access: [system_admin] + audit: true + + bulk_operations: + enabled: true + + system_monitoring: + enabled: true + settings: + metrics_retention_days: 30 + +settings: + security: + password_policy: + min_length: 12 + require_uppercase: true + require_numbers: true + require_special_chars: true + expiry_days: 90 + + session: + timeout_minutes: 60 + concurrent_sessions: 3 + + mfa: + enabled: true + methods: [totp, sms] + + system: + maintenance_mode: false + api_rate_limit: 1000 # per hour + max_upload_size: 10485760 # 10MB + +sort_order: 999 + +ai_context: + intent: "System administration and configuration console" + domain: administration + critical_features: + - "User and access management" + - "Security configuration" + - "System monitoring" + - "Audit logging" +``` + +## 9. Best Practices + +### 9.1 Organization + +- **Single responsibility**: Each app should focus on a specific domain +- **Clear boundaries**: Minimize overlapping functionality between apps +- **Logical grouping**: Group related objects and features together +- **Consistent naming**: Use descriptive, consistent naming conventions + +### 9.2 Scalability + +- **Modular design**: Build apps that can work independently +- **Shared resources**: Use shared objects for common entities +- **Feature flags**: Use flags for gradual rollout of features +- **Performance**: Consider object count and data volume + +### 9.3 User Experience + +- **Clear navigation**: Provide intuitive menu structure +- **Sensible defaults**: Set appropriate default pages and settings +- **Progressive disclosure**: Show advanced features only when needed +- **Consistent branding**: Use consistent icons, colors, and terminology + +### 9.4 Security + +- **Permission-first**: Define permissions for all app components +- **Least privilege**: Grant minimum necessary access +- **Audit logging**: Track configuration changes +- **Regular review**: Periodically review and update permissions + +## 10. Application Lifecycle + +### 10.1 Development + +```yaml +# Development app configuration +is_active: true +features: + beta_features: + enabled: true + debug_mode: + enabled: true +settings: + logging_level: debug +``` + +### 10.2 Production + +```yaml +# Production app configuration +is_active: true +features: + beta_features: + enabled: false + debug_mode: + enabled: false +settings: + logging_level: info + performance_monitoring: true +``` + +## 11. Integration with Other Metadata + +Applications integrate with: + +- **Objects**: Define which objects belong to the app +- **Menus**: Provide navigation structure +- **Pages**: Define app-specific pages and dashboards +- **Permissions**: Control app and feature access +- **Workflows**: Organize workflows by application context + +## See Also + +- [Objects](./object.md) - Data model definitions +- [Menus](./menu.md) - Navigation structure +- [Pages](./page.md) - UI page definitions +- [Permissions](./permission.md) - Access control From 58f026b3db56e44d13cc9a59b36ee201dc1d6d30 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 17 Jan 2026 10:55:46 +0000 Subject: [PATCH 5/5] docs: Add comprehensive pagination examples and best practices to query-language.md Co-authored-by: huangyiirene <7665279+huangyiirene@users.noreply.github.com> --- docs/spec/query-language.md | 434 ++++++++++++++++++++++++++++++++++++ 1 file changed, 434 insertions(+) diff --git a/docs/spec/query-language.md b/docs/spec/query-language.md index 6cbfde5e..d664c441 100644 --- a/docs/spec/query-language.md +++ b/docs/spec/query-language.md @@ -472,3 +472,437 @@ AI context can suggest optimizations: } ``` +## 6. Pagination and Data Fetching + +Pagination is essential for managing large result sets efficiently. ObjectQL supports multiple pagination strategies. + +### 6.1 Offset-Based Pagination + +The traditional approach using `top` (LIMIT) and `skip` (OFFSET). + +**Basic Example:** + +```javascript +{ + "object": "products", + "fields": ["name", "price", "stock"], + "sort": [["name", "asc"]], + + // Page 1: First 20 records + "top": 20, + "skip": 0 +} +``` + +**Page 2:** + +```javascript +{ + "object": "products", + "fields": ["name", "price", "stock"], + "sort": [["name", "asc"]], + + // Page 2: Next 20 records + "top": 20, + "skip": 20 // Skip first page +} +``` + +**Page 3:** + +```javascript +{ + "object": "products", + "fields": ["name", "price", "stock"], + "sort": [["name", "asc"]], + + // Page 3 + "top": 20, + "skip": 40 // Skip first two pages +} +``` + +**Calculating Skip:** +```javascript +// skip = (page - 1) * pageSize +const page = 3; +const pageSize = 20; +const skip = (page - 1) * pageSize; // 40 + +const query = { + object: "products", + top: pageSize, + skip: skip +}; +``` + +**Response Format:** + +```javascript +{ + "data": [...], // Array of records + "pagination": { + "total": 150, // Total records matching query + "page": 3, // Current page (calculated) + "pageSize": 20, // Records per page + "totalPages": 8, // Math.ceil(total / pageSize) + "hasMore": true, // Whether more pages exist + "skip": 40, // Current skip value + "top": 20 // Current limit + } +} +``` + +### 6.2 Cursor-Based Pagination + +More efficient for large datasets, prevents data inconsistencies when records are added/removed. + +**First Request:** + +```javascript +{ + "object": "orders", + "fields": ["id", "order_no", "amount", "created_at"], + "sort": [["created_at", "desc"], ["id", "asc"]], // Must include unique field + "top": 20, + + "ai_context": { + "intent": "First page of recent orders", + "pagination_strategy": "cursor" + } +} +``` + +**Response:** + +```javascript +{ + "data": [ + { "id": "100", "order_no": "ORD-100", "amount": 500, "created_at": "2024-01-15" }, + // ... 19 more records + { "id": "81", "order_no": "ORD-81", "amount": 300, "created_at": "2024-01-14" } + ], + "cursor": { + "next": "eyJjcmVhdGVkX2F0IjoiMjAyNC0wMS0xNCIsImlkIjoiODEifQ==", // Base64 encoded cursor + "hasMore": true + } +} +``` + +**Next Page Request:** + +```javascript +{ + "object": "orders", + "fields": ["id", "order_no", "amount", "created_at"], + "sort": [["created_at", "desc"], ["id", "asc"]], + "top": 20, + + // Use cursor from previous response + "cursor": "eyJjcmVhdGVkX2F0IjoiMjAyNC0wMS0xNCIsImlkIjoiODEifQ==", + + "ai_context": { + "intent": "Next page of orders using cursor", + "pagination_strategy": "cursor" + } +} +``` + +**Cursor Implementation:** + +The cursor encodes the last record's sort values: + +```javascript +// Cursor contains: { created_at: "2024-01-14", id: "81" } +// Query becomes: +"filters": [ + // Your original filters (if any) + // ... plus cursor filter: + "and", + [ + ["created_at", "<", "2024-01-14"], + "or", + [ + ["created_at", "=", "2024-01-14"], + "and", + ["id", ">", "81"] + ] + ] +] +``` + +### 6.3 Keyset Pagination (Seek Method) + +Similar to cursor but explicitly defined in the query. + +```javascript +{ + "object": "customers", + "fields": ["id", "name", "created_at"], + "sort": [["created_at", "desc"], ["id", "asc"]], + "top": 20, + + // For page 2+, use seek criteria + "filters": [ + // Start after the last record from previous page + [ + ["created_at", "<", "2024-01-10"], + "or", + [ + ["created_at", "=", "2024-01-10"], + "and", + ["id", ">", "12345"] + ] + ] + ], + + "ai_context": { + "intent": "Efficient keyset pagination", + "last_seen": { "created_at": "2024-01-10", "id": "12345" } + } +} +``` + +### 6.4 Infinite Scroll Pattern + +For continuously loading data as user scrolls. + +**Initial Load:** + +```javascript +{ + "object": "posts", + "fields": ["id", "title", "content", "created_at"], + "sort": [["created_at", "desc"]], + "top": 20, + + "ai_context": { + "intent": "Initial load for infinite scroll feed", + "ui_pattern": "infinite_scroll" + } +} +``` + +**Load More:** + +```javascript +{ + "object": "posts", + "fields": ["id", "title", "content", "created_at"], + "sort": [["created_at", "desc"]], + "top": 20, + "skip": 20, // Or use cursor + + "ai_context": { + "intent": "Load more posts for infinite scroll", + "scroll_position": "after_20_items" + } +} +``` + +### 6.5 Pagination with Filtering + +Pagination parameters work alongside filters. + +```javascript +{ + "object": "tasks", + "fields": ["title", "status", "assignee", "due_date"], + + // Filters reduce the total result set + "filters": [ + ["status", "in", ["pending", "in_progress"]], + "and", + ["assignee_id", "=", "$current_user"] + ], + + "sort": [["due_date", "asc"]], + + // Pagination applies to filtered results + "top": 25, + "skip": 0, + + "ai_context": { + "intent": "Paginate through my active tasks", + "filtered_pagination": true + } +} +``` + +**Response includes filtered totals:** + +```javascript +{ + "data": [...], + "pagination": { + "total": 67, // Total matching the filters + "totalUnfiltered": 1523, // Total records in table + "filtered": true, + "page": 1, + "pageSize": 25, + "totalPages": 3 + } +} +``` + +### 6.6 Pagination Best Practices + +#### 6.6.1 Performance Considerations + +**DO:** +- Use `top` to limit result size (recommended: 10-100) +- Include specific `fields` to reduce payload size +- Use indexes on sort fields +- Use cursor pagination for large datasets +- Add `ai_context.expected_result_size` for optimization hints + +**DON'T:** +- Omit `top` for unbounded queries +- Use large `skip` values (>10,000) with offset pagination +- Request all fields when only a few are needed +- Skip pagination entirely for tables with >1000 records + +#### 6.6.2 Choosing Pagination Strategy + +| Strategy | Best For | Pros | Cons | +|----------|----------|------|------| +| **Offset** (`top`/`skip`) | Small-medium datasets, simple UIs | Simple, random access to pages | Slow for large offsets, inconsistent with concurrent changes | +| **Cursor** | Large datasets, real-time data | Fast, consistent, efficient | No random page access, more complex | +| **Keyset** | Ordered data, high performance | Very fast, efficient | Requires unique + sortable fields | + +#### 6.6.3 Complete Pagination Example + +```javascript +{ + "object": "invoices", + + "ai_context": { + "intent": "Paginated list of unpaid invoices", + "use_case": "Collections dashboard", + "pagination_strategy": "offset", + "expected_page_views": 5 + }, + + "fields": [ + "invoice_no", + "customer.name", + "amount", + "due_date", + "days_overdue" + ], + + "filters": [ + ["status", "!=", "paid"], + "and", + ["due_date", "<", "$today"] + ], + + "sort": [ + ["days_overdue", "desc"], // Most overdue first + ["amount", "desc"] // Then by amount + ], + + // Page 1: 50 records + "top": 50, + "skip": 0, + + "expand": { + "customer": { + "fields": ["name", "email", "phone"] + } + } +} +``` + +**Client-side pagination handler:** + +```typescript +interface PaginationState { + page: number; + pageSize: number; + total?: number; + cursor?: string; +} + +async function fetchPage(state: PaginationState) { + const query = { + object: "invoices", + fields: ["invoice_no", "amount", "due_date"], + filters: [["status", "!=", "paid"]], + sort: [["due_date", "asc"]], + + // Offset-based + top: state.pageSize, + skip: (state.page - 1) * state.pageSize, + + // Or cursor-based + // cursor: state.cursor + }; + + const response = await objectql.query(query); + + return { + data: response.data, + total: response.pagination.total, + hasMore: response.pagination.hasMore + }; +} +``` + +### 6.7 Pagination Edge Cases + +#### 6.7.1 Empty Results + +```javascript +{ + "data": [], + "pagination": { + "total": 0, + "page": 1, + "pageSize": 20, + "totalPages": 0, + "hasMore": false + } +} +``` + +#### 6.7.2 Single Page + +```javascript +{ + "data": [/* 15 records */], + "pagination": { + "total": 15, + "page": 1, + "pageSize": 20, + "totalPages": 1, + "hasMore": false + } +} +``` + +#### 6.7.3 Last Page + +```javascript +// Requesting page 5 with pageSize 20 +{ + "data": [/* 7 records */], + "pagination": { + "total": 87, + "page": 5, + "pageSize": 20, + "totalPages": 5, + "hasMore": false, + "isLastPage": true + } +} +``` + +## 7. See Also + +- [Query Best Practices Guide](../guide/query-best-practices.md) - Performance optimization and benchmarks +- [Objects](./object.md) - Data model definitions +- [Views](./view.md) - Saved queries and filters +- [REST API](../api/rest.md) - REST endpoint for queries +- [GraphQL API](../api/graphql.md) - GraphQL alternative +