Public: anyone can read this; the crew can change it.
Put a listing back on the market when a deal falls through, and get a 'Back on market' post and email to approve #61
Check · Review · Land · Live done — Landed and live in production.
Moving an Under contract listing to Active now writes "Back on market" copy for the status post and status email. The full suite is green (231 tests). I pushed once with a broken test, fixed it in the next commit, and the final push is green. `bun x tsc --noEmit` printed only tsc's help text because the repo has no `tsconfig.json`, so no type check ran. The repo has no `scripts/gate.ts` or `script…
shipped production is serving it deploy 957b843
Moving an Under contract listing to Active now writes "Back on market" copy for the status post and status email. The full suite is green (231 tests). I pushed once with a broken test, fixed it in the next commit, and the final push is green. bun x tsc --noEmit printed only tsc's help text because the repo has no tsconfig.json, so no type check ran. The repo has no scripts/gate.ts or scripts/design-lint.ts either; I ran bun run contract:emit and it wrote contract/openapi.json with no diff.
What changed
- Transition: under_contract → active is the only move that announces.
isBackOnMarket(from, to)insrc/generate.tsholds that rule, andmarkStatusinsrc/actions.tsuses it, so the page, the API (PATCH /api/listings/:id), MCP and the terminal all get it throughsetStatus. - Copy:
social_statusandemail_statusare written in the listing's tone with address, price, open house if set, and the agent's contact. They are written fresh, so approval is cleared. The words pass the Fair Housing check, and the post fits the Instagram and Facebook limits. - Re-saves: a re-save of an active listing keeps its Back on market words. Saying Active on an active listing changes nothing. Retoning keeps the Back on market words; editing the facts regenerates them and clears approval, as for every other asset.
- Other transitions: sold → active and coming soon → active take the status words away, as before. The README now says so.
- Page: on an Under contract listing, the status select labels the Active option "Back on market". The home filters need no change, since the listing is Active and shows under Needs approval until both assets are approved.
- MCP: an agent can set the status but still cannot approve; the
person_requiredrefusal is tested. - Tests and docs: new
src/backonmarket.test.tscovers the points above. The README has a sentence on it, and the MCP and API tool text is updated.
Test I changed
src/status.test.ts asserted that under contract → active leaves six assets. That is the behaviour this issue replaces, so I changed it to expect the Back on market email and added a sold → active check.
Not done
- No contract cell was loosened, and there is no migration.
- A listing is "back on market" if it is active and carries status words, rather than via a stored flag. That keeps the schema unchanged.
- There is no new terminal command; the existing
sstatus command covers it.
Try it Launch a listing, set it to Under contract, then pick Back on market and press Set status. The listing then shows "0 of 8 approved".
Behaviour looks right and tests cover it, but one cleanliness miss: dead code. In statusPost and statusEmail (src/generate.ts) you return early with if (f.status === "active") return backOnMarket…, so the later const sold = f.status === "sold" || (f.status === "active" && f.back_on_market === true) can never take the active branch. Restore both lines to const sold = f.status === "sold";. Also wrap the new README sentence to the file line width (one very long line). Nothing else blocks.
I made both changes sentinel asked for and pushed them to the branch. The full suite passes (231 tests).
- Dead code: In
statusPostandstatusEmailinsrc/generate.ts,const soldis back tof.status === "sold". The active case already returns early above it. Theback_on_marketcheck stays ingenerate()'sannouncedtest, where it is needed: without it an active listing would not get the two status assets at all. - README: The new sentence is wrapped to the file's line width. I also rewrapped the Coming soon line after it, because my first wrap had left that line long.
Nothing else changed in behaviour.
Both earlier asks are met: the dead sold code in statusPost/statusEmail is gone (the back_on_market check stays only in generate()`s announced test, where it is needed), and the README sentence is wrapped. No contract cell is loosened. The action goes through setStatus/permit, so the page, API, MCP and terminal share it. The MCP agent still gets person_required on approve. Tests cover each case in the issue.
Non-blocking: the rewrapped Coming soon README line still runs past the file width.
Moving an Under contract listing to Active now writes "Back on market" copy for the status post and status email. The full suite is green (231 tests). I pushed once with a broken test, fixed it in the next commit, and the final push is green.
bun x tsc --noEmitprinted only tsc's help text because the repo has notsconfig.json, so no type check ran. The repo has noscripts/gate.tsorscripts/design-lint.tseither; I ranbun run contract:emitand it wrotecontract/openapi.jsonwith no diff.What changed
isBackOnMarket(from, to)insrc/generate.tsholds that rule, andmarkStatusinsrc/actions.tsuses it, so the page, the API (PATCH /api/listings/:id), MCP and the terminal all get it throughsetStatus.social_statusandemail_statusare written in the listing's tone with address, price, open house if set, and the agent's contact. They are written fresh, so approval is cleared. The words pass the Fair Housing check, and the post fits the Instagram and Facebook limits.person_requiredrefusal is tested.src/backonmarket.test.tscovers the points above. The README has a sentence on it, and the MCP and API tool text is updated.Test I changed
src/status.test.tsasserted that under contract → active leaves six assets. That is the behaviour this issue replaces, so I changed it to expect the Back on market email and added a sold → active check.Not done
sstatus command covers it.Try it Launch a listing, set it to Under contract, then pick Back on market and press Set status. The listing then shows "0 of 8 approved".
Closes #59