Site copy: overview paragraph, nonclinical notice, real legal text, contact route, plan and settings wording - #209
Merged
Conversation
…itle the tab A first-time visitor had no sentence explaining what the site does. Add a short paragraph under the hero subtitle (browse, upload for segmentation, annotate) followed by the site-wide nonclinical sentence, and move the canonical strings into src/helpers/copy.ts so every surface uses the same wording. Browser-tab / og / twitter title becomes "BodyMaps: CT Library, Segmentation, and Annotation" and the descriptions follow; the on-page subtitle and stats row are unchanged. copy.test.ts guards the index.html strings and landing.test.tsx checks the paragraph renders directly under the subtitle.
…s, Inc. contact form Keep the tagline, stack the site-wide nonclinical sentence under it, and replace the generic "For commercial use" pointer with an inquiry line that names BodyMaps, Inc. as the contact route and links straight to the form. Strings come from helpers/copy.ts; siteFooter.test.tsx covers the link attributes and copy.test.ts now sweeps src/ for retired phrases.
…TACT entry The fine print was sign-up only and read as if the Privacy Policy were a contract. Show it on both sign-in and sign-up (not on password reset) as "By continuing, you agree to the Terms of Service and acknowledge the Privacy Policy." The header gains a CONTACT pill (desktop and mobile drawer) that opens the BodyMaps, Inc. contact form in a new tab, so bug reports and collaboration inquiries have a visible route. accounts.test.tsx now expects the line on sign-in; header.test.tsx covers the external link attributes.
…al real text
The two pages were section scaffolds behind a "Draft placeholder — not yet
in force" banner. Replace them with plain-English text that describes what
the service does today: nonclinical use (commercial or noncommercial),
18+ accounts, no PHI and no BAA, the scan-contribution license on
de-identified uploads, users' full rights (including commercial) in the
masks they create, honest retention and deletion wording, and the analytics
non-identification guarantee with the account/browser linkability
disclosure. The two sentences that were untrue in production ("deleted
automatically", "never used to identify you personally") are gone. A quiet
"Provisional … under review" status line replaces the orange banner; the
closing line routes questions to the BodyMaps, Inc. contact form.
legalPage.test.tsx checks headings, status line, retired phrases and the
contact link; copy.test.ts adds the retired phrases to its sweep.
Member cards were plain text. Add an optional links field and render a small LinkedIn link under the role for the two profiles that have been verified (Zongwei Zhou, Wenxuan Li); the other four cards stay unlinked until their URLs are confirmed. Title, roster, order and photos are unchanged. teamPage.test.tsx pins exactly two links with accessible "<name> on LinkedIn" labels.
… cards
Pro and Team showed invented donation prices ($1.99 / $4.99) and the cards
promised things the code does not do (BAA/DPA, PACS integration, priority
queue, pooled usage) with clinical framing ("clinical and research work",
"practice", "hospital"). Future tiers now read "Coming soon" with general
wording; Free says "always free"; Enterprise lists private deployment and
alternate data terms; report-oriented strings say research summaries and
the upgrade dialog no longer speaks of donations. Behaviour (limits,
admin-only tier switching) is unchanged.
Tests updated for the new strings; copy.test.ts retires the old ones.
…t you can see The two confirmation texts promised more than the service does: "Delete scan history" claimed to permanently delete every scan, and account deletion implied a clean 30-day purge. Reword both to what happens: history clearing removes the visible jobs and the working files and masks we can associate with them, a separated de-identified contribution may remain, and account removal is scheduled after the 30-day grace period rather than guaranteed on a day. GET /api/me/export used to return the whole account row (internal id included) plus job rows carrying server paths. It now returns only the fields a user can already see in Settings — email, name, role, plan, created date — and the control is relabelled "Export account details". The Privacy Notice's rights section mentions the download. Functional test pins the exact payload shape (no id, no jobs, no hash); the settings tests that used Export as a notification fixture now use clear-history instead.
… under the stats The overview paragraph sat between the subtitle and the stats row and broke the hero's rhythm. Move it under the stats. The subtitle changes from "The open library of labeled body CT scans" to "The intelligence layer for medical imaging AI", and the same line replaces it in the og/twitter image alt text and in the link-preview artwork (svg source edited, png re-rendered at 1200x630). landing.test.tsx pins the new order; routes smoke test and the copy guard follow the subtitle change.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
TLDR
Wordsmithing pass across the public surfaces so a first-time visitor knows what the site is, every page carries the same nonclinical sentence, the legal pages are real text instead of a "Draft placeholder" scaffold, and the Settings/plan copy says only what the service actually does. Seven commits, 27 files, no behaviour change except one endpoint returning less (the account export drops internal ids and server paths).
Major decisions
src/helpers/copy.ts, guarded bycopy.test.ts(canonical strings present, retired phrases swept fromsrc/)What changed
LandingPage/index.tsx,.module.css,index.htmlSiteFooter/*AuthModal.tsx,Header/index.tsxCONTACTentry (desktop + mobile) opening the contact form in a new tabLegalPage.tsx,.cssTeamPage/*linkson members; LinkedIn for Zongwei Zhou and Wenxuan Li with " on LinkedIn" labelsaccountProfile.ts,UpgradeDialog.tsxPrivacySettings.tsx,auth_blueprint.pyGET /api/me/exportreturns onlyemail, name, account_type, plan, created_athelpers/copy.ts(new)Testing
Local gates identical to
ci.yml, on the final tree:npm run typecheck— 0 errorsnpm run lint— 0 errors (49 pre-existing warnings, unchanged frommain)npm test— 46 files, 307 tests passed (6 new files: landing, siteFooter, header, legalPage, teamPage, copy guard)npm run build— OK;/,/team,/terms,/privacy,/uploadscreenshotted fromvite previewat 1440 pxpython -m compileall -q .OK; path_safety, user_dataset, chunk_store, job_store, auth_store + auth endpoints, oauth, plan_store, live_room_store, live_quiz, quiz_platform (-k) — all passing. The export test pins the payload shape.Edge cases covered: sign-in vs sign-up vs reset views (fine print only on the first two); export mocked as a 503 in the notice tests; plan picker shows one group at a time;
$0is a legitimate price while$x.xxis asserted absent; LinkedIn link count pinned to exactly two.Verified correct, no change needed: landing subtitle and stats row; on-page
<h1>; favicon/og-image set;brand.csstokens; plan limits and admin-only tier switching inplan_store.py//me/plan; account-type values (Patient/Clinician/Researcher/Student) — labels only, left as is.Lower-severity, deferred (with reason): mobile overflow at ≤390 px on the landing page — pre-existing on
main(open PR #43 covers it);AuthModaluseEffectdependency warning — pre-existing;copy.test.tssweepssrc/only, notflask-serverPDF header strings.Conflict proof: branch is
upstream/main(7893a9f) + 7 commits;git merge-treeclean; no open PR and no upstream branch pushed since 2026-08-22 touches any of the 27 files.Out of scope (deliberately)
api_blueprint.py; text is ready, implementation is a separate PR.Reviewer checklist
/reads: subtitle → overview paragraph → stats; tab title changed, subtitle not/,/dashboard,/upload,/teamCONTACTin the header opens thebodymaps.com/contact in a new tab (desktop and drawer)/termsand/privacyrender every section; no "placeholder"/"not in force" text remains