
2.1 Tile = data row
Dev: 8 edits · native tile: 10+ stepsWithout: Every tile ships shell
Row carries permission and switch
For the CRM2 team. 21 Oct 2026. All names and numbers in the demo are invented.
This is a demo. Try it, then send us your notes. Nothing here changes your own code or data.
Works best on a phone. A desktop browser also works.
Open crm2-proto.anantmb.workers.dev. Sign in with one username below.
Password for every account: Jaigurudev123
| Persona | Username | Try this |
|---|---|---|
| Teacher | tour.teacher |
|
| Volunteer | tour.volunteer |
|
| Second volunteer | tour.volunteer2 |
|
| Coordinator | tour.coordinator |
|
| Admin | tour.admin |
|
Tip: for the two volunteers, use two phones or two browsers.
Each tile on Home opens one app. You see only the apps your role may use.
An org admin can turn any app off. Go to Home > Turn apps on or off. The tile hides at once. No rebuild.
Follow up with people you invited. Call or WhatsApp in one tap.
TryOne lead per phoneDo not contact needs a reasonUndo the last stepClosed list with reason
Your centre and its team. Invite people. Set the centre's place on the map.
Try
The Happiness Survey. Each teacher makes their own QR link.

Seva you can join near you. Sign up, check in, log hours.

Shared rides to programs and seva.

Programs you run or attend.

The Art of Living program catalog.

Notices from registered centres. Filter by centre.

Videos, posters, your program links and ready messages.

Accounts, support requests, return rules, data import, connected apps.

Your details and your language.
These tiles show demo data in this demo.
Wisdom · talks by GurudevResources · posters, videos, templatesAsk AI · find or create anythingVTP · Volunteer Training ProgramCentres · find a centreEvents · events and sign-up
| Item | Before | After | Why |
|---|---|---|---|
| App list | The tile list was fixed in code. | Home reads the list at sign-in. | A team adds an app with one row in its own list. One id row in the shell, which a check keeps equal. |
| On/off switch | Every person saw every tile. | Each app has a permission and a switch. | An admin hides an unready app in one tap. |
| Top bar and app frame | CRM2 modules shared one header. AOL was a separate site with its own bar. | AOL apps open under the same top bar. Their own bar is hidden. | Every app looks like one product. App teams build no header. |
| One web address | The shell talked to CRM2's own backend only. | Added apps run under the same address. | One sign-in, one cookie, no cross-site setup. |
| Icons and languages | Generic icons. English and Hindi. | Sunburst icons. Six languages in the Samanvay build: English, Hindi, Marathi, Telugu, Gujarati, Kannada. | One look, and the languages volunteers speak. The last four are drafts. |
| Speed | Sign-in 1.12 s. Open Leads 1.88 s. | Sign-in 0.57 s. Open Leads 0.97 s. | A tile tap no longer reloads the whole page. |
Speed: median of 3 runs, desktop browser at phone size. Phones were not measured. Timed on the 20 Oct builds; the current build is not re-timed.
Part 1: the Samanvay shell. Part 2 (AOL split) follows.
RegistrySwitchDoorOne frame
The core becomes a plug-in board

Dev: 8 edits · native tile: 10+ stepsWithout: Every tile ships shell
Row carries permission and switch

Deploys 1 → 0Without: Faulty app stays on
Bad app off in one tap

5 files ≈+270Without: Only developers switch
Org admins switch tiles

Shell classifier removed · drift caught by checkWithout: Two lists drift
Shell keeps app lists; check pins ids and paths
AOL apps under the shell barWithout: AOL stays a separate site
AOL's own chrome stays hidden

Sign-ins: 1 (AOL's session, first-party)Without: Separate AOL site
One origin, one session

Sign-in 1123 → 572 ms · desktop, before one-frameWithout: ≈2 s every tap
Deploy-1022 one-frame state was not timed

4 files ≈+150Without: Notices go unseen
Notice seen from Home

Locales 2 → 6 · AOL shell buildOther builds: en + hi
Six locales in the AOL shell build

17 chunks checkedWithout: Breaks found on phones
Breaks caught before team release

26 files +84/−69Without: Brand forced on team
Brand change can be refused alone
≈ marks an estimate. Speed figures are desktop measurements from before the one-frame change; deploy-1022 was not timed. Phones were not measured.
Part 2. Part 1 is the CRM2 shell above. Before is AOL main 55df3634. After is main ba3653b5 and its branch cut of 22 Oct 03:24 (integration 2256d0e9): 1,607 files / 274,334 lines. Fair-run rows are 55df3634 vs afcf4e05. Where after is worse, the card says so.
CoreApps plug inOne PR eachSwitch offOne core, apps plug in
Honest rows: total core → app imports rise (50 → 57), adding an app adds lines (26 → 86), removing one touches more files (44 → 53), Leads first load is 301 B larger, and /app is 4.1 ms slower in the fair run. The gain is where the links sit and who can switch an app off.
Since #394 the generated lists merge with 0 conflicts (ba3653b5); two real app PRs still edit shared test pins (being fixed).

1,446 → 1,607 files carriedWithout: Apps mixed in src/ and frontend/src/
Apps move out; core keeps listed leftovers
19 ids · 12 hook keys · 6 generated listsWithout: Hubs import every app
Apps plug into twelve hook keys
Hand-written hub imports 50 → 6 · app → app 2 → 0Without: Worse: total core → app 50 → 57 (generated lists)
Core imports no app by hand
| Path | Owner (proposed) |
|---|---|
core/, migrations, scripts, tests | aol-core |
| apps/leads | aol-leads |
| apps/teams | aol-teams |
| apps/programs | aol-programs |
| apps/survey | aol-survey |
| apps/seva, apps/rides | aol-seva |
| apps/announcements, apps/promote | aol-comms |
| apps/admin | aol-core |
Each folder has one ownerWithout: all code in one review lane
Owner names are proposed; no CODEOWNERS file in the cut. The boundary check fails a new cross-app import.
Build, scripts, CI
Alone: via 8 (no code to test)
88 files · +32,539 · base dev
Read first: package.json, then ci.yml
Without: No app builds or runs the boundary check
Server core, 87 migrations
Alone: via 8
304 files · +34,588 · base PR 6
Read first: core/server/app-registry.mjs
Without: Nothing runs
Client core, UI kit, built bundle
Alone: 501 / 0 (was 427 / 220)
269 files · +19,519 · base PR 7
Read first: the two registry readers
Without: Core alone fails 220 tests
Queue, detail, follow-ups
Alone: proven on 9c
203 files · +45,144 · base PR 8
Read first: two registration files, then routes
Without: No Leads tile
Intake, ads, coverage
Alone: proven on 9c
36 files · +9,186 · base PR 9a
Read first: server/apps/leads-intake.mjs
Without: No intake or ads screens
Import, export, refer
Alone: core + Leads 1,953 / 0 (was 189 / 120)
22 files · +7,030 · base PR 9b
Read first: server/apps/leads-bulk.mjs
Without: No CSV import or referrals
Team tree, invites, centre profile
Alone: 2,076 / 0
53 files · +8,407 · base PR 9c
Read first: server/apps/my-centres.mjs
Without: No Teams tile; Admin cannot land
My and Find Programs
Alone: 717 / 0
76 files · +15,134 · base PR 8
Read first: both registrations, then apps/programs/routes/events.mjs
Without: No programme pages
Happiness Survey, form builder
Alone: 532 / 0
39 files · +6,258 · base PR 8
Read first: server/apps/survey.mjs
Without: No Survey tile
Callouts, shifts, roster, safety
Alone: 593 / 0
54 files · +11,338 · base PR 8
Read first: server/apps/seva.mjs (hooks)
Without: No Seva tile; Rides cannot land
Ride offers, needs, notices
Alone: 629 / 0
44 files · +6,629 · base PR 13
Read first: server/apps/rides.mjs (cron, notices)
Without: No Rides tile
Announcements tile (the template)
Alone: 507 / 0
23 files · +607 · base PR 8
Read first: all 7 app files: copy this PR for a new app
Without: No Announcements tile
Videos, posters, links, messages
Alone: 513 / 0
33 files · +1,279 · base PR 8
Read first: server/apps/promote.mjs
Without: No Promote tile
Staff hub, own profile
Alone: 2,115 / 0
55 files · +7,326 · base PR 10
Read first: both registrations; the one declared link
Without: No Admin hub or profile page
357 cross-app test files, 5 generated lists
Alone: 4,226 / 0
357 new files · ~+69,350 · base merge of 11, 12, 14, 15, 16, 17
Read first: test names only
Without: No proof the apps work together
Alone = tests of core plus the apps on the branch chain, in a separate checkout. All counts are from the 22 Oct 03:24 cut of ba3653b5 (branch-status.md). PR 9a and 9b were not run alone, only the stack tip 9c.

12 → 9 filesWithout: Worse: lines added 26 → 86 (fair run)
A new app is mostly its own files

Off in one tap, no deployWithout: Worse: remove touches 44 → 53 files
Off in one tap, no deploy

Conflicts 11/16 → 6/14 (fair run)Without: One 274,334-line review
Each team reviews its folder only
No behaviour change · Leads open 0.0574 → 0.0546 sWithout: Core knows every app
Same tap, registry finds the app

One ordered line, held by coreWithout: Two apps pick the same number
All 87 migrations stay in PR 7
| Worse after | Before | After | Why |
|---|---|---|---|
| Core → app imports, all | 50 | 57 | Generated lists name each app (51 of 57). Hand-written: 50 → 6. |
| Add an app: lines added | 26 | 86 | The old lists were rewritten whole. #394 now makes one line per app; not re-measured. |
| Remove an app: files | 44 | 53 | Lists, boot and route checks still need edits. The gain is the one-tap switch. |
| Leads first load (gzip B) | 109,541 | 109,842 | 55df3634 → ba3653b5; +301 B, inside the 109,850 B budget. |
| /app page (local) | 0.0302 s | 0.0343 s | +4.1 ms; no cause isolated. |
| Sign-in to 303 (local) | 0.0376 s | 0.0381 s | +0.5 ms; no cause isolated. Leads open is faster: 0.0574 → 0.0546 s. |
Not measured: per-app test time (run only one app's tests). Fair-run rows (add, remove, build, sign-in, Leads open, /app page) are 55df3634 vs afcf4e05, median of 3, same machine; they were not re-run on ba3653b5. Fair-run conflicts: 11/16 → 6/14 (55df3634 vs afcf4e05). Local times are local-stack times, not phone times. Mostly plug-in: 6 hand-written core → app imports remain (Queue.jsx and five server routes), plus ride, seva and survey form files, SurveyShare.jsx and seva-safety-switch.mjs in core. App-owned tests, flows and pages outside the app folder, plus test pins, still cost files on add/remove; a package to move them is running.
How to read this. Each block is one app. Steps are in order. Each picture shows the screen for that step. All names and numbers are invented demo data. The pictures show the app on its own. In the demo the Samanvay top bar replaces its header and bottom bar. In the pictures, Teams is called My Teams.
Goal: Add a person, call them, log what happened.


























Goal: See your teams, add a team, add a person.







Goal: Post a notice at one centre.




Goal: Find a program by place, language or PIN code.



Goal: See your sessions and share them.



Goal: Find links and material to share.




Goal: Offer or ask for a ride to a session.


Goal: Find seva near you and sign up. Coordinators add seva.







Goal: Make a link or QR code for a survey and read the answers.





Goal: Change your language, see your profile, ask for a change.



Not in this manual yet: Admin, Wisdom, Resources, Ask AI, VTP. Posters, messages and videos in Promote show sample data.
apps/volunteer2-fe) owns the sign-in screen, the top bar, the tile grid and the app frame. AOL checks the account.volunteer-be and Postgres, as before.src/routes/apps.mjs) and the same id to the shell list (packages/app-registry). A check keeps the two equal.GET /api/apps returns only the rows this person may open./x/<id>/. This "door" checks the session and the switch.feature/samanvay, not into dev. One bad PR then cannot break dev for the team.feature/samanvay into dev.| # | Branch | What it adds | Lines (estimate, before the app split; re-cut pending) |
|---|---|---|---|
| 1 | feat/app-registry | Runtime app list, permission per tile, switches, Admin › Apps | ~1.9k |
| 2 | feat/shell-bar-frame | Top bar, app frame, door, Home and Back, sign-in handoff | ~2.1k |
| 3 | feat/shell-brand-icons-i18n | Samanvay brand, Sunburst icons, six-language shell | ~5.3k |
| 3b | chore/brand-samanvay | Seva → Samanvay in team apps (the team may refuse this one alone) | ~0.2k |
| 4 | perf/shell-speed | Cached assets, boot data in the page, one chunk per module | ~0.3k |
| 5 | test/shell-flows | Browser flows for the shell | ~0.7k |
| 6 | chore/aol-core-tooling | Package, seeds, invented test data, boundary check, CI lane | ~16k |
| 7 | feat/aol-core | Auth, session, scope, roles, people, lead store, all migrations | ~25k |
| 8 | feat/aol-core-ui | UI kit, router, store, core texts | ~14k |
| 9a | feat/app-leads | Lead queue, detail, follow-ups, status | ~32k |
| 9b | feat/app-leads-intake | Intake, ads, coverage, lead sources and fields | ~27k |
| 9c | feat/app-leads-bulk | Import, export, refer, offline book | ~12k |
| 10 | feat/app-teams | Team tree, members, invites, centre profile | ~10k |
| 11 | feat/app-programs | My Programs and Find Programs | ~21k |
| 12 | feat/app-survey | Happiness Survey and form builder | ~11k |
| 13 | feat/app-seva | Seva callouts, shifts, roster, safety | ~14k |
| 14 | feat/app-seva-rides | Ride offers, needs, notices | ~10k |
| 15 | feat/app-announcements | Announcements tile | ~1k |
| 16 | feat/app-promote | Videos, posters, program links, messages | ~2.3k |
| 17 | feat/app-admin-profile | Staff hub and own profile | ~12k |
| 18 | test/aol-integration | Tests that cross two or more apps | ~26k |
| Total | estimate, before the app split; re-cut pending | ≈245k |
| Stays in the demo | What the team uses |
|---|---|
| Demo sign-in with AOL accounts (the stub code is for local tests only) | CRM2's own sign-in. The added apps accept the shell's handoff. |
| Our AOL sign-in screens inside the shell | None. A CRM2 person maps to an AOL user by verified phone. A handoff never creates an account. |
| Local stub of the CI SDK and the demo Worker config | The real CI SDK and the team's own config. |
| The link to our own demo database | The team links its own AOL-Connect Worker and D1 per environment. |
| The name "Samanvay" in team-owned apps | Only if the group agrees (branch 3b). |