Fix CRM example field naming to comply with snake_case convention - #310

Merged
hotlong merged 2 commits into
mainfrom
copilot/fix-ci-build-and-test
Jan 31, 2026
Merged

Fix CRM example field naming to comply with snake_case convention#310
hotlong merged 2 commits into
mainfrom
copilot/fix-ci-build-and-test

Conversation

CopilotAI commented Jan 31, 2026

Copy link
Copy Markdown
Contributor

The ObjectStack compiler enforces snake_case field naming but the CRM example's OpportunityObject used camelCase, causing validation failures:

❌ Validation Failed!
- [objects.2.fields.closeDate] Field names must be lowercase snake_case
- [objects.2.fields.accountId] Field names must be lowercase snake_case
- [objects.2.fields.contactIds] Field names must be lowercase snake_case

Changes

Renamed fields in examples/crm/src/objects/opportunity.object.ts:

  • closeDateclose_date
  • accountIdaccount_id
  • contactIdscontact_ids

Updated corresponding data records in examples/crm/objectstack.config.ts to match new field names.

Original prompt

引用: https://github.com/objectstack-ai/objectui/actions/runs/21549185974/job/62095260658#step:8:1
fix ci build and test


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

@vercel

vercelBot commented Jan 31, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

ProjectDeploymentActionsUpdated (UTC)
objectuiReadyReadyPreview, CommentJan 31, 2026 7:05pm
objectui-componentsReadyReadyPreview, CommentJan 31, 2026 7:05pm
objectui-crm-appReadyReadyPreview, CommentJan 31, 2026 7:05pm

Request Review

Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
CopilotAI changed the title [WIP] Fix CI build and test issuesFix CRM example field naming to comply with snake_case conventionJan 31, 2026
CopilotAI requested a review from hotlongJanuary 31, 2026 18:58
@hotlong
hotlong marked this pull request as ready for review January 31, 2026 19:13
CopilotAI review requested due to automatic review settings January 31, 2026 19:13
@hotlong
hotlong merged commit 2108890 into mainJan 31, 2026
7 checks passed

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Updates the CRM example’s Opportunity object field names to snake_case to satisfy ObjectStack schema validation and prevent CI failures.

Changes:

  • Renamed Opportunity object fields from camelCase to snake_case (close_date, account_id, contact_ids).
  • Updated seeded opportunity records in the CRM example stack config to use the renamed fields.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

FileDescription
examples/crm/src/objects/opportunity.object.tsRenames Opportunity field keys to snake_case to comply with compiler validation rules.
examples/crm/objectstack.config.tsUpdates example opportunity seed data to match the renamed schema fields.

CopilotAI added a commit that referenced this pull request Mar 3, 2026
The useMemo hook was placed after conditional early returns in
RecordDetailView, violating React's Rules of Hooks and causing
"Rendered fewer hooks than expected" (React error #310). Replaced
with an IIFE to keep the same Set-based dedup logic without hooks.
Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
CopilotAI added a commit that referenced this pull request Mar 5, 2026
… React error #310
Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
CopilotAI added a commit that referenced this pull request Mar 5, 2026
…atting to prevent React error #310
Instead of routing highlight values through full CellRenderer components
(which may not handle all data shapes from the API), use direct string
formatting functions (formatCurrency, formatDate, etc.) that guarantee
only primitives reach JSX. All values are coerced through toSafeString()
first, which safely handles MongoDB types, expanded references, arrays
of objects, and other non-primitive values.
Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
CopilotAI added a commit that referenced this pull request Mar 5, 2026
…Highlight to use getCellRenderer
The proper architectural fix for React error #310: instead of working around
unsafe renderers in HeaderHighlight, fix the renderers themselves.
Added coerceToSafeValue() utility in @object-ui/fields that safely coerces
MongoDB wrapper types ($numberDecimal, $oid, $date), expanded reference objects,
arrays, and Date instances to primitive values.
Applied coerceToSafeValue in: NumberCellRenderer, CurrencyCellRenderer,
PercentCellRenderer, TextCellRenderer, EmailCellRenderer, UrlCellRenderer,
PhoneCellRenderer, FormulaCellRenderer, DateCellRenderer, DateTimeCellRenderer.
HeaderHighlight reverted to use getCellRenderer for type-aware rendering,
since all renderers are now safe against non-primitive values.
16 new tests for coerceToSafeValue and cell renderer object safety.
Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
CopilotAI added a commit that referenced this pull request Mar 9, 2026
… error #310
The useMemo hook for detailSchema was placed after conditional early
returns (isLoading / !objectDef), causing an inconsistent hook count
across renders. React error #310 ("Rendered more hooks than during the
previous render") was triggered when transitioning from an early-return
render to a full render.
Move the useMemo before the early returns with a guard clause for
!objectDef inside the callback. All intermediate computation
(primaryField, sections, highlightFields, etc.) is folded into the
useMemo since those variables are only consumed by detailSchema.
Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
os-zhuang pushed a commit that referenced this pull request Jul 5, 2026
os-zhuang pushed a commit that referenced this pull request Sep 2, 2026
A `code` value whose TEXT is JSON rendered as the literal `[Object]`. The
showcase Field Zoo record's Code Editor field (`f_code`) stores the string
`{\n "ok": true\n}` and the detail page showed `[Object]`.
`coerceToSafeValue` parsed any string starting `{`/`[` and ending `}`/`]`,
then ran the result through the reference-label extraction
(`name || label || externalId || id || _id || '[Object]'`). An object carrying
none of those keys answers the placeholder. Every text-like cell reaches this
helper — `text`, `textarea`, `code`, `time`, `auto_number` and `qrcode` all
register to `TextCellRenderer` — so all of them lost JSON-shaped text, and
`[1, 2, 3]` in a text field rendered as `1, 2, 3`.
Shape is not a type. A string is now returned verbatim. The reference case the
parse was written for (#1426, an unresolved external-id ref arriving as
`'{"externalId":"…"}'`) belongs to reference-TYPED columns and already lives
there: `LookupCellRenderer` carries its own JSON-string branch that resolves the
label through the referenced object's schema and links to the record — neither
of which the type-blind helper could do. Scoped, not dropped.
Object and array VALUES still coerce, so React error #310 stays fixed.
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@hotlong
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Fix CRM example field naming to comply with snake_case convention - #310

Merged
hotlong merged 2 commits into
mainfrom
copilot/fix-ci-build-and-test
Jan 31, 2026
Merged

Fix CRM example field naming to comply with snake_case convention#310
hotlong merged 2 commits into
mainfrom
copilot/fix-ci-build-and-test

Conversation

CopilotAI commented Jan 31, 2026

Copy link
Copy Markdown
Contributor

The ObjectStack compiler enforces snake_case field naming but the CRM example's OpportunityObject used camelCase, causing validation failures:

❌ Validation Failed!
- [objects.2.fields.closeDate] Field names must be lowercase snake_case
- [objects.2.fields.accountId] Field names must be lowercase snake_case
- [objects.2.fields.contactIds] Field names must be lowercase snake_case

Changes

Renamed fields in examples/crm/src/objects/opportunity.object.ts:

  • closeDateclose_date
  • accountIdaccount_id
  • contactIdscontact_ids

Updated corresponding data records in examples/crm/objectstack.config.ts to match new field names.

Original prompt

引用: https://github.com/objectstack-ai/objectui/actions/runs/21549185974/job/62095260658#step:8:1
fix ci build and test


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

@vercel

vercelBot commented Jan 31, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

ProjectDeploymentActionsUpdated (UTC)
objectuiReadyReadyPreview, CommentJan 31, 2026 7:05pm
objectui-componentsReadyReadyPreview, CommentJan 31, 2026 7:05pm
objectui-crm-appReadyReadyPreview, CommentJan 31, 2026 7:05pm

Request Review

Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
CopilotAI changed the title [WIP] Fix CI build and test issuesFix CRM example field naming to comply with snake_case conventionJan 31, 2026
CopilotAI requested a review from hotlongJanuary 31, 2026 18:58
@hotlong
hotlong marked this pull request as ready for review January 31, 2026 19:13
CopilotAI review requested due to automatic review settings January 31, 2026 19:13
@hotlong
hotlong merged commit 2108890 into mainJan 31, 2026
7 checks passed

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Updates the CRM example’s Opportunity object field names to snake_case to satisfy ObjectStack schema validation and prevent CI failures.

Changes:

  • Renamed Opportunity object fields from camelCase to snake_case (close_date, account_id, contact_ids).
  • Updated seeded opportunity records in the CRM example stack config to use the renamed fields.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

FileDescription
examples/crm/src/objects/opportunity.object.tsRenames Opportunity field keys to snake_case to comply with compiler validation rules.
examples/crm/objectstack.config.tsUpdates example opportunity seed data to match the renamed schema fields.

CopilotAI added a commit that referenced this pull request Mar 3, 2026
The useMemo hook was placed after conditional early returns in
RecordDetailView, violating React's Rules of Hooks and causing
"Rendered fewer hooks than expected" (React error #310). Replaced
with an IIFE to keep the same Set-based dedup logic without hooks.
Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
CopilotAI added a commit that referenced this pull request Mar 5, 2026
… React error #310
Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
CopilotAI added a commit that referenced this pull request Mar 5, 2026
…atting to prevent React error #310
Instead of routing highlight values through full CellRenderer components
(which may not handle all data shapes from the API), use direct string
formatting functions (formatCurrency, formatDate, etc.) that guarantee
only primitives reach JSX. All values are coerced through toSafeString()
first, which safely handles MongoDB types, expanded references, arrays
of objects, and other non-primitive values.
Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
CopilotAI added a commit that referenced this pull request Mar 5, 2026
…Highlight to use getCellRenderer
The proper architectural fix for React error #310: instead of working around
unsafe renderers in HeaderHighlight, fix the renderers themselves.
Added coerceToSafeValue() utility in @object-ui/fields that safely coerces
MongoDB wrapper types ($numberDecimal, $oid, $date), expanded reference objects,
arrays, and Date instances to primitive values.
Applied coerceToSafeValue in: NumberCellRenderer, CurrencyCellRenderer,
PercentCellRenderer, TextCellRenderer, EmailCellRenderer, UrlCellRenderer,
PhoneCellRenderer, FormulaCellRenderer, DateCellRenderer, DateTimeCellRenderer.
HeaderHighlight reverted to use getCellRenderer for type-aware rendering,
since all renderers are now safe against non-primitive values.
16 new tests for coerceToSafeValue and cell renderer object safety.
Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
CopilotAI added a commit that referenced this pull request Mar 9, 2026
… error #310
The useMemo hook for detailSchema was placed after conditional early
returns (isLoading / !objectDef), causing an inconsistent hook count
across renders. React error #310 ("Rendered more hooks than during the
previous render") was triggered when transitioning from an early-return
render to a full render.
Move the useMemo before the early returns with a guard clause for
!objectDef inside the callback. All intermediate computation
(primaryField, sections, highlightFields, etc.) is folded into the
useMemo since those variables are only consumed by detailSchema.
Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
os-zhuang pushed a commit that referenced this pull request Jul 5, 2026
os-zhuang pushed a commit that referenced this pull request Sep 2, 2026
A `code` value whose TEXT is JSON rendered as the literal `[Object]`. The
showcase Field Zoo record's Code Editor field (`f_code`) stores the string
`{\n "ok": true\n}` and the detail page showed `[Object]`.
`coerceToSafeValue` parsed any string starting `{`/`[` and ending `}`/`]`,
then ran the result through the reference-label extraction
(`name || label || externalId || id || _id || '[Object]'`). An object carrying
none of those keys answers the placeholder. Every text-like cell reaches this
helper — `text`, `textarea`, `code`, `time`, `auto_number` and `qrcode` all
register to `TextCellRenderer` — so all of them lost JSON-shaped text, and
`[1, 2, 3]` in a text field rendered as `1, 2, 3`.
Shape is not a type. A string is now returned verbatim. The reference case the
parse was written for (#1426, an unresolved external-id ref arriving as
`'{"externalId":"…"}'`) belongs to reference-TYPED columns and already lives
there: `LookupCellRenderer` carries its own JSON-string branch that resolves the
label through the referenced object's schema and links to the record — neither
of which the type-blind helper could do. Scoped, not dropped.
Object and array VALUES still coerce, so React error #310 stays fixed.
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@hotlong
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Fix CRM example field naming to comply with snake_case convention - #310

Merged
hotlong merged 2 commits into
mainfrom
copilot/fix-ci-build-and-test
Jan 31, 2026
Merged

Fix CRM example field naming to comply with snake_case convention#310
hotlong merged 2 commits into
mainfrom
copilot/fix-ci-build-and-test

Conversation

CopilotAI commented Jan 31, 2026

Copy link
Copy Markdown
Contributor

The ObjectStack compiler enforces snake_case field naming but the CRM example's OpportunityObject used camelCase, causing validation failures:

❌ Validation Failed!
- [objects.2.fields.closeDate] Field names must be lowercase snake_case
- [objects.2.fields.accountId] Field names must be lowercase snake_case
- [objects.2.fields.contactIds] Field names must be lowercase snake_case

Changes

Renamed fields in examples/crm/src/objects/opportunity.object.ts:

  • closeDateclose_date
  • accountIdaccount_id
  • contactIdscontact_ids

Updated corresponding data records in examples/crm/objectstack.config.ts to match new field names.

Original prompt

引用: https://github.com/objectstack-ai/objectui/actions/runs/21549185974/job/62095260658#step:8:1
fix ci build and test


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

@vercel

vercelBot commented Jan 31, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

ProjectDeploymentActionsUpdated (UTC)
objectuiReadyReadyPreview, CommentJan 31, 2026 7:05pm
objectui-componentsReadyReadyPreview, CommentJan 31, 2026 7:05pm
objectui-crm-appReadyReadyPreview, CommentJan 31, 2026 7:05pm

Request Review

Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
CopilotAI changed the title [WIP] Fix CI build and test issuesFix CRM example field naming to comply with snake_case conventionJan 31, 2026
CopilotAI requested a review from hotlongJanuary 31, 2026 18:58
@hotlong
hotlong marked this pull request as ready for review January 31, 2026 19:13
CopilotAI review requested due to automatic review settings January 31, 2026 19:13
@hotlong
hotlong merged commit 2108890 into mainJan 31, 2026
7 checks passed

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Updates the CRM example’s Opportunity object field names to snake_case to satisfy ObjectStack schema validation and prevent CI failures.

Changes:

  • Renamed Opportunity object fields from camelCase to snake_case (close_date, account_id, contact_ids).
  • Updated seeded opportunity records in the CRM example stack config to use the renamed fields.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

FileDescription
examples/crm/src/objects/opportunity.object.tsRenames Opportunity field keys to snake_case to comply with compiler validation rules.
examples/crm/objectstack.config.tsUpdates example opportunity seed data to match the renamed schema fields.

CopilotAI added a commit that referenced this pull request Mar 3, 2026
The useMemo hook was placed after conditional early returns in
RecordDetailView, violating React's Rules of Hooks and causing
"Rendered fewer hooks than expected" (React error #310). Replaced
with an IIFE to keep the same Set-based dedup logic without hooks.
Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
CopilotAI added a commit that referenced this pull request Mar 5, 2026
… React error #310
Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
CopilotAI added a commit that referenced this pull request Mar 5, 2026
…atting to prevent React error #310
Instead of routing highlight values through full CellRenderer components
(which may not handle all data shapes from the API), use direct string
formatting functions (formatCurrency, formatDate, etc.) that guarantee
only primitives reach JSX. All values are coerced through toSafeString()
first, which safely handles MongoDB types, expanded references, arrays
of objects, and other non-primitive values.
Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
CopilotAI added a commit that referenced this pull request Mar 5, 2026
…Highlight to use getCellRenderer
The proper architectural fix for React error #310: instead of working around
unsafe renderers in HeaderHighlight, fix the renderers themselves.
Added coerceToSafeValue() utility in @object-ui/fields that safely coerces
MongoDB wrapper types ($numberDecimal, $oid, $date), expanded reference objects,
arrays, and Date instances to primitive values.
Applied coerceToSafeValue in: NumberCellRenderer, CurrencyCellRenderer,
PercentCellRenderer, TextCellRenderer, EmailCellRenderer, UrlCellRenderer,
PhoneCellRenderer, FormulaCellRenderer, DateCellRenderer, DateTimeCellRenderer.
HeaderHighlight reverted to use getCellRenderer for type-aware rendering,
since all renderers are now safe against non-primitive values.
16 new tests for coerceToSafeValue and cell renderer object safety.
Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
CopilotAI added a commit that referenced this pull request Mar 9, 2026
… error #310
The useMemo hook for detailSchema was placed after conditional early
returns (isLoading / !objectDef), causing an inconsistent hook count
across renders. React error #310 ("Rendered more hooks than during the
previous render") was triggered when transitioning from an early-return
render to a full render.
Move the useMemo before the early returns with a guard clause for
!objectDef inside the callback. All intermediate computation
(primaryField, sections, highlightFields, etc.) is folded into the
useMemo since those variables are only consumed by detailSchema.
Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
os-zhuang pushed a commit that referenced this pull request Jul 5, 2026
os-zhuang pushed a commit that referenced this pull request Sep 2, 2026
A `code` value whose TEXT is JSON rendered as the literal `[Object]`. The
showcase Field Zoo record's Code Editor field (`f_code`) stores the string
`{\n "ok": true\n}` and the detail page showed `[Object]`.
`coerceToSafeValue` parsed any string starting `{`/`[` and ending `}`/`]`,
then ran the result through the reference-label extraction
(`name || label || externalId || id || _id || '[Object]'`). An object carrying
none of those keys answers the placeholder. Every text-like cell reaches this
helper — `text`, `textarea`, `code`, `time`, `auto_number` and `qrcode` all
register to `TextCellRenderer` — so all of them lost JSON-shaped text, and
`[1, 2, 3]` in a text field rendered as `1, 2, 3`.
Shape is not a type. A string is now returned verbatim. The reference case the
parse was written for (#1426, an unresolved external-id ref arriving as
`'{"externalId":"…"}'`) belongs to reference-TYPED columns and already lives
there: `LookupCellRenderer` carries its own JSON-string branch that resolves the
label through the referenced object's schema and links to the record — neither
of which the type-blind helper could do. Scoped, not dropped.
Object and array VALUES still coerce, so React error #310 stays fixed.
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@hotlong
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Fix CRM example field naming to comply with snake_case convention - #310

Merged
hotlong merged 2 commits into
mainfrom
copilot/fix-ci-build-and-test
Jan 31, 2026
Merged

Fix CRM example field naming to comply with snake_case convention#310
hotlong merged 2 commits into
mainfrom
copilot/fix-ci-build-and-test

Conversation

CopilotAI commented Jan 31, 2026

Copy link
Copy Markdown
Contributor

The ObjectStack compiler enforces snake_case field naming but the CRM example's OpportunityObject used camelCase, causing validation failures:

❌ Validation Failed!
- [objects.2.fields.closeDate] Field names must be lowercase snake_case
- [objects.2.fields.accountId] Field names must be lowercase snake_case
- [objects.2.fields.contactIds] Field names must be lowercase snake_case

Changes

Renamed fields in examples/crm/src/objects/opportunity.object.ts:

  • closeDateclose_date
  • accountIdaccount_id
  • contactIdscontact_ids

Updated corresponding data records in examples/crm/objectstack.config.ts to match new field names.

Original prompt

引用: https://github.com/objectstack-ai/objectui/actions/runs/21549185974/job/62095260658#step:8:1
fix ci build and test


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

@vercel

vercelBot commented Jan 31, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

ProjectDeploymentActionsUpdated (UTC)
objectuiReadyReadyPreview, CommentJan 31, 2026 7:05pm
objectui-componentsReadyReadyPreview, CommentJan 31, 2026 7:05pm
objectui-crm-appReadyReadyPreview, CommentJan 31, 2026 7:05pm

Request Review

Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
CopilotAI changed the title [WIP] Fix CI build and test issuesFix CRM example field naming to comply with snake_case conventionJan 31, 2026
CopilotAI requested a review from hotlongJanuary 31, 2026 18:58
@hotlong
hotlong marked this pull request as ready for review January 31, 2026 19:13
CopilotAI review requested due to automatic review settings January 31, 2026 19:13
@hotlong
hotlong merged commit 2108890 into mainJan 31, 2026
7 checks passed

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Updates the CRM example’s Opportunity object field names to snake_case to satisfy ObjectStack schema validation and prevent CI failures.

Changes:

  • Renamed Opportunity object fields from camelCase to snake_case (close_date, account_id, contact_ids).
  • Updated seeded opportunity records in the CRM example stack config to use the renamed fields.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

FileDescription
examples/crm/src/objects/opportunity.object.tsRenames Opportunity field keys to snake_case to comply with compiler validation rules.
examples/crm/objectstack.config.tsUpdates example opportunity seed data to match the renamed schema fields.

CopilotAI added a commit that referenced this pull request Mar 3, 2026
The useMemo hook was placed after conditional early returns in
RecordDetailView, violating React's Rules of Hooks and causing
"Rendered fewer hooks than expected" (React error #310). Replaced
with an IIFE to keep the same Set-based dedup logic without hooks.
Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
CopilotAI added a commit that referenced this pull request Mar 5, 2026
… React error #310
Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
CopilotAI added a commit that referenced this pull request Mar 5, 2026
…atting to prevent React error #310
Instead of routing highlight values through full CellRenderer components
(which may not handle all data shapes from the API), use direct string
formatting functions (formatCurrency, formatDate, etc.) that guarantee
only primitives reach JSX. All values are coerced through toSafeString()
first, which safely handles MongoDB types, expanded references, arrays
of objects, and other non-primitive values.
Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
CopilotAI added a commit that referenced this pull request Mar 5, 2026
…Highlight to use getCellRenderer
The proper architectural fix for React error #310: instead of working around
unsafe renderers in HeaderHighlight, fix the renderers themselves.
Added coerceToSafeValue() utility in @object-ui/fields that safely coerces
MongoDB wrapper types ($numberDecimal, $oid, $date), expanded reference objects,
arrays, and Date instances to primitive values.
Applied coerceToSafeValue in: NumberCellRenderer, CurrencyCellRenderer,
PercentCellRenderer, TextCellRenderer, EmailCellRenderer, UrlCellRenderer,
PhoneCellRenderer, FormulaCellRenderer, DateCellRenderer, DateTimeCellRenderer.
HeaderHighlight reverted to use getCellRenderer for type-aware rendering,
since all renderers are now safe against non-primitive values.
16 new tests for coerceToSafeValue and cell renderer object safety.
Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
CopilotAI added a commit that referenced this pull request Mar 9, 2026
… error #310
The useMemo hook for detailSchema was placed after conditional early
returns (isLoading / !objectDef), causing an inconsistent hook count
across renders. React error #310 ("Rendered more hooks than during the
previous render") was triggered when transitioning from an early-return
render to a full render.
Move the useMemo before the early returns with a guard clause for
!objectDef inside the callback. All intermediate computation
(primaryField, sections, highlightFields, etc.) is folded into the
useMemo since those variables are only consumed by detailSchema.
Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
os-zhuang pushed a commit that referenced this pull request Jul 5, 2026
os-zhuang pushed a commit that referenced this pull request Sep 2, 2026
A `code` value whose TEXT is JSON rendered as the literal `[Object]`. The
showcase Field Zoo record's Code Editor field (`f_code`) stores the string
`{\n "ok": true\n}` and the detail page showed `[Object]`.
`coerceToSafeValue` parsed any string starting `{`/`[` and ending `}`/`]`,
then ran the result through the reference-label extraction
(`name || label || externalId || id || _id || '[Object]'`). An object carrying
none of those keys answers the placeholder. Every text-like cell reaches this
helper — `text`, `textarea`, `code`, `time`, `auto_number` and `qrcode` all
register to `TextCellRenderer` — so all of them lost JSON-shaped text, and
`[1, 2, 3]` in a text field rendered as `1, 2, 3`.
Shape is not a type. A string is now returned verbatim. The reference case the
parse was written for (#1426, an unresolved external-id ref arriving as
`'{"externalId":"…"}'`) belongs to reference-TYPED columns and already lives
there: `LookupCellRenderer` carries its own JSON-string branch that resolves the
label through the referenced object's schema and links to the record — neither
of which the type-blind helper could do. Scoped, not dropped.
Object and array VALUES still coerce, so React error #310 stays fixed.
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@hotlong
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Fix CRM example field naming to comply with snake_case convention - #310

Merged
hotlong merged 2 commits into
mainfrom
copilot/fix-ci-build-and-test
Jan 31, 2026
Merged

Fix CRM example field naming to comply with snake_case convention#310
hotlong merged 2 commits into
mainfrom
copilot/fix-ci-build-and-test

Conversation

CopilotAI commented Jan 31, 2026

Copy link
Copy Markdown
Contributor

The ObjectStack compiler enforces snake_case field naming but the CRM example's OpportunityObject used camelCase, causing validation failures:

❌ Validation Failed!
- [objects.2.fields.closeDate] Field names must be lowercase snake_case
- [objects.2.fields.accountId] Field names must be lowercase snake_case
- [objects.2.fields.contactIds] Field names must be lowercase snake_case

Changes

Renamed fields in examples/crm/src/objects/opportunity.object.ts:

  • closeDateclose_date
  • accountIdaccount_id
  • contactIdscontact_ids

Updated corresponding data records in examples/crm/objectstack.config.ts to match new field names.

Original prompt

引用: https://github.com/objectstack-ai/objectui/actions/runs/21549185974/job/62095260658#step:8:1
fix ci build and test


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

@vercel

vercelBot commented Jan 31, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

ProjectDeploymentActionsUpdated (UTC)
objectuiReadyReadyPreview, CommentJan 31, 2026 7:05pm
objectui-componentsReadyReadyPreview, CommentJan 31, 2026 7:05pm
objectui-crm-appReadyReadyPreview, CommentJan 31, 2026 7:05pm

Request Review

Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
CopilotAI changed the title [WIP] Fix CI build and test issuesFix CRM example field naming to comply with snake_case conventionJan 31, 2026
CopilotAI requested a review from hotlongJanuary 31, 2026 18:58
@hotlong
hotlong marked this pull request as ready for review January 31, 2026 19:13
CopilotAI review requested due to automatic review settings January 31, 2026 19:13
@hotlong
hotlong merged commit 2108890 into mainJan 31, 2026
7 checks passed

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Updates the CRM example’s Opportunity object field names to snake_case to satisfy ObjectStack schema validation and prevent CI failures.

Changes:

  • Renamed Opportunity object fields from camelCase to snake_case (close_date, account_id, contact_ids).
  • Updated seeded opportunity records in the CRM example stack config to use the renamed fields.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

FileDescription
examples/crm/src/objects/opportunity.object.tsRenames Opportunity field keys to snake_case to comply with compiler validation rules.
examples/crm/objectstack.config.tsUpdates example opportunity seed data to match the renamed schema fields.

CopilotAI added a commit that referenced this pull request Mar 3, 2026
The useMemo hook was placed after conditional early returns in
RecordDetailView, violating React's Rules of Hooks and causing
"Rendered fewer hooks than expected" (React error #310). Replaced
with an IIFE to keep the same Set-based dedup logic without hooks.
Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
CopilotAI added a commit that referenced this pull request Mar 5, 2026
… React error #310
Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
CopilotAI added a commit that referenced this pull request Mar 5, 2026
…atting to prevent React error #310
Instead of routing highlight values through full CellRenderer components
(which may not handle all data shapes from the API), use direct string
formatting functions (formatCurrency, formatDate, etc.) that guarantee
only primitives reach JSX. All values are coerced through toSafeString()
first, which safely handles MongoDB types, expanded references, arrays
of objects, and other non-primitive values.
Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
CopilotAI added a commit that referenced this pull request Mar 5, 2026
…Highlight to use getCellRenderer
The proper architectural fix for React error #310: instead of working around
unsafe renderers in HeaderHighlight, fix the renderers themselves.
Added coerceToSafeValue() utility in @object-ui/fields that safely coerces
MongoDB wrapper types ($numberDecimal, $oid, $date), expanded reference objects,
arrays, and Date instances to primitive values.
Applied coerceToSafeValue in: NumberCellRenderer, CurrencyCellRenderer,
PercentCellRenderer, TextCellRenderer, EmailCellRenderer, UrlCellRenderer,
PhoneCellRenderer, FormulaCellRenderer, DateCellRenderer, DateTimeCellRenderer.
HeaderHighlight reverted to use getCellRenderer for type-aware rendering,
since all renderers are now safe against non-primitive values.
16 new tests for coerceToSafeValue and cell renderer object safety.
Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
CopilotAI added a commit that referenced this pull request Mar 9, 2026
… error #310
The useMemo hook for detailSchema was placed after conditional early
returns (isLoading / !objectDef), causing an inconsistent hook count
across renders. React error #310 ("Rendered more hooks than during the
previous render") was triggered when transitioning from an early-return
render to a full render.
Move the useMemo before the early returns with a guard clause for
!objectDef inside the callback. All intermediate computation
(primaryField, sections, highlightFields, etc.) is folded into the
useMemo since those variables are only consumed by detailSchema.
Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
os-zhuang pushed a commit that referenced this pull request Jul 5, 2026
os-zhuang pushed a commit that referenced this pull request Sep 2, 2026
A `code` value whose TEXT is JSON rendered as the literal `[Object]`. The
showcase Field Zoo record's Code Editor field (`f_code`) stores the string
`{\n "ok": true\n}` and the detail page showed `[Object]`.
`coerceToSafeValue` parsed any string starting `{`/`[` and ending `}`/`]`,
then ran the result through the reference-label extraction
(`name || label || externalId || id || _id || '[Object]'`). An object carrying
none of those keys answers the placeholder. Every text-like cell reaches this
helper — `text`, `textarea`, `code`, `time`, `auto_number` and `qrcode` all
register to `TextCellRenderer` — so all of them lost JSON-shaped text, and
`[1, 2, 3]` in a text field rendered as `1, 2, 3`.
Shape is not a type. A string is now returned verbatim. The reference case the
parse was written for (#1426, an unresolved external-id ref arriving as
`'{"externalId":"…"}'`) belongs to reference-TYPED columns and already lives
there: `LookupCellRenderer` carries its own JSON-string branch that resolves the
label through the referenced object's schema and links to the record — neither
of which the type-blind helper could do. Scoped, not dropped.
Object and array VALUES still coerce, so React error #310 stays fixed.
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@hotlong
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Fix CRM example field naming to comply with snake_case convention - #310

Merged
hotlong merged 2 commits into
mainfrom
copilot/fix-ci-build-and-test
Jan 31, 2026
Merged

Fix CRM example field naming to comply with snake_case convention#310
hotlong merged 2 commits into
mainfrom
copilot/fix-ci-build-and-test

Conversation

CopilotAI commented Jan 31, 2026

Copy link
Copy Markdown
Contributor

The ObjectStack compiler enforces snake_case field naming but the CRM example's OpportunityObject used camelCase, causing validation failures:

❌ Validation Failed!
- [objects.2.fields.closeDate] Field names must be lowercase snake_case
- [objects.2.fields.accountId] Field names must be lowercase snake_case
- [objects.2.fields.contactIds] Field names must be lowercase snake_case

Changes

Renamed fields in examples/crm/src/objects/opportunity.object.ts:

  • closeDateclose_date
  • accountIdaccount_id
  • contactIdscontact_ids

Updated corresponding data records in examples/crm/objectstack.config.ts to match new field names.

Original prompt

引用: https://github.com/objectstack-ai/objectui/actions/runs/21549185974/job/62095260658#step:8:1
fix ci build and test


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

@vercel

vercelBot commented Jan 31, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

ProjectDeploymentActionsUpdated (UTC)
objectuiReadyReadyPreview, CommentJan 31, 2026 7:05pm
objectui-componentsReadyReadyPreview, CommentJan 31, 2026 7:05pm
objectui-crm-appReadyReadyPreview, CommentJan 31, 2026 7:05pm

Request Review

Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
CopilotAI changed the title [WIP] Fix CI build and test issuesFix CRM example field naming to comply with snake_case conventionJan 31, 2026
CopilotAI requested a review from hotlongJanuary 31, 2026 18:58
@hotlong
hotlong marked this pull request as ready for review January 31, 2026 19:13
CopilotAI review requested due to automatic review settings January 31, 2026 19:13
@hotlong
hotlong merged commit 2108890 into mainJan 31, 2026
7 checks passed

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Updates the CRM example’s Opportunity object field names to snake_case to satisfy ObjectStack schema validation and prevent CI failures.

Changes:

  • Renamed Opportunity object fields from camelCase to snake_case (close_date, account_id, contact_ids).
  • Updated seeded opportunity records in the CRM example stack config to use the renamed fields.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

FileDescription
examples/crm/src/objects/opportunity.object.tsRenames Opportunity field keys to snake_case to comply with compiler validation rules.
examples/crm/objectstack.config.tsUpdates example opportunity seed data to match the renamed schema fields.

CopilotAI added a commit that referenced this pull request Mar 3, 2026
The useMemo hook was placed after conditional early returns in
RecordDetailView, violating React's Rules of Hooks and causing
"Rendered fewer hooks than expected" (React error #310). Replaced
with an IIFE to keep the same Set-based dedup logic without hooks.
Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
CopilotAI added a commit that referenced this pull request Mar 5, 2026
… React error #310
Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
CopilotAI added a commit that referenced this pull request Mar 5, 2026
…atting to prevent React error #310
Instead of routing highlight values through full CellRenderer components
(which may not handle all data shapes from the API), use direct string
formatting functions (formatCurrency, formatDate, etc.) that guarantee
only primitives reach JSX. All values are coerced through toSafeString()
first, which safely handles MongoDB types, expanded references, arrays
of objects, and other non-primitive values.
Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
CopilotAI added a commit that referenced this pull request Mar 5, 2026
…Highlight to use getCellRenderer
The proper architectural fix for React error #310: instead of working around
unsafe renderers in HeaderHighlight, fix the renderers themselves.
Added coerceToSafeValue() utility in @object-ui/fields that safely coerces
MongoDB wrapper types ($numberDecimal, $oid, $date), expanded reference objects,
arrays, and Date instances to primitive values.
Applied coerceToSafeValue in: NumberCellRenderer, CurrencyCellRenderer,
PercentCellRenderer, TextCellRenderer, EmailCellRenderer, UrlCellRenderer,
PhoneCellRenderer, FormulaCellRenderer, DateCellRenderer, DateTimeCellRenderer.
HeaderHighlight reverted to use getCellRenderer for type-aware rendering,
since all renderers are now safe against non-primitive values.
16 new tests for coerceToSafeValue and cell renderer object safety.
Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
CopilotAI added a commit that referenced this pull request Mar 9, 2026
… error #310
The useMemo hook for detailSchema was placed after conditional early
returns (isLoading / !objectDef), causing an inconsistent hook count
across renders. React error #310 ("Rendered more hooks than during the
previous render") was triggered when transitioning from an early-return
render to a full render.
Move the useMemo before the early returns with a guard clause for
!objectDef inside the callback. All intermediate computation
(primaryField, sections, highlightFields, etc.) is folded into the
useMemo since those variables are only consumed by detailSchema.
Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
os-zhuang pushed a commit that referenced this pull request Jul 5, 2026
os-zhuang pushed a commit that referenced this pull request Sep 2, 2026
A `code` value whose TEXT is JSON rendered as the literal `[Object]`. The
showcase Field Zoo record's Code Editor field (`f_code`) stores the string
`{\n "ok": true\n}` and the detail page showed `[Object]`.
`coerceToSafeValue` parsed any string starting `{`/`[` and ending `}`/`]`,
then ran the result through the reference-label extraction
(`name || label || externalId || id || _id || '[Object]'`). An object carrying
none of those keys answers the placeholder. Every text-like cell reaches this
helper — `text`, `textarea`, `code`, `time`, `auto_number` and `qrcode` all
register to `TextCellRenderer` — so all of them lost JSON-shaped text, and
`[1, 2, 3]` in a text field rendered as `1, 2, 3`.
Shape is not a type. A string is now returned verbatim. The reference case the
parse was written for (#1426, an unresolved external-id ref arriving as
`'{"externalId":"…"}'`) belongs to reference-TYPED columns and already lives
there: `LookupCellRenderer` carries its own JSON-string branch that resolves the
label through the referenced object's schema and links to the record — neither
of which the type-blind helper could do. Scoped, not dropped.
Object and array VALUES still coerce, so React error #310 stays fixed.
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@hotlong
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Fix CRM example field naming to comply with snake_case convention - #310

Merged
hotlong merged 2 commits into
mainfrom
copilot/fix-ci-build-and-test
Jan 31, 2026
Merged

Fix CRM example field naming to comply with snake_case convention#310
hotlong merged 2 commits into
mainfrom
copilot/fix-ci-build-and-test

Conversation

CopilotAI commented Jan 31, 2026

Copy link
Copy Markdown
Contributor

The ObjectStack compiler enforces snake_case field naming but the CRM example's OpportunityObject used camelCase, causing validation failures:

❌ Validation Failed!
- [objects.2.fields.closeDate] Field names must be lowercase snake_case
- [objects.2.fields.accountId] Field names must be lowercase snake_case
- [objects.2.fields.contactIds] Field names must be lowercase snake_case

Changes

Renamed fields in examples/crm/src/objects/opportunity.object.ts:

  • closeDateclose_date
  • accountIdaccount_id
  • contactIdscontact_ids

Updated corresponding data records in examples/crm/objectstack.config.ts to match new field names.

Original prompt

引用: https://github.com/objectstack-ai/objectui/actions/runs/21549185974/job/62095260658#step:8:1
fix ci build and test


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

@vercel

vercelBot commented Jan 31, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

ProjectDeploymentActionsUpdated (UTC)
objectuiReadyReadyPreview, CommentJan 31, 2026 7:05pm
objectui-componentsReadyReadyPreview, CommentJan 31, 2026 7:05pm
objectui-crm-appReadyReadyPreview, CommentJan 31, 2026 7:05pm

Request Review

Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
CopilotAI changed the title [WIP] Fix CI build and test issuesFix CRM example field naming to comply with snake_case conventionJan 31, 2026
CopilotAI requested a review from hotlongJanuary 31, 2026 18:58
@hotlong
hotlong marked this pull request as ready for review January 31, 2026 19:13
CopilotAI review requested due to automatic review settings January 31, 2026 19:13
@hotlong
hotlong merged commit 2108890 into mainJan 31, 2026
7 checks passed

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Updates the CRM example’s Opportunity object field names to snake_case to satisfy ObjectStack schema validation and prevent CI failures.

Changes:

  • Renamed Opportunity object fields from camelCase to snake_case (close_date, account_id, contact_ids).
  • Updated seeded opportunity records in the CRM example stack config to use the renamed fields.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

FileDescription
examples/crm/src/objects/opportunity.object.tsRenames Opportunity field keys to snake_case to comply with compiler validation rules.
examples/crm/objectstack.config.tsUpdates example opportunity seed data to match the renamed schema fields.

CopilotAI added a commit that referenced this pull request Mar 3, 2026
The useMemo hook was placed after conditional early returns in
RecordDetailView, violating React's Rules of Hooks and causing
"Rendered fewer hooks than expected" (React error #310). Replaced
with an IIFE to keep the same Set-based dedup logic without hooks.
Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
CopilotAI added a commit that referenced this pull request Mar 5, 2026
… React error #310
Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
CopilotAI added a commit that referenced this pull request Mar 5, 2026
…atting to prevent React error #310
Instead of routing highlight values through full CellRenderer components
(which may not handle all data shapes from the API), use direct string
formatting functions (formatCurrency, formatDate, etc.) that guarantee
only primitives reach JSX. All values are coerced through toSafeString()
first, which safely handles MongoDB types, expanded references, arrays
of objects, and other non-primitive values.
Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
CopilotAI added a commit that referenced this pull request Mar 5, 2026
…Highlight to use getCellRenderer
The proper architectural fix for React error #310: instead of working around
unsafe renderers in HeaderHighlight, fix the renderers themselves.
Added coerceToSafeValue() utility in @object-ui/fields that safely coerces
MongoDB wrapper types ($numberDecimal, $oid, $date), expanded reference objects,
arrays, and Date instances to primitive values.
Applied coerceToSafeValue in: NumberCellRenderer, CurrencyCellRenderer,
PercentCellRenderer, TextCellRenderer, EmailCellRenderer, UrlCellRenderer,
PhoneCellRenderer, FormulaCellRenderer, DateCellRenderer, DateTimeCellRenderer.
HeaderHighlight reverted to use getCellRenderer for type-aware rendering,
since all renderers are now safe against non-primitive values.
16 new tests for coerceToSafeValue and cell renderer object safety.
Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
CopilotAI added a commit that referenced this pull request Mar 9, 2026
… error #310
The useMemo hook for detailSchema was placed after conditional early
returns (isLoading / !objectDef), causing an inconsistent hook count
across renders. React error #310 ("Rendered more hooks than during the
previous render") was triggered when transitioning from an early-return
render to a full render.
Move the useMemo before the early returns with a guard clause for
!objectDef inside the callback. All intermediate computation
(primaryField, sections, highlightFields, etc.) is folded into the
useMemo since those variables are only consumed by detailSchema.
Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
os-zhuang pushed a commit that referenced this pull request Jul 5, 2026
os-zhuang pushed a commit that referenced this pull request Sep 2, 2026
A `code` value whose TEXT is JSON rendered as the literal `[Object]`. The
showcase Field Zoo record's Code Editor field (`f_code`) stores the string
`{\n "ok": true\n}` and the detail page showed `[Object]`.
`coerceToSafeValue` parsed any string starting `{`/`[` and ending `}`/`]`,
then ran the result through the reference-label extraction
(`name || label || externalId || id || _id || '[Object]'`). An object carrying
none of those keys answers the placeholder. Every text-like cell reaches this
helper — `text`, `textarea`, `code`, `time`, `auto_number` and `qrcode` all
register to `TextCellRenderer` — so all of them lost JSON-shaped text, and
`[1, 2, 3]` in a text field rendered as `1, 2, 3`.
Shape is not a type. A string is now returned verbatim. The reference case the
parse was written for (#1426, an unresolved external-id ref arriving as
`'{"externalId":"…"}'`) belongs to reference-TYPED columns and already lives
there: `LookupCellRenderer` carries its own JSON-string branch that resolves the
label through the referenced object's schema and links to the record — neither
of which the type-blind helper could do. Scoped, not dropped.
Object and array VALUES still coerce, so React error #310 stays fixed.
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@hotlong
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Fix CRM example field naming to comply with snake_case convention - #310

Merged
hotlong merged 2 commits into
mainfrom
copilot/fix-ci-build-and-test
Jan 31, 2026
Merged

Fix CRM example field naming to comply with snake_case convention#310
hotlong merged 2 commits into
mainfrom
copilot/fix-ci-build-and-test

Conversation

CopilotAI commented Jan 31, 2026

Copy link
Copy Markdown
Contributor

The ObjectStack compiler enforces snake_case field naming but the CRM example's OpportunityObject used camelCase, causing validation failures:

❌ Validation Failed!
- [objects.2.fields.closeDate] Field names must be lowercase snake_case
- [objects.2.fields.accountId] Field names must be lowercase snake_case
- [objects.2.fields.contactIds] Field names must be lowercase snake_case

Changes

Renamed fields in examples/crm/src/objects/opportunity.object.ts:

  • closeDateclose_date
  • accountIdaccount_id
  • contactIdscontact_ids

Updated corresponding data records in examples/crm/objectstack.config.ts to match new field names.

Original prompt

引用: https://github.com/objectstack-ai/objectui/actions/runs/21549185974/job/62095260658#step:8:1
fix ci build and test


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

@vercel

vercelBot commented Jan 31, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

ProjectDeploymentActionsUpdated (UTC)
objectuiReadyReadyPreview, CommentJan 31, 2026 7:05pm
objectui-componentsReadyReadyPreview, CommentJan 31, 2026 7:05pm
objectui-crm-appReadyReadyPreview, CommentJan 31, 2026 7:05pm

Request Review

Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
CopilotAI changed the title [WIP] Fix CI build and test issuesFix CRM example field naming to comply with snake_case conventionJan 31, 2026
CopilotAI requested a review from hotlongJanuary 31, 2026 18:58
@hotlong
hotlong marked this pull request as ready for review January 31, 2026 19:13
CopilotAI review requested due to automatic review settings January 31, 2026 19:13
@hotlong
hotlong merged commit 2108890 into mainJan 31, 2026
7 checks passed

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Updates the CRM example’s Opportunity object field names to snake_case to satisfy ObjectStack schema validation and prevent CI failures.

Changes:

  • Renamed Opportunity object fields from camelCase to snake_case (close_date, account_id, contact_ids).
  • Updated seeded opportunity records in the CRM example stack config to use the renamed fields.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

FileDescription
examples/crm/src/objects/opportunity.object.tsRenames Opportunity field keys to snake_case to comply with compiler validation rules.
examples/crm/objectstack.config.tsUpdates example opportunity seed data to match the renamed schema fields.

CopilotAI added a commit that referenced this pull request Mar 3, 2026
The useMemo hook was placed after conditional early returns in
RecordDetailView, violating React's Rules of Hooks and causing
"Rendered fewer hooks than expected" (React error #310). Replaced
with an IIFE to keep the same Set-based dedup logic without hooks.
Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
CopilotAI added a commit that referenced this pull request Mar 5, 2026
… React error #310
Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
CopilotAI added a commit that referenced this pull request Mar 5, 2026
…atting to prevent React error #310
Instead of routing highlight values through full CellRenderer components
(which may not handle all data shapes from the API), use direct string
formatting functions (formatCurrency, formatDate, etc.) that guarantee
only primitives reach JSX. All values are coerced through toSafeString()
first, which safely handles MongoDB types, expanded references, arrays
of objects, and other non-primitive values.
Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
CopilotAI added a commit that referenced this pull request Mar 5, 2026
…Highlight to use getCellRenderer
The proper architectural fix for React error #310: instead of working around
unsafe renderers in HeaderHighlight, fix the renderers themselves.
Added coerceToSafeValue() utility in @object-ui/fields that safely coerces
MongoDB wrapper types ($numberDecimal, $oid, $date), expanded reference objects,
arrays, and Date instances to primitive values.
Applied coerceToSafeValue in: NumberCellRenderer, CurrencyCellRenderer,
PercentCellRenderer, TextCellRenderer, EmailCellRenderer, UrlCellRenderer,
PhoneCellRenderer, FormulaCellRenderer, DateCellRenderer, DateTimeCellRenderer.
HeaderHighlight reverted to use getCellRenderer for type-aware rendering,
since all renderers are now safe against non-primitive values.
16 new tests for coerceToSafeValue and cell renderer object safety.
Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
CopilotAI added a commit that referenced this pull request Mar 9, 2026
… error #310
The useMemo hook for detailSchema was placed after conditional early
returns (isLoading / !objectDef), causing an inconsistent hook count
across renders. React error #310 ("Rendered more hooks than during the
previous render") was triggered when transitioning from an early-return
render to a full render.
Move the useMemo before the early returns with a guard clause for
!objectDef inside the callback. All intermediate computation
(primaryField, sections, highlightFields, etc.) is folded into the
useMemo since those variables are only consumed by detailSchema.
Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
os-zhuang pushed a commit that referenced this pull request Jul 5, 2026
os-zhuang pushed a commit that referenced this pull request Sep 2, 2026
A `code` value whose TEXT is JSON rendered as the literal `[Object]`. The
showcase Field Zoo record's Code Editor field (`f_code`) stores the string
`{\n "ok": true\n}` and the detail page showed `[Object]`.
`coerceToSafeValue` parsed any string starting `{`/`[` and ending `}`/`]`,
then ran the result through the reference-label extraction
(`name || label || externalId || id || _id || '[Object]'`). An object carrying
none of those keys answers the placeholder. Every text-like cell reaches this
helper — `text`, `textarea`, `code`, `time`, `auto_number` and `qrcode` all
register to `TextCellRenderer` — so all of them lost JSON-shaped text, and
`[1, 2, 3]` in a text field rendered as `1, 2, 3`.
Shape is not a type. A string is now returned verbatim. The reference case the
parse was written for (#1426, an unresolved external-id ref arriving as
`'{"externalId":"…"}'`) belongs to reference-TYPED columns and already lives
there: `LookupCellRenderer` carries its own JSON-string branch that resolves the
label through the referenced object's schema and links to the record — neither
of which the type-blind helper could do. Scoped, not dropped.
Object and array VALUES still coerce, so React error #310 stays fixed.
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@hotlong