feat: MPS-24 Phase 2.5 — product page polish (description wrap + price-history toggle)

Two product-page issues surfaced while shopping printableprompts on
mobile. Both fixed in one commit since they're tightly scoped to the
product page experience.

Description text clipping the right edge on mobile:

- .content-card uses CSS Grid but its grid items had default
  min-width: auto, so they expanded to their content's intrinsic
  width — long unbreakable tokens (URLs, etc.) pushed the card
  wider than the viewport. Then .content's overflow-x: clip
  silently hid the right side instead of wrapping the text.
- Add min-width: 0 + overflow-wrap: break-word to .content-card,
  .content-card-header, .content-card-body. Add word-break:
  break-word to inner <a> / <p> so URLs hyphenate at any character.

Price history shown by default:

- The price history table (commit 1e5fe27, 2026-02-11) was always
  visible to anyone who could edit the shop. Operator feedback:
  "wait for a sale" psychology hurts conversions; shoppers
  shouldn't see a timeline of past prices.
- New Shop.show_price_history Boolean (default False, server-default
  "0") with idempotent Alembic migration c792642911e2.
- Toggle lives in the existing ribbon-settings form section.
- views/product.py (public view) + views/watch.py JSON gate the
  price_history list on the toggle. Template product.j2 also gates
  rendering as belt-and-suspenders.
- Edit page (also views/product.py:product_edit) intentionally
  remains always-on — the operator needs price audit access from
  their own admin surface regardless of the shopper-facing toggle.
- New shop matrix entry in docs/architecture.md.
- 2 new functional tests (default-off + toggle round-trip).

1090 tests passing.
This commit is contained in:
russell@unturf.com 2026-05-15 13:54:24 -04:00
parent 7fe6b56cdb
commit dc79d13358
No known key found for this signature in database
12 changed files with 192 additions and 14 deletions

View file

@ -192,6 +192,7 @@ mps_page_session (raw rows)
|---------|-------------|--------------|---------|
| Watch mode | `shop.watch_mode_enabled` | `ribbon-settings` | Off |
| Sandbox mode | `shop.sandbox_mode` | `ribbon-settings` | Off |
| Show price history (MPS-24 Phase 2.5) | `shop.show_price_history` | `ribbon-settings` | Off |
| Show dates | `shop.show_dates` | `ribbon-settings` | On |
| Grid lanes | `shop.grid_lanes_enabled` | `ribbon-settings` | Off |
| Color filter | `shop.color_filter` | `ribbon-settings` | 0 (none) |

View file

@ -319,6 +319,30 @@ picker is Phase 2).
| `tests/test_models.py` | `TestTagSuggestPureFunctions` — 11 unit tests over tokenize / stem / cluster |
| `tests/test_functional.py` | `test_suggest_clusters_renders_candidates`, `test_apply_suggestion_creates_tag_and_attaches_products`, `test_dismiss_suggestion_adds_to_stopwords`, `test_apply_suggestion_rejects_empty_input` |
### Phase 2.5 — product page polish: description wrap + price-history toggle (shipped 2026-05-15)
Two product-page bugs surfaced while shopping printableprompts:
- **Description text clipping right edge on mobile.** `.content-card`
uses CSS Grid but its grid items had default `min-width: auto`
they expanded to their content's intrinsic width, pushing the card
past the viewport. `.content`'s `overflow-x: clip` then silently
hid the right side of the text instead of wrapping. Fix: `min-width:
0` + `overflow-wrap: break-word` on `.content-card`, `.content-card-
header`, `.content-card-body`, plus `word-break: break-word` on the
inner `<a>`/`<p>` elements so long URLs hyphenate at any character.
- **Price history shown by default.** The price history table
(commit `1e5fe27`, 2026-02-11) was always visible to anyone who
could edit the shop. Operator feedback: "wait for a sale" psychology
hurts conversions; shoppers shouldn't see a timeline of past prices.
Added `Shop.show_price_history` Boolean (default `False`, server-
default `"0"`) with idempotent Alembic migration `c792642911e2`.
Toggle lives in `ribbon-settings` form. View + watch JSON now gate
the `price_history` list on the toggle; template gates rendering
separately as belt-and-suspenders. When off (default), nobody sees
the table — including the operator on their own product page.
Operator can still review history in shop analytics.
### Phase 2.4 — SPA bulk tagger + Netflix-style lanes (shipped 2026-05-15)
Two improvements that compound for the operator workflow: