Revenue-Share Contract Simulator
Overview
Kelly Revenue-Share Simulator is a Busabase Cloud App-in-Skill. Its canonical
product surface is the AirApp in Busabase, not a separate local-data
product. The same Hono source supports an explicitly requested local preview
with OAuth connection bootstrap. It is a control-panel/workspace for a deal
analyst modeling revenue-based-financing (RBF) deals: a funder advances a
principal to an SME business (e.g. a bubble tea, gym, or hotpot restaurant
chain) in exchange for a share of monthly revenue until a repayment cap
multiple is reached or the term ends. The analyst tunes inputs, sees the
projected cash flow and cumulative repayment, and records an underwriting
decision per named scenario — then saves several scenarios for side-by-side
comparison.
This is generic, brand-free tooling: business names in seed data are
placeholder archetypes (bubble tea chain, gym chain, hotpot restaurant), not
real companies.
This is a direct-manipulation control panel, not a review-then-approve
queue: creating, editing, or deleting a scenario, and recording the
underwriting decision, are all direct writes made straight through
busabase-sdk from the browser — the same way kelly-lead-funnel's kanban
stage moves and kelly-agent-builder's agent-config CRUD work. There is no
AI-authored draft to approve and no separate execute/decisions step; the
projected result (cash_flow_payout_multiple, effective_annual_cost_pct,
risk flags) is pure/derived from a scenario's saved inputs and recomputed on
every read (content/kelly-revshare-simulator-app/app/js/simulator-model.js, ported from the retired
lib/simulate.ts).
Default behavior is AirApp-first. Unless the user explicitly asks only for
explanation, give the user the clickable AirApp URL. Start localhost only
when local preview/debugging is explicitly requested; it uses the same
Busabase resources and never offers another data provider. Use chat-only
mode only when the user says "纯聊天", "chat only", "不要打开 UI", or similar.
Mandatory Dependencies
- Read and follow
$kelly-app-skill-creator for product behavior, visual
quality, responsive layout, and the complete canonical content/kelly-revshare-simulator-app/ artifact.
- Read and follow
$busabase for connection, target Space, node discovery,
ChangeRequests, review, and merge behavior.
- Read and follow
$busabase-app-creator for resource modeling, AirApp
runtime limits, security, validation, and deployment.
If a dependency is unavailable, preserve this skill's artifact and product
contracts, stop before the unavailable Busabase operation, and report the
exact missing dependency. Do not invent a second data backend.
App UI Screenshots
Boundary
- Pure deterministic math over analyst-supplied inputs. The app never
fetches live revenue, banking, or payment data, and never disburses,
transfers, or moves money.
- The AirApp reads and writes its own Busabase Bases only; there is no
execution/merge step beyond the direct write itself. Deleting a scenario
always requires an explicit Busabase review step before it merges (the
platform rejects
autoMerge on record deletes) — on a standalone local
preview the app completes that review+merge itself immediately since the
local operator is the trusted actor; from a deployed AirApp the delete
request stays pending for a human to review directly in Busabase.
- Risk flags are neutral, rule-based observations — never automated
approve/reject decisions. A human always makes the underwriting call.
- Generic, brand-neutral tool: never hardcode or reference a specific real
company or SME name in code, templates, or docs.
Busabase Resources
Two Bases under one application Folder (kelly-revshare-simulator),
declared in content/kelly-revshare-simulator-app/app/js/config.js and the generated template sidecars under content/:
scenarios: one row per saved deal scenario — the analyst's raw inputs
(business type, average monthly revenue, revenue volatility, principal,
initial and step-down revenue-share rates, repayment cap multiple, term)
and the underwriting decision (decision-action, decision-note,
decided-at). The projected cash-flow/repayment result (monthly
projection, Cash-Flow Payout Multiple, effective annualized cost, risk
flags) is never stored — it is pure/derived from these inputs and
recomputed on every read.
settings: sanitized config (base currency, underwriting policy
thresholds), one row keyed by kind.
Resources provision lazily through an idempotent Busabase ChangeRequest the
first time the app runs in a Space; see references/ui-schema.md for exact
field shapes.
Domain Model
Inputs per scenario (content/kelly-revshare-simulator-app/app/js/simulator-model.js simulateScenario,
ported verbatim from the retired lib/simulate.ts):
business_type, avg_monthly_revenue, revenue_volatility_pct
principal (proposed advance)
initial_share_rate_pct (revenue share until breakeven)
step_down_share_rate_pct (reduced share rate after principal is recovered)
repayment_cap_multiple (e.g. 1.5x principal — the total obligation cap)
term_months
Computed, always fresh, never stored:
monthly[]: month-by-month revenue, share rate, payment, cumulative
repayment, and breakeven/cap flags.
cash_flow_payout_multiple: a P/E-like ratio — principal ("price") divided
by the annualized repayment cash flow ("earnings"). Lower is faster payback
for the funder.
effective_annual_cost_pct: the annualized cost implied by paying back
total_repayment over the months elapsed, expressed like an APR.
risk_flags[]: cap_not_reached, merchant_cost_too_high,
high_revenue_volatility, thin_term_buffer — deterministic, rule-based,
never automated decisions.
No randomness, no ML — the same scenario input always produces the same
result. Read references/ui-schema.md before editing the app or
content/kelly-revshare-simulator-app/app/js/simulator-model.js.
Direct Scenario Writes
There is no decisions/approval bucket. Every scenario action writes straight
through busabase-sdk from the browser (content/kelly-revshare-simulator-app/app/js/providers/busabase-provider.js):
- Create / Update:
bases.createChangeRequest / records.changeRequest
with the analyst's saved inputs.
- Record underwriting decision:
records.changeRequest sets
decision-action/decision-note/decided-at directly on the scenario's
own record — approve_underwriting, needs_revision, reject, or
cleared back to undecided.
- Delete:
records.changeRequest with operation: "delete". Busabase
always requires an explicit review before a delete merges (autoMerge is
rejected server-side for deletes, unlike create/update) — from a
standalone local preview the app reviews and merges its own delete request
immediately after submitting it (the trusted local operator approving
their own action); from a deployed AirApp the request stays pending for a
human to review directly in Busabase.
From a standalone local preview create/update/decision writes merge
immediately (trusted operator); from the deployed AirApp they create a
pending ChangeRequest for the trusted process to merge, per the AirApp
boundary in $busabase-app-creator.
Demo Mode
?demo=1 opens a deterministic, fully offline mock batch of four
scenarios (bubble tea chain, gym chain, hotpot restaurant, one
deliberately risky example that trips the risk flags) for documentation
and screenshots. It never reads or writes Busabase and never claims a real
connection; demo create/edit/delete/decision actions only update the
in-memory snapshot already rendered in the browser tab.
?demo=scenarios and ?demo=comparison select named mock scenes;
?demo=detail opens the first mock scenario's detail pane.
lang=en or lang=zh forces UI chrome language for screenshots.
UI language: support English and Chinese chrome with Auto default.
Local App
Default behavior is AirApp-first — give the user the clickable AirApp URL.
Start pnpm --dir content/kelly-revshare-simulator-app dev only when local preview/debugging is explicitly
requested.
Views
#/overview: portfolio-level metrics and the list of scenarios still
needing a decision.
#/scenarios: filterable scenario list (All, Undecided, Approved,
Needs Revision, Rejected).
#/scenarios/new: new scenario input form.
#/scenarios/<id>: cash-flow chart, computed metrics, risk flags, editable
inputs, the underwriting decision panel, and delete.
#/comparison: pick multiple saved scenarios for a side-by-side table.
#/settings: sanitized config summary and underwriting policy thresholds.
Completion Criteria
Finish only when:
- the skill contains the complete canonical
content/kelly-revshare-simulator-app/ project and
pnpm --dir content/kelly-revshare-simulator-app dev remains supported;
- all persistent config, state, and domain data use
busabase-sdk and the
declared resource map — no local JSON, browser storage, or provider
choice;
- Vault values and API credentials never reach browser-visible surfaces;
- local setup offers Cloud/custom URL OAuth plus the explicit Demo path,
while a deployed AirApp uses its ambient session;
- Overview, Scenarios, Comparison, and Help & Settings render on desktop and
phone widths;
pnpm --dir content/kelly-revshare-simulator-app run check and node --test pass.
Stop Conditions
Stop before consequential Busabase mutation when the target Space is
ambiguous, the current user lacks permission, or a same-slug resource is not
application-owned. Never fetch live revenue/banking/payment data or move
money from the AirApp.
1---2name: kelly-revshare-simulator3description: Busabase-backed App-in-Skill control-panel/workspace for a deal analyst to model revenue-based-financing (RBF) deals for SME businesses (retail/F&B chain stores). Use when the user invokes $kelly-revshare-simulator or /kelly-revshare-simulator, wants to model a revenue-share or merchant-cash-advance deal, project cash flow and repayment, compute a Cash-Flow Payout Multiple, effective annualized merchant cost, or compare/underwrite multiple financing scenarios. Pure deterministic math, no external calls, no real trading/payment side effects. Scenario create/edit/delete and the underwriting decision are direct writes made by the analyst, not a review/approval queue.4---56# Revenue-Share Contract Simulator78## Overview910Kelly Revenue-Share Simulator is a Busabase Cloud App-in-Skill. Its canonical11product surface is the AirApp in Busabase, not a separate local-data12product. The same Hono source supports an explicitly requested local preview13with OAuth connection bootstrap. It is a control-panel/workspace for a deal14analyst modeling revenue-based-financing (RBF) deals: a funder advances a15principal to an SME business (e.g. a bubble tea, gym, or hotpot restaurant16chain) in exchange for a share of monthly revenue until a repayment cap17multiple is reached or the term ends. The analyst tunes inputs, sees the18projected cash flow and cumulative repayment, and records an underwriting19decision per named scenario — then saves several scenarios for side-by-side20comparison.2122This is generic, brand-free tooling: business names in seed data are23placeholder archetypes (bubble tea chain, gym chain, hotpot restaurant), not24real companies.2526This is a direct-manipulation control panel, not a review-then-approve27queue: creating, editing, or deleting a scenario, and recording the28underwriting decision, are all direct writes made straight through29`busabase-sdk` from the browser — the same way `kelly-lead-funnel`'s kanban30stage moves and `kelly-agent-builder`'s agent-config CRUD work. There is no31AI-authored draft to approve and no separate execute/decisions step; the32projected result (`cash_flow_payout_multiple`, `effective_annual_cost_pct`,33risk flags) is pure/derived from a scenario's saved inputs and recomputed on34every read (`content/kelly-revshare-simulator-app/app/js/simulator-model.js`, ported from the retired35`lib/simulate.ts`).3637Default behavior is AirApp-first. Unless the user explicitly asks only for38explanation, give the user the clickable AirApp URL. Start localhost only39when local preview/debugging is explicitly requested; it uses the same40Busabase resources and never offers another data provider. Use chat-only41mode only when the user says "纯聊天", "chat only", "不要打开 UI", or similar.4243## Mandatory Dependencies44451. Read and follow `$kelly-app-skill-creator` for product behavior, visual46 quality, responsive layout, and the complete canonical `content/kelly-revshare-simulator-app/` artifact.472. Read and follow `$busabase` for connection, target Space, node discovery,48 ChangeRequests, review, and merge behavior.493. Read and follow `$busabase-app-creator` for resource modeling, AirApp50 runtime limits, security, validation, and deployment.5152If a dependency is unavailable, preserve this skill's artifact and product53contracts, stop before the unavailable Busabase operation, and report the54exact missing dependency. Do not invent a second data backend.5556## App UI Screenshots5758<table>59 <tr>60 <td width="50%"><img src="assets/screenshots/overview.webp" alt="Revenue-Share Simulator overview"></td>61 <td width="50%"><img src="assets/screenshots/scenario-detail.webp" alt="Revenue-Share Simulator scenario detail"></td>62 </tr>63 <tr>64 <td><strong>Overview</strong><br>Portfolio-level summary across saved scenarios: average effective cost, flagged deals, and deals still needing an underwriting decision.</td>65 <td><strong>Scenario detail</strong><br>Cash-flow/cumulative-repayment chart, Cash-Flow Payout Multiple, effective annualized merchant cost, risk flags, and the decision panel.</td>66 </tr>67 <tr>68 <td colspan="2" width="100%"><img src="assets/screenshots/comparison.webp" alt="Revenue-Share Simulator comparison"></td>69 </tr>70 <tr>71 <td colspan="2"><strong>Comparison</strong><br>Side-by-side table of selected scenarios' inputs, projected repayment, payout multiple, effective cost, and decisions.</td>72 </tr>73</table>7475## Boundary7677- Pure deterministic math over analyst-supplied inputs. The app never78 fetches live revenue, banking, or payment data, and never disburses,79 transfers, or moves money.80- The AirApp reads and writes its own Busabase Bases only; there is no81 execution/merge step beyond the direct write itself. Deleting a scenario82 always requires an explicit Busabase review step before it merges (the83 platform rejects `autoMerge` on record deletes) — on a standalone local84 preview the app completes that review+merge itself immediately since the85 local operator is the trusted actor; from a deployed AirApp the delete86 request stays pending for a human to review directly in Busabase.87- Risk flags are neutral, rule-based observations — never automated88 approve/reject decisions. A human always makes the underwriting call.89- Generic, brand-neutral tool: never hardcode or reference a specific real90 company or SME name in code, templates, or docs.9192## Busabase Resources9394Two Bases under one application Folder (`kelly-revshare-simulator`),95declared in `content/kelly-revshare-simulator-app/app/js/config.js` and the generated template sidecars under `content/`:9697- `scenarios`: one row per saved deal scenario — the analyst's raw inputs98 (business type, average monthly revenue, revenue volatility, principal,99 initial and step-down revenue-share rates, repayment cap multiple, term)100 and the underwriting decision (`decision-action`, `decision-note`,101 `decided-at`). The projected cash-flow/repayment result (monthly102 projection, Cash-Flow Payout Multiple, effective annualized cost, risk103 flags) is never stored — it is pure/derived from these inputs and104 recomputed on every read.105- `settings`: sanitized config (base currency, underwriting policy106 thresholds), one row keyed by `kind`.107108Resources provision lazily through an idempotent Busabase ChangeRequest the109first time the app runs in a Space; see `references/ui-schema.md` for exact110field shapes.111112## Domain Model113114Inputs per scenario (`content/kelly-revshare-simulator-app/app/js/simulator-model.js` `simulateScenario`,115ported verbatim from the retired `lib/simulate.ts`):116117- `business_type`, `avg_monthly_revenue`, `revenue_volatility_pct`118- `principal` (proposed advance)119- `initial_share_rate_pct` (revenue share until breakeven)120- `step_down_share_rate_pct` (reduced share rate after principal is recovered)121- `repayment_cap_multiple` (e.g. 1.5x principal — the total obligation cap)122- `term_months`123124Computed, always fresh, never stored:125126- `monthly[]`: month-by-month revenue, share rate, payment, cumulative127 repayment, and breakeven/cap flags.128- `cash_flow_payout_multiple`: a P/E-like ratio — principal ("price") divided129 by the annualized repayment cash flow ("earnings"). Lower is faster payback130 for the funder.131- `effective_annual_cost_pct`: the annualized cost implied by paying back132 `total_repayment` over the months elapsed, expressed like an APR.133- `risk_flags[]`: `cap_not_reached`, `merchant_cost_too_high`,134 `high_revenue_volatility`, `thin_term_buffer` — deterministic, rule-based,135 never automated decisions.136137No randomness, no ML — the same scenario input always produces the same138result. Read `references/ui-schema.md` before editing the app or139`content/kelly-revshare-simulator-app/app/js/simulator-model.js`.140141## Direct Scenario Writes142143There is no decisions/approval bucket. Every scenario action writes straight144through `busabase-sdk` from the browser (`content/kelly-revshare-simulator-app/app/js/providers/busabase-provider.js`):145146- **Create** / **Update**: `bases.createChangeRequest` / `records.changeRequest`147 with the analyst's saved inputs.148- **Record underwriting decision**: `records.changeRequest` sets149 `decision-action`/`decision-note`/`decided-at` directly on the scenario's150 own record — `approve_underwriting`, `needs_revision`, `reject`, or151 cleared back to undecided.152- **Delete**: `records.changeRequest` with `operation: "delete"`. Busabase153 always requires an explicit review before a delete merges (`autoMerge` is154 rejected server-side for deletes, unlike create/update) — from a155 standalone local preview the app reviews and merges its own delete request156 immediately after submitting it (the trusted local operator approving157 their own action); from a deployed AirApp the request stays pending for a158 human to review directly in Busabase.159160From a standalone local preview create/update/decision writes merge161immediately (trusted operator); from the deployed AirApp they create a162pending ChangeRequest for the trusted process to merge, per the AirApp163boundary in `$busabase-app-creator`.164165## Demo Mode166167- `?demo=1` opens a deterministic, fully offline mock batch of four168 scenarios (bubble tea chain, gym chain, hotpot restaurant, one169 deliberately risky example that trips the risk flags) for documentation170 and screenshots. It never reads or writes Busabase and never claims a real171 connection; demo create/edit/delete/decision actions only update the172 in-memory snapshot already rendered in the browser tab.173- `?demo=scenarios` and `?demo=comparison` select named mock scenes;174 `?demo=detail` opens the first mock scenario's detail pane.175- `lang=en` or `lang=zh` forces UI chrome language for screenshots.176177UI language: support English and Chinese chrome with `Auto` default.178179## Local App180181Default behavior is AirApp-first — give the user the clickable AirApp URL.182Start `pnpm --dir content/kelly-revshare-simulator-app dev` only when local preview/debugging is explicitly183requested.184185## Views186187- `#/overview`: portfolio-level metrics and the list of scenarios still188 needing a decision.189- `#/scenarios`: filterable scenario list (`All`, `Undecided`, `Approved`,190 `Needs Revision`, `Rejected`).191- `#/scenarios/new`: new scenario input form.192- `#/scenarios/<id>`: cash-flow chart, computed metrics, risk flags, editable193 inputs, the underwriting decision panel, and delete.194- `#/comparison`: pick multiple saved scenarios for a side-by-side table.195- `#/settings`: sanitized config summary and underwriting policy thresholds.196197## Completion Criteria198199Finish only when:200201- the skill contains the complete canonical `content/kelly-revshare-simulator-app/` project and202 `pnpm --dir content/kelly-revshare-simulator-app dev` remains supported;203- all persistent config, state, and domain data use `busabase-sdk` and the204 declared resource map — no local JSON, browser storage, or provider205 choice;206- Vault values and API credentials never reach browser-visible surfaces;207- local setup offers Cloud/custom URL OAuth plus the explicit Demo path,208 while a deployed AirApp uses its ambient session;209- Overview, Scenarios, Comparison, and Help & Settings render on desktop and210 phone widths;211- `pnpm --dir content/kelly-revshare-simulator-app run check` and `node --test` pass.212213## Stop Conditions214215Stop before consequential Busabase mutation when the target Space is216ambiguous, the current user lacks permission, or a same-slug resource is not217application-owned. Never fetch live revenue/banking/payment data or move218money from the AirApp.