Skip to content

feat(sdk): show and lock immutable document properties in the mobile example apps - #4820

Merged
QuantumExplorer merged 2 commits into
v4.2-devfrom
feat/immutable-properties-mobile
Sep 18, 2026
Merged

QuantumExplorer merged 2 commits into
v4.2-devfrom
feat/immutable-properties-mobile

Conversation

@QuantumExplorer

@QuantumExplorer QuantumExplorer commented Sep 18, 2026

Copy link
Copy Markdown
Member

Issue being fixed or feature implemented

Follow-up to #4815 (immutable / immutableAllowSetting document-type keywords) and #4817 (their JavaScript surface). Nothing is required for correctness on mobile, consensus enforces the keywords, but without this the example apps let a user edit a frozen property and pay for a guaranteed rejection (code 40128). This gives Swift and Kotlin the same parity treatment the indexOnly keyword got in #4509.

What was done?

Kotlin (KotlinExampleApp only; the SDK keeps no document-type model)

  • ContractJson.kt: documentTypeImmutability(schema) reads both keywords off the raw schema (an immutableAllowSetting entry outside immutable is dropped, DPP refuses such contracts at registration), and immutablePropertyLock(property, immutability, hasStoredValue) resolves a property to EDITABLE, FROZEN or SETTABLE_ONCE (settable-once only while the stored document has no value).
  • DocumentTypeDetailsScreen.kt: "Immutable Properties" and "Settable Once While Absent" rows under Document Settings.
  • DocumentActionsScreen.kt: the replace form disables frozen fields and captions them, and captions settable-once fields; presence is read from the probed document's fields. Submission semantics are unchanged.
  • DocumentTypeImmutabilityTest.kt: parsing, dropped allowance outside immutable, non-string entries ignored, and the three lock states.

Swift (SwiftDashSDK + SwiftExampleApp)

  • New DocumentTypeImmutability value type: deduped, sorted immutableProperties / immutableAllowSetting plus lockState(for:hasStoredValue:) returning .editable, .frozen or .settableOnce, with the same semantics as the Kotlin helper.
  • PersistentDocumentType exposes immutability, immutableProperties and immutableAllowSetting as computed accessors read off the persisted schemaJSON. Deliberately no new stored column: schemaJSON already persists the whole type dictionary, and a new column moves the entity hash, which since feat(sdk)!: key limits on every client: wasm-dpp2, platform-wallet, FFI, Kotlin and Swift #4811 (DashSchemaV5) costs a schema version, frozen model copies and a fixture store. indexOnly predates that discipline. The frozen V1/V4 schemas are untouched and the migration tests still pass.
  • DocumentTypeDetailsView and the document-type record in StorageRecordDetailViews list the frozen and settable-once properties.
  • DocumentFieldsView badges each property ("Immutable" / "Immutable once set") and disables frozen fields; TransitionDetailView passes the type's immutability only for documentReplace. That generic builder never loads the stored document, so settable-once fields stay editable there with the caption. ReplaceDocumentView on the Documents tab does have the stored document and shows which frozen properties already hold a value.
  • Transition construction is unchanged on both platforms; this is a UI lock and a display only.

How Has This Been Tested?

  • Kotlin: DocumentTypeImmutabilityTest added (parsing, dropped allowance outside immutable, non-string entries ignored, the three lock states). No JDK on this machine, so the Kotlin build and tests rely on CI.
  • Swift: swift test --filter DocumentTypeImmutabilityTests (9 tests) and swift test --filter "DashModelMigrationTests|DocumentTypeImmutabilityTests|DataContractParserPreProgrammedTests" (28 tests, 1 skipped) pass; xcodebuild of SwiftExampleApp for the iPhone 17 simulator builds clean. No simulator UAT was run. Whether the FFI forwards the two keywords in the contract JSON handed to DataContractParser is not verified against a devnet here; it rests on the same path indexOnly, countable and terminal already use.

Breaking Changes

None.

Checklist:

  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have added or updated relevant unit/integration/functional/e2e tests
  • I have added "!" to the title and described breaking changes in the corresponding section if my code contains any
  • I have made corresponding changes to the documentation if needed

For repository code-owners and collaborators only

  • I have assigned this pull request to a milestone

🤖 Generated with Claude Code

…example app

Parity for the protocol v14 `immutable` / `immutableAllowSetting`
document-type keywords (#4815), the same treatment `indexOnly` got:

- ContractJson: `documentTypeImmutability` reads both lists off the raw
  schema (an allowance outside `immutable` is dropped, DPP refuses such
  contracts), and `immutablePropertyLock` resolves a property to
  EDITABLE / FROZEN / SETTABLE_ONCE against the stored document.
- DocumentTypeDetailsScreen lists the frozen and settable-once
  properties under Document Settings.
- DocumentActionsScreen's replace form disables frozen fields and
  captions settable-once ones, so a user is not charged for a replace
  consensus is guaranteed to reject (code 40128).
- Unit tests for the helpers.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Sep 18, 2026

Copy link
Copy Markdown
Contributor

Warning

Review limit reached

Next included review available in 10 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Learn how review limits work.

Review configuration:

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Advanced

Run ID: e943505d-e766-42fc-badf-b5b548b3cea5

📥 Commits

Reviewing files that changed from the base of the PR and between 1a57e10 and 3ec195c.

📒 Files selected for processing (13)
  • packages/kotlin-sdk/KotlinExampleApp/app/src/main/java/org/dashfoundation/example/ui/contracts/ContractJson.kt
  • packages/kotlin-sdk/KotlinExampleApp/app/src/main/java/org/dashfoundation/example/ui/contracts/DocumentActionsScreen.kt
  • packages/kotlin-sdk/KotlinExampleApp/app/src/main/java/org/dashfoundation/example/ui/contracts/DocumentTypeDetailsScreen.kt
  • packages/kotlin-sdk/KotlinExampleApp/app/src/test/java/org/dashfoundation/example/ui/contracts/DocumentTypeImmutabilityTest.kt
  • packages/swift-sdk/Sources/SwiftDashSDK/Core/Utils/DataContractParser.swift
  • packages/swift-sdk/Sources/SwiftDashSDK/Core/Utils/DocumentTypeImmutability.swift
  • packages/swift-sdk/Sources/SwiftDashSDK/Persistence/Models/PersistentDocumentType.swift
  • packages/swift-sdk/SwiftExampleApp/SwiftExampleApp/Views/DocumentFieldsView.swift
  • packages/swift-sdk/SwiftExampleApp/SwiftExampleApp/Views/DocumentTypeDetailsView.swift
  • packages/swift-sdk/SwiftExampleApp/SwiftExampleApp/Views/DocumentsView.swift
  • packages/swift-sdk/SwiftExampleApp/SwiftExampleApp/Views/StorageRecordDetailViews.swift
  • packages/swift-sdk/SwiftExampleApp/SwiftExampleApp/Views/TransitionDetailView.swift
  • packages/swift-sdk/SwiftTests/SwiftDashSDKTests/DocumentTypeImmutabilityTests.swift

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@github-actions github-actions Bot added this to the v4.2.0 milestone Sep 18, 2026
@github-actions

github-actions Bot commented Sep 18, 2026

Copy link
Copy Markdown
Contributor

PR Hygiene

State: waiting-bots · commit 3ec195c8bca69232ba2b9b80a62cdd96f24d6d3c

  • coderabbitai has not reported for the current head
  • thepastaclaw has not reported for the current head

Self-review is an author attestation that you have read the diff:
/self-reviewed — covers everything pushed so far; post it again after a new push.

This report does not bypass CI or repository protection rules.

…xample app

Swift half of the protocol v14 `immutable` / `immutableAllowSetting`
parity (#4815), mirroring the Kotlin commit:

- New `DocumentTypeImmutability` value type (deduped, sorted lists +
  `lockState(for:hasStoredValue:)` -> editable / frozen / settableOnce),
  exposed on `PersistentDocumentType` as computed accessors read off the
  persisted `schemaJSON`. No new stored column: one would move the
  entity hash and cost a DashSchema version plus a fixture store, which
  a display-only keyword does not justify.
- DocumentTypeDetailsView and StorageRecordDetailViews list the frozen
  and settable-once properties.
- DocumentFieldsView badges each property and disables frozen fields on
  the replace flow (TransitionDetailView passes the type's immutability
  only for documentReplace); ReplaceDocumentView shows which frozen
  properties the stored document already has a value for.
- 9 unit tests; migration tests unchanged and passing.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

@QuantumExplorer QuantumExplorer left a comment

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Approved

@thepastaclaw

thepastaclaw commented Sep 18, 2026

Copy link
Copy Markdown
Collaborator

⚠️ DEGRADED — Queued for automated review — 31st in line, estimated start in ~17 h (commit 3ec195c)
Estimated review time once started: ~1.1 h (two-phase automated review; median of recent runs).
The primary review models are currently out of quota; this review will run on stand-in models and be marked as degraded.

  • Request priority review — click to move this review to the front of the queue.

@QuantumExplorer
QuantumExplorer merged commit 71ea82f into v4.2-dev Sep 18, 2026
23 of 24 checks passed
@QuantumExplorer
QuantumExplorer deleted the feat/immutable-properties-mobile branch September 18, 2026 14:43
Sign up for free to 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.

2 participants