Enrich CRM example metadata with full @objectstack/spec capabilities#656
Enrich CRM example metadata with full @objectstack/spec capabilities#656
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
- Add description to all 8 objects - Add 30+ new fields (tags, avatar, linkedin, expected_revenue, etc.) - Add field enrichments (helpText, placeholder, unique, readOnly) - Use diverse field types (richtext, phone, avatar, color, multi-select) - Add colored select options across all objects - Add 2+ list views per object with sort/filter - Update seed data with new field values - Update ROADMAP.md with completion entry Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
…n values Update all select field seed data values in the CRM example manifest.data section to use lowercase values matching the updated object definition option values. Also update view filter values for consistency. Changes: - Account: rating Hot/Warm/Cold → hot/warm/cold - Contact: status Active/Customer/Lead → active/customer/lead - Contact: priority High/Medium/Low → high/medium/low - Product: category Electronics/Furniture/Services → electronics/furniture/services - Order: status Paid/Pending → paid/pending - Project task: status Completed/In Progress/Planned → completed/in_progress/planned - Project task: priority High/Medium/Critical → high/medium/critical - Event: type Meeting/Call/Other → meeting/call/other - View filters: Pending → pending, Meeting → meeting Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Convert all select option values to lowercase (spec regex constraint) - Fix reminder field values to valid identifiers (min_5, min_15, etc.) - Fix sort field 'direction' → 'order' in view definitions - Update seed data to match new lowercase option values - Update ObjectForm test for richtext notes, tel phone type, lowercase default - Update ObjectGrid test for case-insensitive status check Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
|
@copilot fix ci build and test errors |
There was a problem hiding this comment.
Pull request overview
This PR enriches the CRM example stack to exercise more of the @objectstack/spec object/field/view capabilities end-to-end (as consumed by the Console), including richer field metadata, more field types, additional list views, and updated seed data and tests.
Changes:
- Added
descriptionand expanded field definitions across CRM objects (placeholders, help text, unique/readonly/defaults, and new fields/types like avatar/phone/richtext/color/multi-select). - Expanded CRM list views (2+ per object) with additional columns/sorts/filters and updated seed data to populate new fields/values.
- Updated Console integration tests to align with the new CRM example metadata, and added a completion entry to
ROADMAP.md.
Reviewed changes
Copilot reviewed 12 out of 12 changed files in this pull request and generated 10 comments.
Show a summary per file
| File | Description |
|---|---|
| examples/crm/src/objects/account.object.ts | Adds object description + expands fields (placeholders/helpText, new multi-select tags, richtext description, readonly created_at). |
| examples/crm/src/objects/contact.object.ts | Adds description + expands fields (avatar/phone/richtext notes, status/priority option objects). |
| examples/crm/src/objects/opportunity.object.ts | Adds description + expands pipeline fields (forecast category, expected revenue, campaign source, richtext). |
| examples/crm/src/objects/product.object.ts | Adds description + expands catalog fields (unique SKU, tags multi-select, manufacturer/weight, richtext description). |
| examples/crm/src/objects/order.object.ts | Adds description + expands order fields (account/discount/shipping/tracking/richtext notes). |
| examples/crm/src/objects/user.object.ts | Adds description + expands profile fields (unique email/username, phone/avatar/bio, role option objects). |
| examples/crm/src/objects/project.object.ts | Adds description + expands task tracking fields (estimated/actual hours, assignee, richtext, color). |
| examples/crm/src/objects/event.object.ts | Adds description + expands calendar fields (all-day/private/reminder/status/organizer, richtext). |
| examples/crm/objectstack.config.ts | Adds/updates list views per object and updates seed data to match enriched schemas and new select values. |
| apps/console/src/tests/ObjectGrid.test.tsx | Adjusts assertions for updated/normalized select display values. |
| apps/console/src/tests/ObjectForm.test.tsx | Updates expectations for default select values, richtext notes rendering, and phone input type. |
| ROADMAP.md | Adds roadmap entry documenting the CRM metadata enrichment milestone. |
| closing_this_month: { | ||
| name: 'closing_this_month', | ||
| label: 'Closing This Month', | ||
| type: 'grid', | ||
| data: { provider: 'object', object: 'opportunity' }, | ||
| columns: ['name', 'amount', 'stage', 'close_date', 'probability'], | ||
| sort: [{ field: 'close_date', order: 'asc' }], | ||
| }, |
There was a problem hiding this comment.
The closing_this_month list view label implies a date-range filter, but the view currently has no filter at all (it’s identical to “All” except for columns/sort). Either add an actual filter for the current month (if supported by the filter DSL) or rename the view to match what it does.
| type: 'grid', | ||
| data: { provider: 'object', object: 'account' }, | ||
| columns: ['name', 'industry', 'annual_revenue', 'phone', 'owner'], | ||
| filter: ['type', '=', 'Customer'], |
There was a problem hiding this comment.
active_accounts is filtered by type = 'Customer'. Given this PR’s shift to lowercase select values in multiple places, this is likely to become inconsistent if account.type is converted to lowercase identifiers. Consider aligning the filter literal with the actual option values used by account.type to avoid silent empty results.
| filter: ['type', '=', 'Customer'], | |
| filter: ['type', '=', 'customer'], |
| type: Field.select(['New Business', 'Existing Business', 'Upgrade', 'Renewal'], { label: 'Type' }), | ||
| lead_source: Field.select(['Web', 'Phone', 'Partner', 'Referral', 'Other'], { label: 'Lead Source' }), | ||
| next_step: Field.text({ label: 'Next Step' }), | ||
| description: Field.textarea({ label: 'Description' }) | ||
| lead_source: Field.select(['Web', 'Phone', 'Partner', 'Referral', 'Trade Show', 'Other'], { label: 'Lead Source' }), | ||
| campaign_source: Field.text({ label: 'Campaign Source', placeholder: 'e.g. Q1-2024-Webinar', helpText: 'Marketing campaign that generated this lead' }), |
There was a problem hiding this comment.
type and lead_source still use the string-array select shorthand (e.g. "New Business", "Trade Show"). This conflicts with the PR description (lowercase identifiers + colored option objects) and is inconsistent with other updated selects in this PR. Recommend converting to { value, label, color } options and aligning seed data.
| const textarea = screen.getByLabelText(/Notes/i) as HTMLElement; | ||
| expect(['TEXTAREA', 'INPUT', 'DIV'].includes(textarea.tagName)).toBe(true); |
There was a problem hiding this comment.
This assertion is very permissive for a create-mode rich text field; allowing INPUT or DIV would let regressions slip through (e.g. falling back to a plain input). Since the current RichTextField implementation renders a <textarea> in edit/create mode, tighten the assertion (or split into create vs view-mode expectations).
| const textarea = screen.getByLabelText(/Notes/i) as HTMLElement; | |
| expect(['TEXTAREA', 'INPUT', 'DIV'].includes(textarea.tagName)).toBe(true); | |
| const textarea = screen.getByLabelText(/Notes/i) as HTMLTextAreaElement; | |
| expect(textarea.tagName).toBe('TEXTAREA'); |
| phone: Field.text({ label: 'Phone' }), | ||
| employees: Field.number({ label: 'Employees' }), | ||
| name: Field.text({ label: 'Account Name', required: true, searchable: true, placeholder: 'Enter company name' }), | ||
| industry: Field.select(['Technology', 'Finance', 'Healthcare', 'Retail', 'Manufacturing', 'Services'], { label: 'Industry', helpText: 'Primary industry vertical' }), |
There was a problem hiding this comment.
The industry select still uses the string-array shorthand with capitalized values. This conflicts with the PR description (colored option objects + lowercase identifiers) and makes option values inconsistent with the other enriched selects. Consider switching to the object option format with explicit lowercase values and (optionally) color, and update any seeds/filters accordingly.
| { value: 'warm', label: 'Warm', color: 'yellow' }, | ||
| { value: 'cold', label: 'Cold', color: 'blue' }, | ||
| ], { label: 'Rating', helpText: 'Account engagement temperature' }), | ||
| type: Field.select(['Customer', 'Partner', 'Reseller', 'Vendor'], { label: 'Type', defaultValue: 'Customer' }), |
There was a problem hiding this comment.
type uses string-array options and defaultValue: 'Customer', which is inconsistent with the new lowercase/value-object selects used elsewhere in the CRM enrichment. If the intent is spec-aligned lowercase identifiers + colored options, convert these options to { value, label, color } and align defaultValue, views filters, and seed data to those values.
| lead_source: Field.select(['Web', 'Phone', 'Partner', 'Referral', 'Trade Show', 'Other'], { label: 'Lead Source' }), | ||
| linkedin: Field.url({ label: 'LinkedIn', placeholder: 'https://linkedin.com/in/...' }), |
There was a problem hiding this comment.
lead_source is still using the string-array select shorthand (mixed case + spaces like "Trade Show"). This contradicts the PR’s stated goal of lowercase identifier values and colored option objects. Recommend switching to the object option format and updating seeds to use the new lowercase values.
| amount: Field.currency({ label: 'Amount' }), | ||
| name: Field.text({ label: 'Opportunity Name', required: true, searchable: true, placeholder: 'Enter deal name' }), | ||
| amount: Field.currency({ label: 'Amount', helpText: 'Total deal value in USD' }), | ||
| expected_revenue: Field.currency({ label: 'Expected Revenue', readonly: true, helpText: 'Amount × Probability' }), |
There was a problem hiding this comment.
expected_revenue is marked readonly and documented as “Amount × Probability”, but it’s defined as a plain currency field. This will become stale whenever amount/probability change. Since Field.formula(...) exists in the codebase (see kitchen sink example), consider making this a formula field so the value is actually derived and the example exercises the spec’s computed field capability.
| expected_revenue: Field.currency({ label: 'Expected Revenue', readonly: true, helpText: 'Amount × Probability' }), | |
| expected_revenue: Field.formula('amount * probability', Field.currency({ label: 'Expected Revenue', readonly: true, helpText: 'Amount × Probability' })), |
| payment_method: Field.select(['Credit Card', 'Wire Transfer', 'PayPal', 'Invoice', 'Check'], { label: 'Payment Method' }), | ||
| order_date: Field.date({ label: 'Order Date', defaultValue: 'now' }), |
There was a problem hiding this comment.
payment_method is still using the string-array select shorthand with spaced/capitalized values. If this example is meant to validate spec constraints and exercise colored select options, it should use explicit { value, label, color } options (with lowercase identifier values) and update the seed records accordingly.
…ut type) The @objectstack/spec FieldInput type does not include helpText or placeholder properties, causing TypeScript compilation errors in the console build. Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
Fixed in |
|
21:17:06.089 @object-ui/plugin-dashboard:build: �[96msrc/DashboardRenderer.tsx�[0m:�[93m179�[0m:�[93m41�[0m - �[91merror�[0m�[90m TS7006: �[0mParameter 'action' implicitly has an 'any' type. |
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
|
@copilot Fix all |
✅ Console Performance Budget
📦 Bundle Size Report
Size Limits
|
- plugin-map: rename Map import to MapGL to avoid shadowing global Map - plugin-dashboard: add explicit types for header.actions map params - plugin-charts: add 'combo' key to ChartComponent lookup - plugin-kanban: prefix unused coverImageField with underscore - plugin-grid: prefix unused rIdx with underscore - plugin-form: add null guard for field.type in applyAutoColSpan - plugin-view: cast DraggableAttributes to Record<string, unknown> Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
Original prompt
🔒 GitHub Advanced Security automatically protects Copilot coding agent pull requests. You can protect all pull requests by enabling Advanced Security for your repositories. Learn more about Advanced Security.