# rApp β†’ Applet Mapping (Phase B) > **Purpose.** Every flow-node type inside an rApp mini-canvas should exist as an `AppletDefinition` so the main rSpace canvas can render it as a `folk-applet` with typed I/O ports. This is the asymmetric B-model: *rSpace understands every rApp shape; rApps don't need to understand every rSpace shape.* > > **Status legend** (for each proposed applet): > - βœ… = already registered in `modules//applets.ts` > - πŸ†• = proposed new applet β€” user approves, I implement > - 🟑 = covered by existing custom element (`folk-gov-*`) β€” should wrap into AppletDefinition for registry discoverability + template support > > **Review process.** Walk each section, mark βœ“/βœ—/edit on proposed rows (id, label, icon, color, ports). I'll implement the βœ“ set per-rApp in follow-up PRs. --- ## Currently-registered applets (27 total) For reference only β€” these already work on the main canvas. | rApp | Applet ID | Label | Icon | |---|---|---|---| | rbooks | `book-card` | Book Card | πŸ“š | | rcal | `next-event` | Next Event | πŸ“… | | rcal | `timeline-view` | Timeline | πŸ•’ | | rchats | `unread-count` | Unread Count | πŸ’¬ | | rchoices | `vote-tally` | Vote Tally | πŸ—³οΈ | | rdata | `analytics-card` | Analytics Card | πŸ“Š | | rdocs | `doc-summary` | Doc Summary | πŸ“„ | | rexchange | `rate-card` | Rate Card | πŸ’± | | rexchange | `trade-status` | Trade Status | πŸ”„ | | rflows | `flow-summary` | Flow Summary | πŸ’§ | | rgov | `signoff-gate` | Signoff Gate | βš–οΈ | | rgov | `governance-circuit` | Governance Circuit | πŸ”€ | | rinbox | `thread-feed` | Thread Feed | πŸ“¬ | | rmaps | `location-pin` | Location Pin | πŸ“ | | rmaps | `route-summary` | Route Summary | πŸ—ΊοΈ | | rnetwork | `contact-card` | Contact Card | πŸ‘€ | | rnotes | `vault-note` | Vault Note | πŸ—’οΈ | | rphotos | `album-card` | Album Card | πŸ–ΌοΈ | | rsocials | `post-draft` | Post Draft | ✏️ | | rtasks | `task-counter` | Task Counter | πŸ“‹ | | rtasks | `due-today` | Due Today | ⏰ | | rtasks | `resource-coverage` | Resource Coverage | 🎯 | | rtime | `commitment-meter` | Commitment Meter | ⏳ | | rtime | `weaving-coverage` | Weaving Coverage | 🧢 | | rwallet | `balance-card` | Balance Card | πŸ’° | | rwallet | `token-balance` | Token Balance | πŸͺ™ | --- ## Proposed new applets (51 total across 7 rApps) Port type legend: `trigger` (flow control pulse), `data` (payload), `text`, `number`, `boolean`, `json`, `date`. Colors follow existing rApp accents (`modules//applets.ts`). --- ### rsocials β€” Campaign Planner (source: `modules/rsocials/schemas.ts`, `CampaignNodeType`) Planner nodes represent the building blocks of a campaign *structure* (not runtime flow). | # | id | label | icon | color | input ports | output ports | compact preview | |---|---|---|---|---|---|---|---| | 1 | πŸ†• `planner-post` | Campaign Post | πŸ“ | #db2777 | `content:text` | `post:json` | platform + char-count + preview | | 2 | πŸ†• `planner-thread` | Thread | 🧡 | #db2777 | `tweets:json` | `thread:json` | tweet count + platform | | 3 | πŸ†• `planner-platform` | Platform Channel | πŸ“‘ | #db2777 | `post:json` | `scheduled:json` | platform logo + cadence | | 4 | πŸ†• `planner-audience` | Audience | πŸ‘₯ | #db2777 | `segments:json` | `target:json` | segment count + size | | 5 | πŸ†• `planner-phase` | Campaign Phase | πŸ—“οΈ | #db2777 | `trigger:trigger` | `next:trigger` | phase name + date range | | 6 | πŸ†• `planner-goal` | Campaign Goal | 🎯 | #db2777 | β€” | `metric:data` | KPI name + target | | 7 | πŸ†• `planner-message` | Key Message | πŸ’¬ | #db2777 | β€” | `copy:text` | message + tone | | 8 | πŸ†• `planner-tone` | Brand Tone | 🎨 | #db2777 | β€” | `style:data` | tone name + examples | | 9 | πŸ†• `planner-brief` | Creative Brief | πŸ“‹ | #db2777 | β€” | `brief:json` | objective + constraints | --- ### rsocials β€” Campaign Workflow (source: `modules/rsocials/schemas.ts`, `CAMPAIGN_NODE_CATALOG`) Workflow nodes are n8n-style runtime steps. These already have full typed I/O in the schema. | # | id | label | icon | color | input ports | output ports | |---|---|---|---|---|---|---| | 10 | πŸ†• `wf-campaign-start` | Campaign Start | β–Ά | #3b82f6 | β€” | `trigger:trigger` | | 11 | πŸ†• `wf-schedule-trigger` | Schedule Trigger | ⏰ | #3b82f6 | β€” | `trigger:trigger`, `timestamp:data` | | 12 | πŸ†• `wf-webhook-trigger` | Webhook Trigger | πŸ”— | #3b82f6 | β€” | `trigger:trigger`, `payload:data` | | 13 | πŸ†• `wf-wait-duration` | Wait Duration | ⏳ | #f59e0b | `trigger:trigger` | `done:trigger` | | 14 | πŸ†• `wf-wait-approval` | Wait for Approval | βœ‹ | #f59e0b | `trigger:trigger` | `approved:trigger`, `rejected:trigger` | | 15 | πŸ†• `wf-engagement-check` | Engagement Check | πŸ“ˆ | #a855f7 | `trigger:trigger`, `metrics:data` | `above:trigger`, `below:trigger` | | 16 | πŸ†• `wf-time-window` | Time Window | πŸ•“ | #a855f7 | `trigger:trigger` | `in-window:trigger`, `outside:trigger` | | 17 | πŸ†• `wf-post-to-platform` | Post to Platform | πŸ“€ | #10b981 | `trigger:trigger`, `content:data` | `done:trigger`, `postId:data` | | 18 | πŸ†• `wf-cross-post` | Cross-Post | πŸ”€ | #10b981 | `trigger:trigger`, `content:data` | `done:trigger`, `results:data` | | 19 | πŸ†• `wf-publish-thread` | Publish Thread | 🧡 | #10b981 | `trigger:trigger` | `done:trigger`, `threadId:data` | | 20 | πŸ†• `wf-send-newsletter` | Send Newsletter | βœ‰οΈ | #10b981 | `trigger:trigger`, `content:data` | `done:trigger`, `campaignId:data` | | 21 | πŸ†• `wf-post-webhook` | POST Webhook | πŸ“‘ | #10b981 | `trigger:trigger`, `data:data` | `done:trigger`, `response:data` | > **Color groups:** trigger=blue `#3b82f6`, delay=amber `#f59e0b`, condition=purple `#a855f7`, action=emerald `#10b981`. Matches existing workflow palette. --- ### rminders β€” Automation Canvas (source: `modules/rminders/schemas.ts`, `NODE_CATALOG`) | # | id | label | icon | color | input ports | output ports | |---|---|---|---|---|---|---| | 22 | πŸ†• `auto-trigger-cron` | Cron Schedule | ⏰ | #3b82f6 | β€” | `fire:trigger` | | 23 | πŸ†• `auto-trigger-data-change` | Data Change | πŸ”„ | #3b82f6 | β€” | `fire:trigger`, `delta:data` | | 24 | πŸ†• `auto-trigger-webhook` | Webhook Incoming | πŸ”— | #3b82f6 | β€” | `fire:trigger`, `payload:data` | | 25 | πŸ†• `auto-trigger-manual` | Manual Trigger | πŸ‘† | #3b82f6 | β€” | `fire:trigger` | | 26 | πŸ†• `auto-trigger-proximity` | Location Proximity | πŸ“ | #3b82f6 | β€” | `enter:trigger`, `exit:trigger` | | 27 | πŸ†• `auto-condition-compare` | Compare Values | βš–οΈ | #a855f7 | `trigger:trigger`, `a:data`, `b:data` | `true:trigger`, `false:trigger` | | 28 | πŸ†• `auto-condition-geofence` | Geofence Check | 🌐 | #a855f7 | `trigger:trigger`, `location:data` | `inside:trigger`, `outside:trigger` | | 29 | πŸ†• `auto-condition-time-window` | Time Window | πŸ•“ | #a855f7 | `trigger:trigger` | `in-window:trigger`, `outside:trigger` | | 30 | πŸ†• `auto-condition-data-filter` | Data Filter | πŸ” | #a855f7 | `trigger:trigger`, `data:data` | `pass:trigger`, `block:trigger` | | 31 | πŸ†• `auto-action-send-email` | Send Email | βœ‰οΈ | #10b981 | `trigger:trigger` | `done:trigger` | | 32 | πŸ†• `auto-action-post-webhook` | POST Webhook | πŸ“‘ | #10b981 | `trigger:trigger`, `body:data` | `done:trigger`, `response:data` | | 33 | πŸ†• `auto-action-create-event` | Create Calendar Event | πŸ“… | #10b981 | `trigger:trigger` | `done:trigger`, `eventId:data` | | 34 | πŸ†• `auto-action-create-task` | Create Task | βœ… | #10b981 | `trigger:trigger` | `done:trigger`, `taskId:data` | | 35 | πŸ†• `auto-action-send-notification` | Send Notification | πŸ”” | #10b981 | `trigger:trigger` | `done:trigger` | | 36 | πŸ†• `auto-action-update-data` | Update Data | πŸ’Ύ | #10b981 | `trigger:trigger`, `patch:data` | `done:trigger` | --- ### rflows β€” Funnel Canvas (source: `modules/rflows/lib/types.ts`, `FlowNode`) Three node types with typed flow ports: `outflow / inflow / overflow / spending`. Already has a coarse `flow-summary` applet β€” propose splitting into per-node types. | # | id | label | icon | color | input ports | output ports | |---|---|---|---|---|---|---| | 37 | πŸ†• `flow-source` | Income Source | πŸ’§ | #10b981 | β€” | `outflow:number` | | 38 | πŸ†• `flow-funnel` | Funnel | πŸ”½ | #60a5fa | `inflow:number` | `overflow:number`, `spending:number` | | 39 | πŸ†• `flow-outcome` | Outcome | 🎯 | #8b5cf6 | `inflow:number` | `overflow:number` | > **Note:** port colors already defined in `PORT_DEFS` β€” reuse exactly so canvas-level wire colors match. Port type is `number` (monthly flow rate) not `data`. --- ### rgov β€” Governance Circuit (source: `modules/rgov/components/folk-gov-circuit.ts`, `GOV_NODE_CATALOG`) These already exist as `folk-gov-*` custom elements rendered by the main canvas. But they are **not registered** as AppletDefinitions β€” which means users can only add them from within the circuit mini-canvas, not from the main canvas palette. Low-lift win: register the 8 that aren't already wrapped. | # | id | label | icon | color | input ports | output ports | notes | |---|---|---|---|---|---|---|---| | 40 | 🟑 `gov-binary` | Signoff | βœ“ | #7c3aed | `in:trigger` | `out:trigger` | duplicates existing `signoff-gate` applet β€” deprecate one? | | 41 | πŸ†• `gov-threshold` | Threshold | πŸ“Š | #0891b2 | `in:number` | `out:trigger` | trips when input β‰₯ N | | 42 | πŸ†• `gov-knob` | Knob | 🎚️ | #b45309 | `in:trigger` | `out:number` | manual dial value | | 43 | πŸ†• `gov-project` | Project | πŸ“ | #10b981 | `in:trigger` | `out:data` | project card as flow node | | 44 | πŸ†• `gov-quadratic` | Quadratic Vote | ⊿ | #14b8a6 | `in:data` | `out:number` | quadratic tally | | 45 | πŸ†• `gov-conviction` | Conviction Vote | ⏱️ | #d97706 | `in:data` | `out:number` | conviction curve | | 46 | πŸ†• `gov-multisig` | Multisig Approval | πŸ” | #6366f1 | `in:trigger` | `out:trigger` | M-of-N signers | | 47 | πŸ†• `gov-sankey` | Sankey Flow | 〰️ | #f43f5e | `in:data` | `out:data` | fund-routing viz | > **Alternative:** register as thin AppletDefinition wrappers that delegate `renderCompact` to the existing `folk-gov-*` component. Keeps rendering logic in one place. Recommend this approach. --- ### rtime β€” Weave Canvas (source: `modules/rtime/components/folk-timebank-app.ts`) | # | id | label | icon | color | input ports | output ports | |---|---|---|---|---|---|---| | 48 | πŸ†• `weave-commitment` | Commitment | 🀝 | #7c3aed | `trigger:trigger` | `fulfilled:trigger`, `progress:number` | | 49 | πŸ†• `weave-task` | Weave Task | 🧡 | #7c3aed | `assignee:data`, `trigger:trigger` | `done:trigger` | > Existing `commitment-meter` + `weaving-coverage` applets aggregate all commitments. These new ones represent *individual* commitment/task nodes droppable on canvas. --- ### rnetwork β€” CRM Graph (source: `modules/rnetwork/components/folk-crm-view.ts`, `CrmGraphNode`) Existing `contact-card` covers the person case well. Propose one additional for organizations. | # | id | label | icon | color | input ports | output ports | |---|---|---|---|---|---|---| | 50 | πŸ†• `org-card` | Organization | 🏒 | #4f46e5 | β€” | `members:json` | company card w/ member count | --- ### rchoices β€” other vote types Currently only `vote-tally`. rChoices supports multiple vote types β€” each deserves its own applet. | # | id | label | icon | color | input ports | output ports | |---|---|---|---|---|---|---| | 51 | πŸ†• `choice-conviction` | Conviction Vote | ⏱️ | #7c3aed | `submit:data` | `result:data` | | 52 | πŸ†• `choice-rank` | Ranked Choice | πŸ† | #7c3aed | `submit:data` | `winner:data`, `round:data` | | 53 | πŸ†• `choice-spider` | Spider Vote | πŸ•ΈοΈ | #7c3aed | `submit:data` | `profile:data` | > *These overlap with existing `folk-choice-*` custom elements the main canvas already renders β€” same pattern as rgov: wrap into AppletDefinitions so they appear in the palette.* --- ## Implementation order (proposed) 1. **rgov** (Β§40-47) β€” easiest, already custom elements. 🟑 ones delegate; πŸ†• ones wrap existing components. ~1h. 2. **rflows** (Β§37-39) β€” only 3 types, clean port model already in `PORT_DEFS`. ~1h. 3. **rsocials planner** (Β§1-9) β€” 9 types, shared palette color. ~2h. 4. **rminders automation** (Β§22-36) β€” 15 types with clean catalog. ~2-3h (lots of glyph decisions). 5. **rsocials workflow** (Β§10-21) β€” 12 types, similar to rminders. ~2h. 6. **rtime, rnetwork, rchoices extras** (Β§48-53) β€” cleanup round. ~1h. Total: ~10 hours of focused work, spread across 4-6 PRs. One rApp per PR for clean rollback. --- ## Open questions for review 1. **Naming prefix.** Should I use `planner-*` / `wf-*` / `auto-*` / `gov-*` / `flow-*` prefixes, or namespace only by `moduleId` (registry already does `moduleId:appletId`)? Prefixes improve readability in the palette; namespacing is already handled. **Default: use prefixes for readability.** 2. **Duplicate deprecation.** rgov `signoff-gate` and proposed `gov-binary` are the same concept. Keep one? 3. **Port name `trigger`.** Borrowed from the campaign workflow schema. Alternative: `pulse` or `step`. Consistent with automation catalog. 4. **Icons.** Most proposed icons are emoji for compactness. Some rApps prefer Lucide SVG icons β€” confirm preference. 5. **Compact preview.** For every πŸ†•, I've described the preview in prose. Want me to mock the actual `renderCompact()` HTML for one rApp as a sample before I scale? 6. **Live data.** Several proposed applets would benefit from `fetchLiveData()` pulling real metrics (engagement counts, commitment progress). Add at first implementation or in a second pass? --- *Generated: 2026-04-17. Review and modify above; I'll implement per Β§Implementation order once approved.*