Repository navigation
Open
Labels
Description
As a phone app developer, I need the card model to carry the Open dashboard action and its target, so that the phone can open the right dashboard.
Motivation — plain
The phone keeps cards in its own database. Without a place for the target dashboard, the action reaches the phone and is lost. The target is kept as a plain reference to the dashboard. On a fresh phone, cards arrive before dashboards, so a stored link to the dashboard itself would be empty.
Acceptance Criteria — plain
- A card synced with Open dashboard is stored with its action and the target dashboard's reference, on a fresh install and on an upgraded one.
- On a fresh install, the target is present even though cards sync before dashboards.
- A card with any other action stores no target.
- Upgrading a phone with existing cards keeps them and their actions unchanged.
- A new avni-models version is released carrying this change.
Tech Approach — technical
Verified on avni-models origin/18.3 @ 6bb6ac8, version 1.33.86.
src/ReportCard.js:actionTypes(:22-26): addOpenDashboard: "OpenDashboard".- Schema (
:38-64): addactionDetailDashboardUUID: {type: "string", optional: true}. A string, not an object reference. Reference data syncs from the end ofEntityMetaData.model()backwards (src/EntityMetaData.js:495), soreportCardsyncs beforedashboard(:503). ADashboardresolved infromResourceis null on a fresh phone. - Getter and setter beside
actionDetailVisitType(:319). fromResource(:203-237): inside theresource.actionDetailblock,reportCard.actionDetailDashboardUUID = resource.actionDetail.dashboardUUID || null.isActionOpenDashboard()besideisActionMarkAttendance()(:347).
src/Schema.js: bumpschemaVersionfrom 220 (:281) to 221, with a comment-only stepif (oldDB.schemaVersion < 221), following< 213(:1075).- Release, then bump
openchs-modelsin avni-clientpackages/openchs-android/package.json:106and avni-webapppackage.json:43. Both pin 1.33.86 today. - SQLite on the phone is handled in avni-client (story Open a dashboard from a tile, carrying filters over and restoring the one underneath avni-client#2220). This story only changes the model.
Testing Gotchas — plain
- Test a fresh install, not only an upgrade. A fresh install is where cards arrive before dashboards.
- Upgrade a phone that holds cards with Do visit and Mark attendance. Their visit types and attendance types must survive.
Out of Scope — plain
- The filter preset model change. It is story Preset fields on the filter settings model #75, in its own release.
Related — plain
- Open dashboard card action avni-server#1101 (server), Open a dashboard from a tile, carrying filters over and restoring the one underneath avni-client#2220 (phone app, which adds the storage change for the phone's newer database).
Metadata
Metadata
Assignees
Labels
Type
Projects
- StatusShow more project fieldsQA Ready
Activity
#74 | Carry the Open dashboard action and its target dashboard on a card
#74 | Fetch every card again after the upgrade, so cards synced befor…
adamsanadi6 commentedon Oct 29, 2026
Pushed to 18.3 as
6bb6ac8..88d9b71and released as openchs-models 1.33.88. 1.33.87, released first, misses acceptance criterion 3 in one case, and 1.33.88 fixes it. All five criteria hold in the model and on a real phone database. The web app takes 1.33.88 on 18.3 and runs on it locally, though it does not show the new action yet. The phone app waits for avniproject/avni-client#2220, which should take 1.33.88 together with its migration.Two changes from the card as written:
Review on 30 Oct, before any testing: three reviewers checked each criterion against the code. Criterion 3 failed in the case above, and nothing else did. Two reviewers then checked the fix, and the wording of one comment was corrected.
Tested on 30 Oct, all passing:
Before the 1.33.88 release, the unit suite, the real-database checks and the package check ran again on the fix, and three reviewer agents found nothing that blocks it. The published 1.33.88 passes the same package checks.
Checked again from the beginning after the release, on 30 Oct:
Tested again later on 30 Oct, after one more review confirmed the fix commit, all passing:
Tested on a local server and web app built from 18.3, on 30 Oct, with a test card that opens a test dashboard, all passing:
Screenshots, numbered as the files:
Gaps and issues:
Testing notes:
Manual tests (technical)
Setup. A server built from
18.3(it carries avniproject/avni-server#1101), the phone app built from avniproject/avni-client#2220 on openchs-models 1.33.88, with migration0009, an emulator, and one organisation whose user's group sees dashboard A, plus a second dashboard B. On a dashboard the user sees, four cards: the test card, Open dashboard with target A, created as in avni-server#1101's manual test 1; a Do visit card; a Mark attendance card; and a View subject profile card.1. Upgrade on the older database (AC 1, AC 4, Gotcha 2). Install today's app (models 1.33.86), log in and sync. Install the #2220 build over it without uninstalling, open it and sync.
Expected: the app opens with its data. After the sync the test card opens dashboard A, and the other three cards do what they did before.
2. Upgrade on the newer database (AC 1, AC 4). Repeat 1 with a user whose phone is already on the newer database.
Expected: as in 1, and the app starts without a database error.
3. Fresh install (AC 2, Gotcha 1). Uninstall, install the #2220 build, log in and sync.
Expected: the test card opens dashboard A, though dashboards download after cards.
4. Switch to Do visit (AC 3). Change the test card to Do visit on the server (avni-server#1101's manual test 6, with Do visit details) and sync.
Expected: the test card acts as a Do visit card, and no dashboard opens.
5. Switch to View subject profile (AC 3). Change the test card to View subject profile and sync.
Expected: the test card opens subjects as before, and its old target is gone.
6. Back to Open dashboard (AC 1). Change the test card to Open dashboard with target B and sync.
Expected: the test card opens dashboard B.
7. Rerun the evidence, any time. From
avni-product-ops, run each.shinanalysis/dashboard-navigation-and-filter-presets/dev-testing/avni-models-74-evidence/, withavni-modelsandavni-clientchecked out beside it.Expected: each log ends with
RESULT: every check passed.Tech details
23a99a4:ReportCardgainsactionTypes.OpenDashboard,actionDetailDashboardUUID(optional string) andisActionOpenDashboard().fromResourcemapsactionDetail.dashboardUUIDinside theactionDetailblock (src/ReportCard.js:225-240).17170c8: schema 221. The< 221step moves theReportCardsync marker to 1900-01-01 (src/Schema.js:1145-1162), the same loop as the 208 step.0e0b566:v1.33.87. Publish run 40954094562 passed; npmgitHeadis0e0b566, tarball sha1f89d0171.417a3b6: anelseinfromResourcesetsactionDetailDashboardUUIDto null whenresource.actionDetailis absent (src/ReportCard.js:240-244). Intest/ReportCardTest.js,isUndefinedbecomesisNull, and a new test, "clears the target when a card arrives with no action details", covers View subject profile and no action.88d9b71:v1.33.88. Publish run 41021885467 passed; npmgitHeadis88d9b71, tarball sha14d72332d.published-1.33.88-checkpasses 13 of 13 on the npm tarball.a9f07542aon 18.3:openchs-models1.33.86 to 1.33.88 inpackage.json:43and its one lockfile entry, the step the Tech Approach names. A frozen install accepts the lockfile, and the web app's 537 tests and production build pass.full-recheck-1.33.88-summary.logand the*-v1.33.88.logfiles in the evidence folder, withrealm-corner-cases-v1.33.87.logandsqlite-after-0009-v1.33.87.logas the controls;consumer-avni-client-18.3.logandconsumer-avni-webapp-18.3.logran the npm tarball.417a3b6with Node 20.18.1: the file passes 15 of 15 and the suite 483, with 1 skipped. The build compiles 158 files, and all 97 schemas are valid at 221.analysis/dashboard-navigation-and-filter-presets/dev-testing/avni-models-74-evidence/, run on Node 24.11.1 unless noted:realm-corner-cases(27 checks) andsqlite-after-0009(14). Their-0e0b566logs show the defect in the release.realm-upgrade-220-to-221(30),realm-upgrade-from-old(45),realm-fault-injection(16),realm-downgrade(15),realm-volume(7),model-fuzz(9, seed 20261030) andrealm-old-phone-story(12).sqlite-pin-without-0009(12) andpublished-1.33.87-check(10).server-sync-capture: avni-server694572fc6ReportCardControllerIntegrationTest9 of 9, JDK 21.0.12.1, Gradle 8.10.2, offline, from a throwaway worktree. It also holds the two sync bodies.consumer-avni-client-18.3: avni-clienta527c117aon Node 20.18.1. Unit 2,315 and integration 432 passed, both with 1.33.86 and with the fix.417a3b6:realm-upgrade-matrix(99 checks; release schemas 204 to 220, with 203 refused by Realm 12.14.2),migration-properties(5 checks over 5,000 stand-in sets and 30 real files),switch-chains(33 checks through avni-client'sSqliteProxy.bulkCreateandEntityHydrator.flattenand throughRealmProxy, onserver-sync-do-visit.json,server-sync-mark-attendance.jsonandserver-sync-chain-*.json),release-candidate-1.33.88-check(13 checks; same 176 files as 1.33.87, onlydist/ReportCard.jsandpackage.jsondiffer),local-mutation-analysis(21 of 21 killed; StrykerJS would be downloaded and run throughnpx, which the session's safety check refused) andconsumer-avni-webapp-18.3(avni-webappc519dfad2, 526 passed with both).RealmProxyin the app's update mode. The newer database is built from avni-clienta527c117a's migrations0000to0008plus the planned0009.fromResourcetakes 41.8 ms and one write 25.4 ms. A 220 file holding 1,000 cards and 300 markers opens in 37.1 ms, migration included.ReportCardControllerIntegrationTestreads_embedded.card[].actionDetail.dashboardUUIDfrom the real sync endpoint. This card readsresource.actionDetail.dashboardUUID(src/ReportCard.js:239). After the switch, the sync sends"actionDetail": null.a9f07542awith 1.33.88 installed, on Vite's dev server, against a local avni-server built from694572fc6, in the HCO Test organisation, with test card 100 and target dashboard 18.src/formDesigner/components/ReportCard/ReportCardShow.jsx:216-221names every action other than Do visit "View subject profile". The editor's Action options (CreateEditReportCard.jsx:521-531) have no Open dashboard, and its save reaches the server as Open dashboard with no target, whichCardService.java:329refuses with 400 "Dashboard is required when action is OpenDashboard". The editor shows that message (CreateEditReportCard.jsx:953-956), and the card is unchanged.live-server-contract(3 checks): the server's/v2/card/search/lastModifiedbody for card 100, read by the installed 1.33.88ReportCard.fromResource: the target as created, null afterPUT /web/reportCard/100to View subject profile ("actionDetail": null), and back after a switch back. Card 100 ends as created. The screenshots are in the evidence folder'swebapp-1.33.88/.#74 | Clear the target dashboard when a card arrives without action d…
avniproject/avni-models#74 | Take openchs-models 1.33.88, which carri…