# 起 + D walkthrough — every issue the founder raised (2026-09-03) and how it is fixed

The founder walked 起 and D as a member and reported everything below. This is the working list:
each item names the fix, the file, and who did it. Nothing here is a paraphrase — the quoted
words are his.

## 0 · Blocking

| # | Issue | Fix | Status |
|---|---|---|---|
| A1 | Saving any card 500s: `UniqueConstraintViolationException … Duplicate entry '3518-1'` | An admin RESET soft-deletes the cycle, but the row keeps its `(lead_id, cycle_no)` in the unique index, so `start()` could not see it and re-inserted. `LearningJourneyRepository::start()` now purges trashed cycles inside the same transaction; Shawn's leftover row purged. | **done** |

## 1 · Shared UX (the frame, not the words)

| # | Issue (his words) | Fix | File |
|---|---|---|---|
| B1 | *"only show the description at left, but right side already show since early … if info not yet describe, then dun show at right"* — at 「认识 Ryan」 the drawing already showed the target card, the formula, +958 | The ledger's reveal order must equal the POINT order, and each card appears empty when introduced and fills when its point explains it: target card empty at 「目标是一个数字」 → fills at 「Ryan 的目标是多少」; formula empty at 「被动收入怎么算」 → fills at 「买对的房…」; Ryan's card appears at 「认识 Ryan」 and nothing later leaks earlier | `Viz/FreedomLedger.vue`, `content/mindset.js` |
| B2 | *"i dun like u got two next button (one of sub section, one for main section)"* + *"extra materials at bottom … people might be confused and dunno need to drag down … next button should be at most bottom right"* | ONE next control per screen, at the very bottom right, AFTER every extra block. `PointStepper` gained a `#below` slot; the stage/mindset screens put their tool cards, lesson shelf and CTA in it; the old screen-level nav is gone wherever a stepper owns the screen | `Components/Road/PointStepper.vue`, `Road/Stage.vue`, `Mindset/MindsetStepper.vue`, `ToolsScreen.vue` |
| B3 | *"right section the color dark blue always only at D stage … if description say C, then right section dark blue should be C"* | `DmaicMap` highlights the stage the point is about: wealth→D, analyze→M·A·I, landlord→C, a2→T, area-guide→A | `Mindset/Viz/DmaicMap.vue` |
| B4 | *"got green return line back to D at right section, super confusing"* · *"should not have D′, should go back to D, you should show a flywheel"* · *"T is part of C … sustain the T which create new income and extend to D to redefine your active income and passive rental income once u complete one cycle"* | The map becomes a **flywheel**: D → M → A → I → C → T(收入变了) → back to D, with the loop labelled 「一轮走完，收入和承担都变了 → 回到 D 重新算」. D′ is never shown to a member; it stays an internal word only | `Mindset/Viz/DmaicMap.vue`, `Mindset/Viz/RoadStrip.vue`, `content/mindset.js`, `content/next.js` |
| B5 | *"press next then website move to 先算，再看房 … suddenly go down and no further instruction, how people know?"* | The promise + CTA is the stepper's own last point (inside `#below`), so 下一步 lands on it with the same transition as every other point | `Mindset/ToolsScreen.vue` |
| B6 | *"还完 ≤ 70 岁 is overlapped, confused uiux"* | Label moved off the axis; the cap sits above the bar with its own row | `Viz/TenureClock.vue` |
| B7 | *"this dsr … is so ugly, wrong uiux, nothing but show 27.7%"* | The fraction is redrawn: a real numerator/denominator stack with each commitment as its own chip, the division written out, and the result read as 「1,800 ÷ 6,500 = 27.7%」 | `Viz/DsrFraction.vue` |
| B8 | *"when talk about 小明 is E, by right right section only highlight E box and others is like light grey"* + *"why dun consider add picture and highlight like 拿时间换钱，手停口停"* | `EsbiQuadrant` dims every box but the active one and prints the one-line meaning under it | `Mindset/Viz/EsbiQuadrant.vue` |
| B9 | *"you ask me to choose one of the 3 options, but no impact/effect after click"* | Picking a goal locks it in visibly (the chosen card fills, the other two grey out, a line says what it means for the plan's Goal step) | `Viz/ThreeGoals.vue` |
| B10 | *"keep mention 你的天花板, means what? direct translate from english?"* | Reworded throughout: 「两个上限，取小的那个」 — 「银行最多借你到 X」/「你的现金最多买到 Y」/「所以你能看的价位是 Y」 | `Viz/TwoCeilings.vue`, `content/define.js` |

## 2 · Copy rules (apply to every station, added to content-rules.md)

| # | Rule | Why |
|---|---|---|
| C1 | **Never say 「课程」** (nor 「书」). Say 「我们的做法」/「这条路的规矩」, or state the rule with no source at all | *"mention 课程, why mention it, same stupid mistake like mention book"* |
| C2 | **Never use a letter or acronym alone** — 「Employee（打工）」 on every use, not 「E」; same for ESBI, DSR, MoF, COCR | *"dun mention E and I, need to mention Employee (E) like that, people might not remember what is E"* |
| C3 | **Every calculation is shown step by step**, one step per line, each line labelled — never a chain like `6,500 × 60% − 1,800 = 2,100 → 贷 474,000 → ÷ 90% → 527,000` | *"is confusing, people dunno how to read it, in this course, all these calculation do it step by step to show, easier understand, make it a rule"* |
| C4 | **Chinese must read as Chinese**, never a translated English sentence (「银行肯借多少是一根柱子」, 「算辞职撑几个月时它是分母」, 「你的天花板」 all failed) | *"your grammar and explanation reasoning is really bad"* |
| C5 | **Say who Ryan is** wherever a screen first leans on him, in the same sentence | *"always mention ryan do this and do that, people dunno who is ryan"* |
| C6 | **A claim that raises a question answers it on the same screen** (why not three units in four years; why the page is blank for a negative-cash-flow unit) | *"no explanation at all"* |

## 3 · Content corrections the founder supplied (facts, not wording)

| # | Where | What must be said |
|---|---|---|
| D1 | D · 年龄 | An older buyer gets a shorter tenure → a higher instalment. That is exactly why **ROI and cash flow matter more with age**: a 7–8 % unit at least breaks even where a 4 % one bleeds. Add the option of a **joint-name loan with a younger child** to stretch the tenure back to 35 years — and its cost: it consumes one of the child's two 90 % quotas |
| D2 | D · 谁付你薪水 | Ryan picks **Employee first**, and becomes Self-employed and Investor later: the business is started after resigning, funded by grants plus the portfolio built during the Employee years — because he does not want the company deciding his future |
| D3 | D · 谁付你薪水 | 「Resign Mode」 is retired as a member-facing name. Use **双引擎并行（Twin Active Income）**: keep the paycheck, build the second income, resign only when it stands on its own |
| D4 | D · 银行的线 | Add a reference block under the point: **DSR limits differ by bank and by income band**, with a few main Malaysian banks named |
| D5 | D · 第三间 | The RM 235,800 cash is printed **in red** as a high entry cost, and a new point teaches **Cash-on-Cash Return**: leverage the bank, maximise **OPM (Other People's Money)**, minimise the cash you put in — which is why a new project with a developer rebate usually wins on COCR. With the caveat: this never means buy anything; it must still pass 2+2+1 |
| D6 | D · 承担四格 | A credit card counts as **5 % of the outstanding balance**, not the printed minimum payment |
| D7 | D · 承担四格 | The credit-card point must not jump to guarantor loans — separate points |
| D8 | D · 清承担 | Name them: car loan, personal loan, credit card = **bad debt**; a mortgage on the right property = **good debt**. Clearing bad debt is what lifts eligibility |
| D9 | D · 几岁前 | Say why three units in four years is impossible (the signing month spends the DSR; the bank recognises rent only after 12 months, so the earliest second signing is ~4.5 years) |
| D10 | D · 提前还本 | Show the **compounding** effect, and answer: is paying extra into a **flexi loan** the same thing? |
| D11 | D · 负现金流 | Explain what "this page is blank" means instead of asserting it |
| D12 | D · KYS | Say that our **WhoPay** service can pull the report for the member |
| D13 | D · 批准函 | Correct the advice: a booking fee is normal. What you must not do is **sign the SPA assuming approval** — if the loan fails you fund it yourself, and cancelling costs a minimum **10 % of the SPA price** |
| D14 | D · 签约当月 | Show the arithmetic of the refusal, not just the ✗ |
| D15 | every station | A **member testimonial** block (Lucas on D) |
| D16 | 起 · 怎么走 | D is 「先定目标，再算银行肯借多少」 — the goal is half of D and was missing |
| D17 | 起 · 怎么走 | 「第二轮从变了的数字开始」 must be explained: after one cycle your income, commitments and recognised rent have all changed, so D is recalculated with the new numbers |
| D18 | 起 · 怎么走 | 「前后各加一站」 rewritten as a sentence a first-time reader can follow |
| D19 | 起 · 怎么走 | 「每站留一张答案卡」 rewritten: what a card is, what is on it, why the next station needs it |

## 4 · Who does what

- **Core (this session):** A1, B1–B6, B9, B10, C1 as a guard test, the shared `CalcSteps` /
  `Testimonial` / `BankDsrNote` blocks, and content-rules.md rules 15–18.
- **起 agent:** B4's copy side, B8, D16–D19, and the C rules across mindset.js.
- **D agent:** B7, D1–D14, and the C rules across define.js.
- **M · A · I · C · T agent:** the same C rules and the 课程/acronym/step-by-step sweep.
- **Validator agent (last):** walks every station's every point and reports any survivor of the
  C rules, any diagram showing what its point has not said, any acronym used bare, any chained
  calculation, and any 课程/书 mention.
