Public: anyone can read this; the crew can change it.

See each listing's days on market and its price history on the listing, the seller report and the weekly seller update #90

Merged opened this

Check · Review · Land · Live done — Landed and live in production.

Merged

Each listing now shows its days on market and its price history on the listing page, the seller report and the weekly seller update, and the home list shows the day count beside active listings. `bun test` passes (352 tests, speed test included) and `bun scripts/lint-design.ts` is clean. I could not run `bun x tsc --noEmit` because the repository has no tsconfig, so tsc only printed its help. The…

shipped production is serving it deploy 957b843

opened this

Each listing now shows its days on market and its price history on the listing page, the seller report and the weekly seller update, and the home list shows the day count beside active listings. bun test passes (352 tests, speed test included) and bun scripts/lint-design.ts is clean. I could not run bun x tsc --noEmit because the repository has no tsconfig, so tsc only printed its help. The issue's scripts/design-lint.ts is actually scripts/lint-design.ts.

What changed

  • src/market.ts (new): pure, dates only.

- daysOnMarket counts from the day the listing first went active to today. It stops at the day it left the market (Under contract, Sold, Withdrawn or Expired). - A listing launched today reads "0 days", and a clock before the list date never goes negative. - Coming soon does not count, and Back on market clears the end day so the count resumes from the original list date. - It also builds the price history (each entry with its change from the one before) and the plain-text lines used by the report and the seller update.

  • src/db.ts:

- One new migration adds listing.listed_on and listing.market_ended_on and a price_history table. - Existing listings are backfilled. Listed-on is the day created (unless Coming soon). Ended-on is the day last touched, if the listing is off the market. - Each existing listing gets one entry from its current price. If it has a was_price, it gets two: the was-price on the creation date, then the current price. A sold listing with a sold price also gets a sold entry.

  • src/actions.ts:

- Launch records the list price. - Editing the price on Edit facts records a price change, raise or cut. - Changing status updates the market dates, and the sold-price entry follows the Sold status. - The listing loads with a history field.

  • Pages: the listing page and seller report show "N days on market" and a Date / Price / Change table. They both call src/pages/market.ts. The home list shows an "N days" pill on active listings, and the printed report text and the weekly seller update carry the count and the history too. The new CSS classes are named in docs/design/areas/market.md.
  • Samples: 412 Alder Lane is 38 days on market with a $709,000 → $689,000 cut 17 days ago. The condo was listed 75 days ago, cut once, and sold for $752,000 12 days ago, which reads 63 days. The house is 21 days on market with no change. This is set once, last, so samples already in a database get it too.
  • README: the "For the agent" section says where to see both.
  • Tests: src/market.test.ts covers the day count across Coming soon, Back on market and Sold with fixed dates, and the history after two price changes. It also checks that all four surfaces contain both, and that the samples' numbers are believable.

Test I changed: src/comingsoon.test.ts compared whole listing rows before and after the migrations. The new migration adds two columns, so I extended its expected rows with the backfilled dates. Nothing else about the test changed.

Not done

  • The public property page is unchanged; the issue lists the agent's listing page, report and update only.
  • The sample's price cut is not wired to was_price, so Alder Lane's generated Price improvement assets are unchanged. Setting was_price would have rewritten its assets and approvals.
  • Existing listings' days on market are approximate, because the migration can only read the creation and last-touched dates.
  • #81's showings edits to the home list and listing page may conflict; I did not see them on this base.

To try it: boot the app and open / for the day pills. Then open 412 Alder Lane for the "38 days on market" line and the table, and /listings/<id>/report for the report. Change a price on Edit facts to add a history row.

Closes #87

commented

Each listing now shows its days on market and its price history on the listing page, the seller report and the weekly seller update, and the home list shows the day count beside active listings. bun test passes (352 tests, speed test included) and bun scripts/lint-design.ts is clean. I could not run bun x tsc --noEmit because the repository has no tsconfig, so tsc only printed its help. The issue's scripts/design-lint.ts is actually scripts/lint-design.ts.

What changed

  • src/market.ts (new): pure, dates only.

- daysOnMarket counts from the day the listing first went active to today. It stops at the day it left the market (Under contract, Sold, Withdrawn or Expired). - A listing launched today reads "0 days", and a clock before the list date never goes negative. - Coming soon does not count, and Back on market clears the end day so the count resumes from the original list date. - It also builds the price history (each entry with its change from the one before) and the plain-text lines used by the report and the seller update.

  • src/db.ts:

- One new migration adds listing.listed_on and listing.market_ended_on and a price_history table. - Existing listings are backfilled. Listed-on is the day created (unless Coming soon). Ended-on is the day last touched, if the listing is off the market. - Each existing listing gets one entry from its current price. If it has a was_price, it gets two: the was-price on the creation date, then the current price. A sold listing with a sold price also gets a sold entry.

  • src/actions.ts:

- Launch records the list price. - Editing the price on Edit facts records a price change, raise or cut. - Changing status updates the market dates, and the sold-price entry follows the Sold status. - The listing loads with a history field.

  • Pages: the listing page and seller report show "N days on market" and a Date / Price / Change table. They both call src/pages/market.ts. The home list shows an "N days" pill on active listings, and the printed report text and the weekly seller update carry the count and the history too. The new CSS classes are named in docs/design/areas/market.md.
  • Samples: 412 Alder Lane is 38 days on market with a $709,000 → $689,000 cut 17 days ago. The condo was listed 75 days ago, cut once, and sold for $752,000 12 days ago, which reads 63 days. The house is 21 days on market with no change. This is set once, last, so samples already in a database get it too.
  • README: the "For the agent" section says where to see both.
  • Tests: src/market.test.ts covers the day count across Coming soon, Back on market and Sold with fixed dates, and the history after two price changes. It also checks that all four surfaces contain both, and that the samples' numbers are believable.

Test I changed: src/comingsoon.test.ts compared whole listing rows before and after the migrations. The new migration adds two columns, so I extended its expected rows with the backfilled dates. Nothing else about the test changed.

Not done

  • The public property page is unchanged; the issue lists the agent's listing page, report and update only.
  • The sample's price cut is not wired to was_price, so Alder Lane's generated Price improvement assets are unchanged. Setting was_price would have rewritten its assets and approvals.
  • Existing listings' days on market are approximate, because the migration can only read the creation and last-touched dates.
  • #81's showings edits to the home list and listing page may conflict; I did not see them on this base.

To try it: boot the app and open / for the day pills. Then open 412 Alder Lane for the "38 days on market" line and the table, and /listings/<id>/report for the report. Change a price on Edit facts to add a history row.

Changes requested — before the latest push

Two things to fix before this lands.

  1. (First) The terminal door lacks the feature. The listing view in src/tty.ts (~line 206, the head with address/price/tone) shows neither the days on market nor the price history, and the home list in the terminal has no day count. Only the seller report (R) carries it. The list says what a person can do on the page they can do in tty too. Add the day line and the history lines (daysLine and historyLines from src/market.ts are ready) to the tty listing view and the day count to the tty list, and add a test in the tty tests that fails without them. Mention the tty in the README section.
  1. Cleanliness. (a) The doc comment '/** Green when nothing is flagged; amber with how many otherwise. */' in src/pages/home.ts now sits above daysPill instead of status; move it back. (b) src/pages/market.ts exports daysOnMarket, which shadows the numeric daysOnMarket in src/market.ts; rename it (e.g. daysLineHtml). (c) report.ts uses marketLines(...).slice(1) followed by a manual '' to undo the leading blank line; make marketLines not lead with a blank line and let each caller place its own spacing. (d) Stray double blank line in src/market.ts; README item is numbered '0.' - renumber or fold into the list properly. (e) the README says 'N days' is shown; the home pill does so by string replace on the line, build it from the number instead.

Also state in the pull that tsc was not run (no tsconfig) and fine otherwise: contract cells untouched, outputs escaped, migration and tests look sound.

commented

Days on market and price history now show on the listing page, the home list, the seller report, the weekly seller update and the terminal. bun test passes (353 tests) and the design lint is clean. I did not run bun x tsc --noEmit, because the repository has no tsconfig. Contract cells are untouched.

What changed

  • Days on market: counted from the day the listing first went active. Coming soon does not count, and the count stops at Under contract, Sold, Withdrawn or Expired. Back on market resumes it from the original list date.
  • Price history: the list price, each price change and the sold price are recorded with their dates, in a new price_history table. The listing page, report and update show each entry's change from the one before.
  • Samples: 412 Alder Lane opens at 38 days with one price cut, from $709,000 to $689,000.
  • Migration: existing listings are backfilled from their creation and last-updated dates. Their day counts are therefore approximate.
  • Tests: src/market.test.ts covers the count across status changes, the history after two price changes and the samples. I also changed src/comingsoon.test.ts, which compares whole listing rows across migrations; its expected rows now include the two backfilled date columns.

Review feedback

  • Terminal: the terminal listing list shows "· N days" on active listings. An opened listing shows the day line and the price-history lines under its head. A new test in src/tty.test.ts fails without them.
  • Naming and comments: I moved the doc comment back onto status in src/pages/home.ts. I renamed the page helper to daysLineHtml, so it no longer shadows daysOnMarket in src/market.ts.
  • marketLines: it no longer leads with a blank line. The report and the update each add their own spacing, and the .slice(1) hack is gone.
  • Home pill: it is built from the day count through a shared dayCount, not by editing a string.
  • Housekeeping: I removed the stray blank line in src/market.ts. The README entry is now item 6 of the "For the agent" list and mentions the terminal.

Left out:

  • The public property page is unchanged; the issue only names the agent's listing page, the report and the update.
  • The sample's price cut is not tied to was_price, so Alder Lane's generated Price improvement assets are unchanged.

To try it: run bun run src/tty.ts and open Alder Lane for the day line and history. Or open / and /listings/<id>/report on the page.

🤖 Generated with Claude Code

Approved

Earlier asks are met: the terminal now shows the day count in the list and the day line and price history on an opened listing, with a test in src/tty.test.ts. The naming and marketLines cleanups and the README item are done. The preview home list shows the 21 days and 38 days pills. Contract cells are untouched and no dependency was added. I could not diff against 0e1472eac63e because the clone lacks that commit, so I read the whole change.

Non-blocking: the migration backfill is approximate for existing listings, and the pull says so.

Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs