Skip to content

feat(web): add OPropertiesField for form and list summary - #271

Merged
buke merged 5 commits into
mainfrom
feat/orm-properties-pp3
Aug 11, 2026
Merged

feat(web): add OPropertiesField for form and list summary#271
buke merged 5 commits into
mainfrom
feat/orm-properties-pp3

Conversation

@buke

@buke buke commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

User description

Summary

  • Expose BaseModel.ResolveProperties (and WebModelStore.ResolveProperties) so Form loads schema⊕map without Browse attaching resolved values (PP3).
  • Add OPropertiesField with PP7 light controls, full-map replace writes, schema∩map list summary, empty-schema safety, and unknown-type skip.
  • Helpers + unit coverage for render/write/summary/re-resolve (PP4 B1: container change does not trim in-memory map).

Test plan

  • go run . test unit web --fe (896 passed, no Vue warn / stderr noise)
  • go run . test unit web (BE + FE)
  • go run . test typecheck web
  • go run . test unit core --be
  • CI PR gate green

Made with Cursor


PR Type

Enhancement, Tests


Description

  • Expose BaseModel.ResolveProperties and WebModelStore.ResolveProperties for schema+map resolution.

  • Add OPropertiesField component with form editing, display, and list summary of resolved property items.

  • Introduce helpers (filterRenderablePropertyItems, buildFullPropertiesMap, writePropertyValue, etc.) for item filtering, full-map replace writes, and schema∩map intersection count.

  • Add comprehensive unit tests covering rendering, item write, summary text, empty schema, and container-driven re-resolve.


File Walkthrough

Relevant files
Enhancement
index.ts
Export property‑resolve types and helpers                               

modules/core/service/orm/model/index.ts

  • Re-exports ResolvePropertiesOptions, PROPERTIES_V1_TYPES,
    normalizePropertiesMap, isPlainPropertiesMap, PropertyItemDefinition,
    and ResolvedPropertyItem for wider access.
+8/-1     
model.ts
Expose ResolveProperties on BaseModel                                       

modules/core/service/orm/model/model.ts

  • Imports resolveProperties and ResolvePropertiesOptions.
  • Adds BaseModel.ResolveProperties static method that calls
    resolveProperties and returns ResolvedPropertyItem[].
  • Provides JSDoc explaining its use for Form UIs.
+15/-0   
modelStore.ts
Add ResolveProperties to the web model store type               

modules/web/web/stores/modelStore.ts

  • Appends ResolveProperties service method to the WebModelStore
    interface.
+1/-0     
oproperties_helpers.ts
Add helpers for render, full‑map write, and summary count

modules/web/web/components/field/oproperties_helpers.ts

  • New file implementing property‑editing helpers:
    filterRenderablePropertyItems, normalizeSelectionOptions,
    countSchemaMapIntersection, buildFullPropertiesMap,
    writePropertyValue.
  • Handles type filtering (only V1 renderable types), selection‑option
    normalisation, and full-map replace writes.
+86/-0   
OPropertiesField.vue
Add OPropertiesField component for editing and list summary

modules/web/web/components/field/OPropertiesField.vue

  • New Vue 3 component that renders a form with per‑property controls
    (switch, number, textarea, date picker, select, etc.) based on the
    resolved schema.
  • Displays a list summary (count of schema∩map keys) in table/inline
    modes.
  • Re‑resolves items when the record, map, or containerId prop changes.
  • Gracefully skips unsupported property types and logs a warning.
+337/-0 
Tests
OPropertiesField.test.ts
Add unit tests for OPropertiesField and helpers                   

modules/web/web/components/field/OPropertiesField.test.ts

  • New test suite for OPropertiesField and its helpers.
  • Covers renderable filtering, normalise selection, schema‑map
    intersection, and full‑map write helpers.
  • Tests the component in form and table modes: renders items, writes
    full map on edit, shows summary count, handles empty schema, and
    re‑resolves on container change.
+297/-0 

Summary by CodeRabbit

  • New Features

    • Added a reusable properties field for displaying and editing boolean, numeric, text, date/time, and selection values.
    • Added automatic property definition resolution, default-value handling, formatting, validation, and read-only or inline display modes.
    • Added support for date/time conversion and preserving existing property values.
    • Added model and web-store support for resolving property definitions.
  • Bug Fixes

    • Improved handling of unsupported property types, invalid values, empty schemas, failed or stale resolutions, and property updates.

- Expose BaseModel.ResolveProperties on the web store so Form loads schema⊕map without Browse attaching resolved values.

- Add OPropertiesField with PP7 light controls, full-map replace writes, schema∩map list summary, and empty/unknown-type safe rendering.

Co-authored-by: Cursor <cursoragent@cursor.com>
@coderabbitai

coderabbitai Bot commented Aug 11, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

You’ve reached a temporary PR review limit under our Fair Usage Limits Policy.

Your recent review volume is higher than typical usage, so adaptive limits are currently applied.

Next review available in: 51 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: d23c8566-9f44-4cff-88a6-fb544c85debf

📥 Commits

Reviewing files that changed from the base of the PR and between 398c09a and fe4c390.

📒 Files selected for processing (3)
  • modules/web/web/components/field/OPropertiesField.test.ts
  • modules/web/web/components/field/OPropertiesField.vue
  • modules/web/web/components/field/oproperties_helpers.ts
📝 Walkthrough

Walkthrough

The PR exposes property resolution through BaseModel and WebModelStore. It adds OPropertiesField with property map helpers, supported-type rendering, value normalization, asynchronous resolution, reactive reloads, and comprehensive Vitest coverage.

Changes

Properties field resolution

Layer / File(s) Summary
Model resolution API
modules/core/service/orm/model/index.ts, modules/core/service/orm/model/model.ts, modules/web/web/stores/modelStore.ts, modules/core/service/orm/model/properties_resolve.test.ts
The model barrel exports property-resolution types and helpers. BaseModel.ResolveProperties delegates to resolveProperties. WebModelStore exposes the client service. RPC coverage verifies resolved property values.
Properties field behavior
modules/web/web/components/field/oproperties_helpers.ts, modules/web/web/components/field/OPropertiesField.vue
The new field resolves property definitions, renders supported types, normalizes values, preserves defaults, writes full maps, and reloads when field context changes.
Properties field validation
modules/web/web/components/field/OPropertiesField.test.ts
Tests cover helper utilities, form and list modes, unsupported types, empty schemas, map replacement, control behavior, container changes, and stale asynchronous responses.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant OPropertiesField
  participant WebModelStore
  participant BaseModel
  participant resolveProperties
  OPropertiesField->>WebModelStore: ResolveProperties(record, fieldName, options)
  WebModelStore->>BaseModel: ResolveProperties(record, fieldName, options)
  BaseModel->>resolveProperties: Resolve property map and effective schema
  resolveProperties-->>BaseModel: ResolvedPropertyItem[]
  BaseModel-->>WebModelStore: ResolvedPropertyItem[]
  WebModelStore-->>OPropertiesField: ResolvedPropertyItem[]
  OPropertiesField->>OPropertiesField: Write normalized property map
Loading

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly identifies the main change: adding OPropertiesField for form editing and list summaries.
Description check ✅ Passed The description explains the changes, test coverage, and validation status, including the pending CI PR gate.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/orm-properties-pp3

Comment @coderabbitai help to get the list of available commands.

@codecov

codecov Bot commented Aug 11, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ All tests successful. No failed tests found.

📢 Thoughts on this report? Let us know!

@github-actions

Copy link
Copy Markdown

PR Reviewer Guide 🔍

Here are some key observations to aid the review process:

⏱️ Estimated effort to review: 3 🔵🔵🔵⚪⚪
🧪 PR contains tests
🔒 No security concerns identified
⚡ No major issues detected

@github-actions

Copy link
Copy Markdown

PR Code Suggestions ✨

No code suggestions found for the PR.

- Use (v: any) update handlers matching other O*Field components so ElSwitch assignability passes CI vue-tsc.

Co-authored-by: Cursor <cursoragent@cursor.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@modules/web/web/components/field/OPropertiesField.vue`:
- Around line 264-288: Update reloadResolved to maintain a monotonically
increasing request id and capture the id for each ResolveProperties call. Only
apply resolvedItems updates, skipped-item warnings, and error handling when the
captured id is still current, so older responses cannot overwrite newer record
or containerId results. Add a test that starts two requests, resolves the newer
one first, then verifies the older response does not change the resolved schema.
- Around line 36-91: Associate each property label and control in the field
template for accessibility. Add a stable, unique matching id to every rendered
control and set the corresponding label’s for attribute, or apply
itemLabel(item) as each control’s aria-label; ensure all branches, including
boolean, numeric, text, date, selection, and fallback controls, receive the
association.
- Around line 62-69: Update the datetime branch in the date-picker binding to
convert stored values with utcToUserWallDate and picker updates with
userWallDateToUtc followed by formatUtcIso before calling onItemWrite. Keep
date-only handling unchanged, and remove reliance on the literal [Z]
value-format suffix for datetime conversion.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 3e9ea6f5-43d8-44d7-aad4-af66f05d6b38

📥 Commits

Reviewing files that changed from the base of the PR and between 876acbb and 55e9ab8.

📒 Files selected for processing (6)
  • modules/core/service/orm/model/index.ts
  • modules/core/service/orm/model/model.ts
  • modules/web/web/components/field/OPropertiesField.test.ts
  • modules/web/web/components/field/OPropertiesField.vue
  • modules/web/web/components/field/oproperties_helpers.ts
  • modules/web/web/stores/modelStore.ts

Comment thread modules/web/web/components/field/OPropertiesField.vue Outdated
Comment thread modules/web/web/components/field/OPropertiesField.vue
Comment thread modules/web/web/components/field/OPropertiesField.vue
buke and others added 2 commits August 11, 2026 17:56
- Wire label for/id on every property control for accessible naming.

- Convert datetime values through utcToUserWallDate / userWallDateToUtc / formatUtcIso instead of a literal [Z] value-format.

- Ignore stale ResolveProperties responses with a generation guard, and cover race / UTC / a11y in unit tests.

Co-authored-by: Cursor <cursoragent@cursor.com>
- Expand helper and component unit tests across PP7 controls, races, and fallbacks.

- Exercise BaseModel.ResolveProperties in properties resolve BE tests.

- Extract propertiesFieldKey and drop an unreachable sync generation guard.

Co-authored-by: Cursor <cursoragent@cursor.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
modules/web/web/components/field/oproperties_helpers.ts (1)

96-126: 🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

Avoid ordinary assignment for __proto__.

assertValidPropertyDefinitionItems accepts __proto__, and the resolver passes it through. The dynamic assignments create no own key and can change next's prototype, so the property is omitted from the submitted map. Use Object.defineProperty or reject __proto__ during validation.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@modules/web/web/components/field/oproperties_helpers.ts` around lines 96 -
126, Update buildFullPropertiesMap and writePropertyValue to safely persist the
schema key "__proto__" using an own-property definition rather than ordinary
assignment, including when copying previous, value, default, or explicitly
written values. Preserve the existing filtering and replacement behavior for all
other property names.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@modules/web/web/components/field/OPropertiesField.test.ts`:
- Around line 145-153: Update the test factory’s store selection logic to
distinguish an explicitly provided store value, including undefined, from an
omitted store by checking whether the store property exists on opts. Preserve
the existing default-store behavior only when the property is absent, so the
missing-store test exercises the intended path.

---

Outside diff comments:
In `@modules/web/web/components/field/oproperties_helpers.ts`:
- Around line 96-126: Update buildFullPropertiesMap and writePropertyValue to
safely persist the schema key "__proto__" using an own-property definition
rather than ordinary assignment, including when copying previous, value,
default, or explicitly written values. Preserve the existing filtering and
replacement behavior for all other property names.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: ceb4a9ce-3d2e-4623-ba57-667743655adf

📥 Commits

Reviewing files that changed from the base of the PR and between 55e9ab8 and 398c09a.

📒 Files selected for processing (4)
  • modules/core/service/orm/model/properties_resolve.test.ts
  • modules/web/web/components/field/OPropertiesField.test.ts
  • modules/web/web/components/field/OPropertiesField.vue
  • modules/web/web/components/field/oproperties_helpers.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • modules/web/web/components/field/OPropertiesField.vue

Comment thread modules/web/web/components/field/OPropertiesField.test.ts Outdated
- Build replace maps with Object.create(null) so "__proto__" is an own data key.

- Copy field values via own-key enumeration in toView for the same reason.

- Let the test factory treat store: undefined as an explicit missing store.

Co-authored-by: Cursor <cursoragent@cursor.com>
@buke
buke merged commit c6a3f4f into main Aug 11, 2026
43 checks passed
@buke
buke deleted the feat/orm-properties-pp3 branch August 11, 2026 10:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant