# Release Notes
## 2026-10-10
### Features
- App 1.3: after a few returned items, the iPhone and Android apps may ask once for an App Store / Play rating (at most every 90 days, never in the first session; the system decides whether the dialog shows) (LEN-475)
- Website: a new Group resources page (`/guides/group-resources`) collects the free lending log and return-message templates for clubs, camps and neighborhood newsletters. The About page now opens with "LendLoop: track what you lend and borrow"
### Improvements
- Sign-in with email: new accounts that sign in from the emailed link are asked what friends should call them too, and the name field starts empty with a hint instead of the start of your email address (LEN-564)
- Home, Items, Friends and Profile now show both directions: the Home summary counts what you borrowed as well as what you lent and leads with the most urgent thing (late, then due soon, then what you're holding); "Coming up" includes borrowed items and loans with no date; Home adds "Ready to lend" picks that open the lend sheet and "Recently returned"; Items shows every ready item in a grid with full names; borrowed rows show "No date" when nothing is set; the Friends card tells you what you're holding; Profile counts lent and borrowed; the borrowed item screen no longer cuts off "Mark returned" (LEN-566)
- Home, Items, Friends and the item screen now agree on "due soon": anything due within 3 days. Items due the same day list what you borrowed first, a lent item due today says "today" in the Home summary, an account with no loans sees one "Nothing out" card with a single Lend action, and the Friends card counts only friends holding your items and says how many of theirs you have (LEN-566)
## 2026-10-06
### Features
- iPhone app 1.2 (TestFlight): the new look and feel (redesigned screens), sign in with email, and version-safe updates. Testers: please try lending, borrowing and sharing, and tell us what feels off
- App versions: the iOS and Android apps can now keep the version of LendLoop they were released with while the website moves on, and an app that is too old shows an "Update LendLoop" screen with a link to the store. App 1.2 tells LendLoop its version so each release gets the right one (docs/ops/versions.md)
## 2026-10-04
### Features
- Redesign (DSv2): a new Home that shows the one thing that needs you (a late item, several, or all on track), thank-yous from friends, offers to accept and what is coming up; Items with Lent/Borrowed/Ready counts and swipe actions (remind, mark returned, extend); a Friends tab with who has your things and on-time records; a new item screen with the loan timeline and history; lending from the Lend button in sheets that remember how long you lent the item last time and can remind your friend for you; Profile with your lending stats; dark mode and large text throughout (LEN-565, PR #704)
- Sign-in: "Continue with email" under the Apple and Google buttons: we email a 6-digit code (or a link), no password; new accounts pick the name friends see. Shown only where email sign-in is switched on (LEN-564)
- Sign-in: a short note under the Apple and Google buttons says they only confirm it's you and that signing in shares none of your items, loans or activity with them
### Chore
- Design: the DSv2 design study (benchmark captures of ten apps, every design iteration, the owner review decisions) is in the repo as the spec for the redesign (PR #702)
### Improvements
- Redesign: cards no longer show a square corner on iPhone; the first-run steps read as a progress line instead of buttons; "Popular to lend" suggests categories (Tools, Books, Games, Tech) and opens Add item with that category chosen (LEN-565, PR #706)
- Redesign polish: item photos and friend faces sit correctly in lists, the tab bar and header buttons look like frosted glass, sheets dim the whole screen, and the reminder switch, loan progress and Profile badges match the new design (LEN-565, PR #705)
## 2026-10-02
### Fixes
- Sign-in: the Apple and Google buttons now use Apple's and Google's official logo artwork and button styles (white Apple button in dark mode), and the sign-in consent line is the standard one; the arbitration notice moved to the top of the Terms (LEN-559)
- Email: the daily delivery summary no longer lists bounces and delays for QA test accounts (they have no mailbox); Resend events for them are dropped
## 2026-09-30
### Chore
- Staging: the sign-in screen offers one-tap sign-in as a QA test account, so LendStaging testing skips Google and Apple (staging only)
### Features
- Borrowing: a borrower sees the item as "Borrowed" with "Lent to you" in its history, and a loan with a custom due date shows the date instead of "duration.labels.custom" (LEN-556)
- Borrowing: after you accept a lend offer, the item page says "You have it" with the return date, who lent it, the ask-for-more-time options and Mark Returned, instead of "Check back later"; your profile's item count is now labelled "Shared items" (LEN-553)
### Fixes
- Email: the lending receipt (and 10 other emails: invites, reminders, return and deletion notices) showed raw keys like `email.lendingReceipt.headingHtml`, the receipt subject showed `\u201c` instead of quotes, and the duration showed `2-weeks`; all now read normally in English and Spanish (LEN-558)
- Loans: the "Would you have paid?" question now appears as a centered pop-up after a few quiet seconds, only for a return from the last 2 days, once per visit and not again for 14 days after an answer or Skip; it no longer repeats for every old return or stacks "Thanks" messages (LEN-555)
- Loans: the "Need more time?" buttons show their text, apostrophes no longer appear as `'`, a loan with a due date no longer shows an empty "Duration:", and Loan Details and the Set Due Date sheet no longer scroll sideways at phone width; `npm run test:overflow` audits every screen for it (LEN-551, LEN-552)
- Items: each tab lists only its own items (the Borrowed tab no longer shows your lent-out items under "On loan"); the section, tab and badges all say "Lent out" (LEN-554)
- Email: no more mail to the QA test accounts (their domain has no mailbox), which were bouncing and hurting delivery for everyone
- Onboarding and Activity: the compact "Getting started" card on Loans is evenly padded, and the Activity invite prompt wraps instead of cutting its text off (LEN-557)
## 2026-09-29
### Features
- Activity feed: older activity loads by itself as you scroll, and the feed ends with a little chick and "You're all caught up" (LEN-549)
- Analytics: the app now also reports the phone model, OS version and the vendor id, so app players can be told apart and recognised across installs; needs the new TestFlight build (LEN-550)
- Analytics: app users are now marked as iOS app, Android app or web in PostHog's people list too (platform and app build), not only on events (PR #665)
- Website: the Sustainability page opens with "Make more use of what you already own" and a "Before you buy, ask" checklist; the power-tools page and the gear-library guide now show how to track lent tools and gear, with a worked tent example (LEN-544, PR #657)
- Crews: deleting a crew updates the app at once and leaves the screen; a crew that is already gone says "This crew was deleted."; removing an item from a crew is instant and rolls back on failure (LEN-520)
- Loans and items: returns, lending and offers update the screen at once, roll back if the server refuses, and refresh themselves afterwards (LEN-518, LEN-530, PR #590)
- iOS: forms no longer shift the page when the keyboard opens; needs the new TestFlight build (LEN-537, PR #658)
- Spanish: every app screen, crew invites, share and referral links, link previews and the website are now in Spanish, reviewed for natural Latin-American wording (LEN-545, PR #652)
## 2026-09-27
### Features
- Sharing: link previews now show an illustrated LendLoop card (LEN-547)
- Activity: cards say who lent what to whom, with no View button or zero counts; recent dates are relative and older ones short (“Mar 16”); several loans in a row by the same friend fold into one card; the invite card is one small row below the first cards (PR #648)
- Activity: shows only your friends’ lending, with no filter bar on top; an empty feed asks you to track your first item, or to build your library if you already have items (PR #643)
- Spanish: the app follows your device language, with a Language setting in Profile (LEN-545, PR #637)
- Spanish: items, loans, sharing, activity, crews, profile, onboarding, sign-in, the home page, and loan emails and push reminders are now in Spanish for Spanish-language devices; a few screens follow (LEN-545, PR #644)
- iPhone and Android apps (next build): camera and photo permission prompts and the offline screen in Spanish (LEN-545)
- Sharing: link previews in Messages and other apps now say what the link is: “Cordless drill: a loan from Alex” for a loan, “Join Maple St. Housemates on LendLoop” for a crew invite, and “Alex invited you to LendLoop” with a new image for referrals. The loan preview image shows the item instead of “Borrow on LendLoop” (LEN-536, PR #633)
- Website: three new guides: how to keep track of things you lend, a free borrowed-items tracker template (spreadsheet download and printable log), and friendly messages for asking for your stuff back; the footer links to all guides (LEN-536, PR #632)
- Website: the home page now leads with “Know who has your stuff.” and a clearer title and description for search; personal pages (loans, share and invite links, app tabs) and the staging site are kept out of search results, and the sitemap lists only public pages (LEN-536, PR #631)
- Email: invitations (referral, crew and share-link emails) have an unsubscribe link and our postal address; addresses that bounce, complain or unsubscribe stop getting them, and delivery problems are summarized daily to the team once the Resend webhook is set up (LEN-477, PR #624)
- Loans: while a share link waits to be accepted, note who has the item (pick a friend or type a name). Only you see this note; it doesn't change who can accept, and the real borrower's name shows once they accept (LEN-521, PR #625)
### Fixes
- Loans: a loan's page shows the item's emoji instead of a generic box when it has no photo (LEN-546, PR #647)
- Website: the footer no longer squeezes into a narrow column on desktop home; it picks its layout from the space it has, and the stray “©” heading is gone (PR #635)
- Items: saving an edit shows one "Item updated!" message instead of two, and a failed notification-settings save shows one error (LEN-541, PR #630)
- Loans: a link nobody has accepted yet no longer offers "Confirm Return Received" or says "from Unknown"; the invite line uses your private note or neutral wording (LEN-539, PR #626)
- Web sign-in: signing in with a Google or Apple account whose email already has a LendLoop account now says so ("Sign in the way you did before") instead of "Couldn't sign you in" (LEN-515, PR #622)
- Items: no "Track your first item" when everything you own is lent out (LEN-524, PR #603)
- Returns and confirmed returns refresh the Items tab, item and loan pages by themselves (no pull-to-refresh); deleting an item lands on My Items with it already gone, and puts it back with an error if the delete fails (LEN-518, LEN-530) (PR #615)
### Fixes
- Shared reminder links work again: they pointed at lendloop.co, which only forwards its home page, so every reminder link opened a “not found” page. Reminder, share, crew, referral and email links now all use www.lendloop.co (PR #587)
### Improvements
- Store listings: the next App Store version's subtitle, keywords and promotional text, and the Google Play draft, now lead with “Know who has your stuff.” (drafts only; they ship with the next app version) (LEN-536, PR #634)
- Android app (in progress): push notifications only after you turn them on for your account on that phone; switching accounts on a shared phone stops the previous account's notifications (LEN-513, PR #598)
- iOS and Android apps (next builds): the app starts on lendloop.co directly, skipping a redirect; old www links still open the app (PR #629)
- Android app (in progress): the iOS and Android apps now build from one app shell (packages/app-shell). No change to the iOS app (LEN-513, PR #567)
- Android app (in progress): push notifications (only after you turn them on), Google sign-in with Android's account sheet, app links that open the app, and help/privacy links in a browser tab. Not released yet (LEN-513, PR #594)
- Android app (in progress): release signing, Google Play upload and release tags, the Play Data safety draft and listing (LEN-513, PR #595)
- Privacy: server error reports sent to PostHog keep only known-safe words from error messages (names, emails, phone numbers, titles and secrets are dropped), on top of the previous scrubbing (LEN-528, PR #616)
- Lending: an offer to a named person expires after 7 days like a share link; direct lending to a crewmate can't go to yourself or someone who blocked you, and two lends of the same item at once can't both win; re-creating a share link emails the borrower at most 20 times an hour; loan notifications read only the fields they need (LEN-515, PR #618)
- Account deletion: when a deleted account is finally purged (30 days after the request), its analytics profile and events in PostHog are erased too, as the privacy policy says (LEN-502, PR #611)
- iOS app polish from TestFlight: toasts sit below the status bar, one pull-to-refresh on every tab and detail screen (off offline), Activity shows only the Friends toggle, item detail shows the category on the photo and keeps Edit in the … menu, and short screens no longer scroll into empty space (LEN-531–535) (PR #609)
- iOS app: items you add with no connection can get a photo: tap the item's tile, take or choose a photo, and it uploads with the item once you're back online (next iOS build for the offline screen; PR #612)
- Crews: any member can leave a crew from its Members tab; when you leave your last crew, the Crews tab goes away. The only member of a crew is offered Delete instead (LEN-520, PR #606)
- App Store: 1.1 listing drafted with one-to-one lending first and crews as a one-line mention (docs, PR #604)
- Privacy policy: covers the upcoming Android app, and says that its notifications go through Google (Firebase Cloud Messaging), which then receives the device token, a Firebase installation ID, device and app details and the notification contents, only once you turn notifications on (LEN-513, PR #589)
- Upcoming Android app: native Google sign-in (Android's account sheet), with a closed sheet treated as a cancel. No change on the web or in the iOS app (LEN-513, PR #588)
- iOS app: an app, not a website. Every screen has a Back that never scrolls away (item detail keeps its buttons over the photo, then a glass bar); links from a notification or Messages come back to the right tab; no website footer or landing page (signed-out users see an app welcome); help, contact, privacy, terms and marketing open in Safari; glass bars run under the status bar and its text follows Light/Dark (LEN-516, LEN-519, LEN-522) (PR #591)
- Website: a guide to starting a gear library for your club or camp, linked from the footer (web only) (PR #582)
- Push notifications for the upcoming Android app: the server can deliver reminders and loan updates to Android phones through Firebase Cloud Messaging, next to iOS and web push. Stays off until the Firebase key is configured; no change on the web or in the iOS app (LEN-513, PR #584)
- Web app ready for the upcoming Android app: it recognises the Android shell (back button closes sheets, then goes back, then leaves the app; status bar icons follow the theme; no Apple sign-in or web push inside it). No change on the web or in the iOS app (LEN-513, PR #581)
- Photos: item and profile photos are now stored in private cloud storage instead of the database, and share previews use the full-size photo. Photos added before this change don't carry over; add them again (LEN-504, PR #574)
- Crews are now optional: the Crews tab appears only once you create or join a crew (or while you're on Crews). Start one from Profile → Crews; invite links still work. No more crew prompts on the Items tab (PR #571)
- iOS app (next build): scrolling feels native again: the rubber-band bounce and momentum are back (short pages too), the space the bounce opens shows the app's background in light and dark, Items' pull-to-refresh follows the real pull (arrow, light tap, refresh on release), and dragging a sheet never moves the page behind it (LEN-517) (PR #575)
- iOS app (next build): Google sign-in's system prompt now asks on behalf of "LendLoop" instead of "App" (PR #576)
- iOS app (next 1.1 build): the offline screen can add items too, even when the app starts with no connection. Type one per line; they're listed as "Pending" and added to your library once you're back online. Coming back online while you type never loses what you typed (PR #565)
- iOS app: add items with no connection (one per line). They wait on your phone as "Waiting to sync" and are added to your library when you're back online, never twice (PR #555)
- Sign-in: plain-language errors and honest value props on the landing page; calmer toasts (no bounce, 3s, polite screen-reader announcements); item toasts that never showed now do, once (LEN-494, PR #551)
- iOS app: if a page can't load because there's no connection (or iOS reloads the app while offline), you now see your offline items and loans instead of a blank screen, and the app returns by itself when you're back online (PR #549)
- Items: Edit Item has the same category picker as Add Item, so a wrong emoji can be fixed; crew lists and story cards show the chosen emoji (LEN-464, PR #547)
- Loans: Confirm Return waits for the save and shows errors in the sheet; "Remind" label; "Lend again" after a return; no automatic share sheet for borrowers; crew item count refreshes (LEN-495, PR #546)
- Ops: the Railway config file now includes the photo storage bucket, so a config apply can't remove it (LEN-504, LEN-508, PR #554)
- Ops: the hourly jobs and the nightly backup now run the scripts in the repo (small Docker images, rebuilt only when their script changes); database migrations run as a pre-deploy step that stops a bad deploy (LEN-508, PR #559)
- Tests: two timing-sensitive tests no longer fail on a busy machine (LEN-508, PR #560)
- Staging environment at lendloop-staging.up.railway.app: its own database, photo bucket and jobs, QA users reset on every deploy, no emails, push or analytics (LEN-474, LEN-508, PR #562)
- Ops: migrations run once per deploy, in the pre-deploy step only (LEN-508, PR #563)
- Tests: Testing Library waits up to 5 s for async UI, so full runs stay green on a busy machine (LEN-508, PR #572)
- Crews: deleting a crew no longer shows an error when it worked (the app goes to Crews); crew screens show one error per failure, with the server's reason (LEN-520) (PR #566)
- iOS offline view shows your item photos and the other person's profile photo (saved on the device), with emoji and initials when a photo isn't saved (PR #542)
- Onboarding: clearer first-run copy, honest "Link shared / copied / ready" after sharing, one "add an item" prompt at a time, and automatic sheets that never pop over other screens (LEN-478, PR #525)
### Chore
- Ops: photos are backed up nightly with the database, and an hourly job removes photo files nothing uses any more (LEN-504, PR #596)
- Tests: full test runs finish again (about 80 s) instead of hanging on the items tests: a photo race test no longer depends on timing, and photo byte checks fail fast (PR #600)
- Tests: end-to-end flows sign in through test sessions, warm up their local server, and follow the current lending and crew screens (LEN-527).
- Ops: the old photo columns and the Railway photo volume are gone; photos live only in the private media bucket (archived first) (LEN-504, PR #583)
- Photos: storage driver for the private media bucket (S3 in production, local files in dev), not used by the app yet (LEN-504, PR #558)
- iOS uploads tag themselves again (`ios/v<version>-<build>`); the 1.1 build 1083 was tagged by hand (PR #557)
- Error tracking: uncaught errors from every server page and API route now reach error monitoring, grouped by route with ids and personal data scrubbed (LEN-506, PR #544)
- UX research sessions (ux-session skill) start their own dev server on a free port and stop only that server; they no longer kill whatever runs on port 3000 (PR #556)
- Codebase cleanup: shared package folded into the app, about 30 unused files and 8 unused packages removed, unused-code check (knip) in CI (LEN-507, PR #564)
- Docs: CLAUDE.md is a short map that a test checks against the code; runbooks in docs/ops, old docs in docs/archive; PR screenshots published outside the repo (about 98 MB of images removed from the tree) (LEN-505) (PR #569)
- UX research sessions (ux-session skill) run on a throwaway local database with their own dependencies, never copy the production .env, and their dev server refuses a non-local database (PR #579)
- API: one wrapper for API routes (auth, validation, error bodies kept exactly as they are), one structured server logger with request ids, and no personal data in server logs; nothing changes for users yet (LEN-506) (PR #578)
- Docs: the agent guide states the app's screen rule (a tab or a screen with a Back bar, never website chrome) (LEN-516) (PR #607)
- Ops: every environment variable is listed and checked at startup; problems show up in the logs by name, never by value, and nothing is enforced yet (LEN-506) (PR #608)
- API: the activity feed, friends, your loans and stats, blocked users, profiles, crew members and item searches run on the shared route wrapper; responses are unchanged (LEN-506) (PR #610)
- API: crew screens (list, create, edit, delete, crew items, requests, invite links and emails) run on the shared route wrapper; responses are unchanged (LEN-506) (PR #613)
- API: privacy and notification settings, onboarding and time zone, referrals, the health check and the error-alert webhook run on the shared route wrapper; responses are unchanged (LEN-506) (PR #614)
- API: reporting content, contacting support and blocking people run on the shared route wrapper; responses are unchanged (LEN-506) (PR #617)
- Ops: the hourly reminder job and the media cleanup run on the shared route wrapper with structured logs; results are unchanged (LEN-506) (PR #619)
- API: link-preview images, profile photos and loan story cards run on the shared route wrapper; images and headers are unchanged (LEN-506) (PR #620)
- Ops: the nightly account purge runs on the shared route wrapper with structured logs; what it deletes and reports is unchanged (LEN-506) (PR #621)
- API: item search runs on the shared route wrapper; results and privacy scoping are unchanged (LEN-506) (PR #623)
## 2026-09-26
### Features
- Reminders: sent at 9am in each person's time zone, deep-link to the loan, friendlier copy; secret-gated test login and seeded QA users for testing in production (LEN-470, PR #508)
- Reminders: lender heads-ups when a loan is late, "Remind them", "Ask for more time", weekly follow-ups, daily digest; borrowers stop getting reminders once they mark an item returned (LEN-470, PR #518)
- Share reminder: lenders send a friendly return reminder through the phone's share sheet; reminder race fixes (LEN-470, PR #523)
### Fixes
- Item page no longer crashes after editing an item photo (PR #524)
### Chore
- Shared mock item photos for screenshots/tests; App Store upload script (PR #524)
### Fixes
- Items tab: no blank band above the sticky header on iOS; pull-to-refresh only fires at the top of the list (PR #516)
- Item photos now show everywhere (Loans, feed, crews, share links, lend flow); photo edits replace the shown image (PR #517)
### Chore
- App Store screenshots skill and the persona-ranked, captioned 1.0 screenshot set (PR #515)
### Features
- Visual modernization: semantic design tokens with dark mode (System/Light/Dark in Profile), native-feel shell (safe areas, 44pt targets, glass tab bar, bottom-sheet modals), overdue-first Loans tab, all five tabs always visible, and 29 UX-test fixes including comment/like privacy checks (LEN-452/453/459/460/461/462, PR #495)
### Improvements
- Offline while the app is open: one "You're offline" pill above the tab bar (it no longer covers the page header), and Loans and Items show "loan status as of …" so saved state never passes as current (PR #530)
- iOS app works offline: with no connection it shows your last synced items, loans (due and overdue) and crews, read-only, and reconnects by itself; the Loans tab now refreshes when you return to the app (PR #526)
- Friends are now simply the people you have lent to or borrowed from: the lend-to picker, search and feed share one definition; removed unused friend-invite/contacts code and the Friendship table; phone numbers are no longer collected (LEN-469, PR #507)
- PostHog dashboard for activation, weekly retention by first loan, loan lifecycle timings and iOS app vs web; new server events for sign-up and loan accept/return (LEN-480, PR #511)
- Ops: PostHog error tracking (web, iOS app, server) with email alerts to the team, uptime monitoring, deploy-failure alerts, and nightly database backups with a verified restore (LEN-472, PR #510, PR #519)
- E2E test runs no longer kill other dev servers: they reuse `BASE_URL`, or start their own dev server on a free port and stop only that one (PR #541)
- Account deletion: a failing Sign in with Apple token revocation is now retried for 7 days from the first failure (it was 7 hours) before the account is purged (LEN-508, PR #543)
- Unit tests pass on a clean checkout again: dropped a leftover mock of the removed Mixpanel SDK (LEN-508, PR #548)
- Ops: the Railway setup (database, web, cron, backups, storage) is now code in `.railway/railway.ts`, checked to match production exactly, ahead of Railway retiring its old config files on 2026-12-01 (LEN-508, PR #550)
- Ops: CI now runs every migration on an empty Postgres, fails when the schema and migrations disagree, runs the integration tests, and builds with the production command on Node 24 (LEN-508, PR #552)
- Ops: every test is now type-checked by `npm run check` (193 type errors fixed), without affecting production builds (LEN-508, PR #553)
## 2026-05-19
### Features
- Inline CSS wordmark for Logo — eliminates opaque-square misuse on inline-on-light surfaces; FeedHeader now shows the brand name (PR #466)
- New brand identity: refreshed logo, teal/navy + lime/mint palette, and Fredoka display font across web favicons, app icons, splash, and in-app assets (PR #463)
## 2026-04-20
### Features
- Privacy Policy and Terms of Service pages live at /privacy and /terms (Trip.Fish LLC) — linked from mobile + web login (LEN-431, PR #459)
- Sign in with Apple on web (NextAuth) and mobile (expo-apple-authentication), with strict JWT email-verification to prevent account takeover (LEN-429, PR #460)
- Mobile iOS: declared usesNonExemptEncryption=false to skip App Store export-compliance prompt (PR #460)
- App Store reviewer flow docs (docs/app-store-reviewer.md) (PR #460)
- Universal Links: https://lendloop.co share/crew-join/item/crew URLs open the app directly on iOS (LEN-434, PR #461)
- Self-serve account deletion with 30-day grace period — required by App Store 5.1.1(v); owner data is deleted, other users' items/crews preserved (LEN-450, PR #462)
## 2026-04-19
### Chore
- Sync product-tree docs: add Priority Rules and Bronze/Silver/Gold sections (PR #446)
### Improvements
- Remove redundant "View Details" button on transaction cards (PR #447)
- Trim dead zone above sticky CTA footer on share page (PR #447)
- Collapse duplicate card wrapper on crew join page (PR #447)
- Mobile (iOS): clearer LENT/BORROW pill on loan cards, replace ambiguous arrow badge (PR #448)
- Mobile (iOS): Crews empty state shows reliable people icon and primary "Create a crew" CTA (PR #448)
- Mobile (iOS): tighter Profile spacing, AA-contrast Dev Login link, evenly distributed Feed card actions (PR #448)
- Mobile (iOS): Loans filter tabs hit 44pt touch-target minimum (PR #448)
### Fixes
- Mobile Items tab: bound horizontal filter ScrollView height — eliminates dead zone above item list (LEN-447, PR #449)
- Mobile Loans card: replace "Lent to Unknown" with branched borrower name / "Awaiting claim" state (LEN-446, PR #450)
- Profile stats now reflect active loans, matching the Loans tab; lending-stats response is additive (LEN-445, PR #451)
- Mobile iOS: declare camera and photo library permissions in Info.plist via app.json (LEN-435, PR #454)
- Mobile iOS: fix MinimumOSVersion key via expo-build-properties deploymentTarget 15.1 (LEN-437, PR #454)
- Mobile iOS: 401 session-expiry interceptor signs out, redirects to login, shows "Session expired" alert (LEN-433, PR #453)
- Mobile iOS: audited App Store icon — meets Apple tech requirements, flagged placeholder art for designer follow-up (LEN-436, PR #452)
- Mobile iOS: push notification permission flow (expo-notifications) post-auth, simulator-safe (LEN-438, PR #455)
- Mobile iOS: Sentry crash reporting integrated into app root (LEN-443, PR #455)
- Mobile iOS: jest-expo smoke tests for authStore and api interceptor — 10 tests (LEN-439, PR #457)
- Mobile iOS: belt-and-suspenders guard for Dev Login button (requires both __DEV__ AND non-production env) (LEN-440, PR #456)
- Chore: exclude packages/mobile from root tsc + jest (mobile has its own checks) (PR #458)
## 2026-04-06
### Features
- Item thumbnail images in Items, Loans, and Feed lists — show product photos when available (PR #444)
- Feed web parity: user avatar circles, blue tappable item links, "View" button (PR #445)
- Onboarding welcome card for first-time users with 3-step value prop and Add Item CTA (LEN-426, PR #441)
### Fixes
- Item dedup script + prevent duplicate item creation via 409 Conflict (LEN-421, PR #440)
- Unified pending badge: show only Pending or Available, never both stacked (LEN-419, PR #442)
- Items queries staleTime 30s with keepPreviousData to prevent loading flash (LEN-416, PR #442)
- Profile cache scoped by session user ID to prevent stale data on session change (LEN-428, PR #443)
### Chore
- Closed stale issues: LEN-405, LEN-402, LEN-403 (not reproducible in UX sessions)
## 2026-04-05
### Improvements
- Compact activity feed header: merged logo + filter pills into single row, removed community label (LEN-420, PR #434)
- Cancel pending share links directly from item detail page (LEN-418, PR #435)
- Add 4 E2E happy-path tests for top product flows: item+lend, share accept, return confirm, crew join (PR #430)
### Fixes
- Fix Turbopack dynamic route failure: disable Turbopack in dev scripts for Pages Router compat (LEN-423, PR #433)
- Fix activity feed View button navigating to /loans/ 404 — now opens item detail (LEN-400, PR #434)
- Fix non-owner item detail missing image when only thumbnailBlob exists (LEN-422, PR #435)
- Fix duration displaying raw enum on share page e.g. 1_week instead of 1 week (LEN-424, PR #436)
- Fix Add Item modal category persisting between sessions causing wrong emoji (LEN-425, PR #436)
- Fix mirror item duplication: claim flows no longer create duplicate Item rows (PR #428)
- Add integration test infrastructure with Docker Postgres and 18 happy-path tests (PR #428)
- Fix items screen: tapping item cards now navigates to detail, filter counts, status picker (LEN-408, PR #424)
- Item detail: sticky lend CTA, 44px touch targets, added-date, empty history state (LEN-412, PR #423)
- Feed screen: 44px touch targets, bold user names, item title in activity cards (LEN-407, LEN-406, PR #422)
- Loans screen: direction badge size, empty state CTA, bolder stats (LEN-409, PR #426)
- Profile screen: stats fallback, avatar ring border, referral card, menu cleanup (LEN-411, PR #427)
## 2026-04-02
### Features
- UX research session 2026-04-02: 2 issues found (PR #420)
- Redesign add-item modal: search/URL primary affordance (LEN-373, PR #419)
- Fix items filter pills overflow on narrow screens (LEN-404, PR #418)
- Add HOLDING to Edit Item + clarify lend button copy (LEN-401, LEN-371, PR #417)