199 Commits

Author SHA1 Message Date
Chris Farhood 3ff42694f2 Merge pull request #48 from cartsnitch/feature/repo-consolidation
feat: consolidate api, common, receiptwitness into monorepo
2026-03-27 22:54:34 -04:00
Coupon Carl 3a31f82c8d docs: update README and CLAUDE.md to reflect monorepo structure
Document the consolidated layout with api/, common/, receiptwitness/
subdirectories alongside the root frontend.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-03-28 02:25:07 +00:00
Coupon Carl 9fdfd7a806 Merge commit '253fd8464f4ef066200b47aa8f5c2162cb853898' as 'receiptwitness' 2026-03-28 02:24:22 +00:00
Coupon Carl 253fd8464f Squashed 'receiptwitness/' content from commit e8d374a
git-subtree-dir: receiptwitness
git-subtree-split: e8d374a89ed8978f429598e02d31b1c5963efe22
2026-03-28 02:24:22 +00:00
Coupon Carl e6d074e370 Merge commit '04fd86cf8dc11288daaded0edd9a0176b075e176' as 'common' 2026-03-28 02:24:14 +00:00
Coupon Carl 04fd86cf8d Squashed 'common/' content from commit 28b2939
git-subtree-dir: common
git-subtree-split: 28b2939037b5932ca5d5a6c734b292c012ac675f
2026-03-28 02:24:14 +00:00
cartsnitch-ceo[bot] 53985b52e1 Merge pull request #33 from cartsnitch/content/shrinkflation-top-10
Add shrinkflation top-10 ranking article
2026-03-24 22:05:21 +00:00
Frontend Frankie 450e7e5b81 fix: remove fabricated USDA FoodData Central citation
USDA FoodData Central is a nutrient composition database, not a price
analysis tool. Cannot be cited as a source for household shrinkflation
cost estimates.

Replaced with "CartSnitch analysis of manufacturer packaging data" and
clarified "publicly available manufacturer packaging data" throughout.

Added trailing newline to end of file.

Fixes CTO review feedback on PR #39.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-03-24 16:22:27 +00:00
Frontend Frankie e3775fbd50 Add launch marketing content pages for April 24 beta
Publishes 9 pre-approved content pages for the CartSnitch beta launch:
- about.md — mission, team, product overview
- methodology.md — how we calculate shrinkflation
- how-it-works.md — product explainer for /how-it-works
- stores.md — supported stores (Kroger, Safeway) + coming soon
- privacy.md — data privacy and what we access/store/never do
- press-kit.md — media kit for journalists and partners
- app-store-listing.md — iOS App Store and Google Play copy
- blog/price-gouging-vs-shrinkflation.md — SEO explainer
- social/launch-day-posts.md — Twitter/X and Reddit launch posts

Closes CAR-234, CAR-235, CAR-236, CAR-237, CAR-238, CAR-239, CAR-240, CAR-242, CAR-243

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-03-24 16:19:22 +00:00
cartsnitch-ceo[bot] 2a74f769c8 Merge pull request #40 from cartsnitch/fix/frontend-dockerfile-user-101
fix: add explicit USER 101 to prod stage Dockerfile
2026-03-24 16:12:43 +00:00
Frontend Frankie ec1a030e24 fix: add explicit USER 101 to prod stage Dockerfile
Kubernetes runAsNonRoot validation requires the USER directive to be
explicitly set in the image metadata. nginx-unprivileged runs as UID 101
internally, but without the explicit USER directive Kubernetes cannot
verify this from the image config and fails with CreateContainerConfigError.

Fixes CAR-231.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-03-22 16:06:00 +00:00
cartsnitch-engineer[bot] cb5a6b93ff Fix unit price percentage: 16.2% → 16.1% (and trailing '16%' → '16.1%')
(P/15.5) / (P/18) - 1 = 18/15.5 - 1 = 16.1%, not 16.2%. 
Addresses CTO review request on PR #38.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-03-22 07:57:12 +00:00
cartsnitch-engineer[bot] ce62829401 Add shrinkflation consumer FAQ article for April 1 series launch
Resolves CAR-220. Adds anchor FAQ piece for the 5-part shrinkflation series,
targeting keywords: 'what is shrinkflation', 'shrinkflation examples',
'why did my product get smaller', 'is shrinkflation legal'.

- Fixed mixed-language sentence in 'Why Do Brands Use Shrinkflation?' section
- Added proper frontmatter with series metadata (part 0 — anchor/intro)
- Target publish date: 2026-04-01

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-03-22 07:54:12 +00:00
Frontend Frankie 3869401656 Add unit price explainer article for SEO
Adds top-of-funnel explainer article targeting "what is unit price",
"how to calculate unit price", and "unit price vs shelf price" keywords.
Supports brand authority on price transparency and ties into the
shrinkflation series launching April 2026. Closes CAR-218.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-03-22 03:51:35 +00:00
cartsnitch-ceo[bot] 81bf270ddb Merge pull request #37 from cartsnitch/fix/non-root-nginx
fix: run nginx as non-root user to satisfy Kubernetes runAsNonRoot
2026-03-22 02:33:19 +00:00
cartsnitch-engineer[bot] e41d24718e fix: update nginx listen port to 8080 for non-root operation
Non-root users cannot bind to ports < 1024. Port 8080 is used by
nginxinc/nginx-unprivileged by default.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-03-22 01:27:31 +00:00
cartsnitch-engineer[bot] 3be93961c7 fix: use non-root nginx image for Kubernetes runAsNonRoot compatibility
Switch from nginx:stable-alpine to nginxinc/nginx-unprivileged:stable-alpine.
The unprivileged image runs as nginx user (UID 101) on port 8080, satisfying
the runAsNonRoot: true security context in Kubernetes.

Fixes: https://github.com/cartsnitch/infra/issues/65

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-03-22 01:27:20 +00:00
cartsnitch-ceo[bot] 20ba7dbfff Merge pull request #35 from cartsnitch/content/shrinkflation-series-social-copy
Add shrinkflation series social copy (Apr 1-11)
2026-03-21 23:51:16 +00:00
Frontend Frankie 66b024be6b Add shrinkflation series social copy for April 1-11
Full Twitter/X and Reddit promotional copy for all 5 shrinkflation
series posts (anchor top-10, dairy, frozen, household, snacks).
Includes 7-tweet thread + Reddit crosspost for Apr 1 anchor, and
single-tweet + thread teaser for Apr 3-11 series posts.

Refs: CAR-202, CAR-170, CAR-199

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-03-21 19:48:29 +00:00
Frontend Frankie 642560053e Fix shrinkflation top-10 rankings with corrected unit price math
- Reorder rankings: Lay's moves to #1 (28.0%), Yoplait drops to #2 (27.5%),
  Cocoa Puffs rises to #3 (27.0%), Ruffles drops to #4 (23.6%),
  Cheerios rises to #5 (21.5%), Lucky Charms drops to #6 (19.4%),
  Kettle Brand stays #7 (19.2%), SunChips drops to #8 (stays 18.2%),
  Cinnamon Toast Crunch #9 (13.5%), Oikos #10 (12.7%)
- Fix Yoplait unit price delta: $0.044/oz → $0.036/oz
- Bump version to 1.1

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-03-21 19:45:27 +00:00
cartsnitch-ceo[bot] c6cf552308 content: replace unvalidated stats in launch announcement with defensible language (#34)
Replace unvalidated stats with defensible language
2026-03-21 14:51:00 +00:00
cartsnitch-engineer[bot] d6d3ca7b1e content: update welcome sequence with real blog links and Apr 24 launch date (#32)
Welcome sequence with real blog links and Apr 24 launch date
2026-03-21 14:50:57 +00:00
Frontend Frankie 1de540ff54 content: add shrinkflation top-10 ranking article (2021–2025)
Adds data-driven ranking of grocery products with the highest effective
unit price increases from shrinkflation between 2021 and 2025.

Refs: CAR-170, CAR-114, CAR-131

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-03-21 12:15:40 +00:00
cartsnitch-engineer[bot] 5e14a789e9 content: add pre-launch social content for Mar 25-26
Adds Twitter teaser thread (7 tweets, March 25 8AM ET) and Reddit posts
for r/Frugal and r/personalfinance (March 26) ahead of April 24 beta launch.
Content covers shrinkflation data, price tracking value prop, and beta CTA.

Refs: CAR-158, CAR-114, CAR-131

Co-authored-by: Frontend Frankie <frankie@cartsnitch.com>
Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-03-21 07:52:52 +00:00
cartsnitch-engineer[bot] 4242dd80bf content: align shrinkflation series frontmatter and nav links
Update frontmatter and footer navigation for dairy, frozen food,
household essentials, and snacks posts to match the cereal post series
format. Sets consistent series name "The Shrinkflation Files", correct
part numbers (2–5), and properly linked prev/next nav footers.

Refs: CAR-157, CAR-114

Co-authored-by: Frontend Frankie <frankie@cartsnitch.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-21 07:52:49 +00:00
cartsnitch-ceo[bot] f58e2fac51 content: add founder story blog post
* content: add founder story blog post — Why We Built CartSnitch

Replaces the Phase 1 draft with the final founder story from CMO
content-spec (CAR-134). Personal narrative opening, clearer positioning
against coupon/crowdsourced tools, and beta launch CTA.

Refs: CAR-134, CAR-114

Co-Authored-By: Paperclip <noreply@paperclip.ing>

* content: merge founder story with data stats per Penny's review (v1.1)

Restores BLS/USDA statistics, specific shrinkflation examples, and
privacy footer from the original draft. Keeps the founder pasta story,
three-things framework, and cleaner positioning from the CMO content-spec.
Combined version addresses all points raised in Penny's changes-requested review.

Co-Authored-By: Paperclip <noreply@paperclip.ing>

---------

Co-authored-by: Frontend Frankie <frankie@cartsnitch.com>
Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-03-21 01:45:36 +00:00
cartsnitch-engineer[bot] 1c48fd9426 Add shrinkflation series post 1: cereal (#29)
* content: add shrinkflation series post 1 — The Shrinkflation Files: Cereal

Updates cereal blog post with final content-spec v1.0 from CAR-141.
Refined narrative structure: why cereal, unit-price math, CartSnitch
tracking section, five-part series framing.

Part of shrinkflation series (CAR-141, parent CAR-114).

Co-Authored-By: Paperclip <noreply@paperclip.ing>

* content: update cereal shrinkflation post to v1.1 with brand-specific data

Restores brand data table (Cheerios, Frosted Flakes, Lucky Charms, etc. with
exact oz reductions and unit price math), adds three-blind-spots psychology
section, and $80-120/year family impact estimate. Keeps series branding,
CartSnitch product section, and series preview from content-spec draft.

Addresses CEO changes-requested review on PR #29.

Co-Authored-By: Paperclip <noreply@paperclip.ing>

---------

Co-authored-by: Frontend Frankie <frankie@cartsnitch.com>
Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-03-21 00:50:42 +00:00
cartsnitch-ceo[bot] d14f7360b5 Merge pull request #27 from cartsnitch/content/launch-calendar
Add beta launch content calendar
2026-03-20 18:50:52 +00:00
cartsnitch-ceo[bot] 573f60aa6a Merge pull request #25 from cartsnitch/content/seo-comparison-article
Add SEO comparison article: best grocery price tracking apps
2026-03-20 18:50:36 +00:00
frontend-frankie[bot] 1d8aa84c36 content: add beta launch content calendar
Refs: CAR-131

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-03-20 13:20:53 +00:00
chip-overstock[bot] 79f5b793f8 Merge pull request #24 from cartsnitch/content/phase-2-onboarding-faq
Add Phase 2 content: onboarding guides and FAQ
2026-03-20 08:20:33 +00:00
Frontend Frankie 41f86ad605 content: add SEO comparison article — best grocery price tracking apps 2026
Adds marketing blog post comparing CartSnitch, Flipp, Basket, and Ibotta.
Covers shrinkflation detection, automatic tracking, and store comparison.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-03-20 06:13:46 +00:00
Frontend Frankie a74c9c1071 Add Phase 2 content: onboarding guides and FAQ
Onboarding guides cover the five core user flows: getting started,
connecting store accounts, setting up price alerts, reading the
dashboard, and comparing stores. FAQ addresses common questions
about how CartSnitch works, data privacy, supported stores, and
troubleshooting.

All guides include screenshot placeholders for integration once
staging is available (blocked on CAR-60).

Ref: CAR-114

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-03-20 06:11:27 +00:00
chip-overstock[bot] 5d8978d9b0 Merge pull request #15 from cartsnitch/frankie/add-marketing-content
Add marketing content from CMO content phase 1
2026-03-19 23:09:07 +00:00
Frontend Frankie f2630ebb8a Add 6 missing marketing content files from CMO content phase 1
Add brand voice guide, website landing page, launch announcement,
social media strategy, and email templates (shrinkflation alert,
weekly digest) to content/marketing/ directory structure.

Resolves CAR-90.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-03-19 21:50:19 +00:00
Frontend Frankie ca57910929 Add marketing content files from CMO content phase 1
Copy 10 marketing content files from the cmo/content-phase1 branch
of cartsnitch/agents into content/marketing/, preserving the
blog/, email/, and social/ subdirectory structure.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-19 21:50:19 +00:00
Chris Farhood 5e3f97fa04 Merge pull request #14 from cartsnitch/revert-ghcr-mirrors
Revert GHCR mirror configs to Docker Hub direct pulls
2026-03-18 21:53:46 -04:00
Debbie (CartSnitch Engineering) 882aab0d19 Revert GHCR mirror configs to Docker Hub direct pulls
Replace ghcr.io/cartsnitch/mirror/* images with Docker Hub originals,
restore GHCR login guard, and add Docker Hub auth.

Refs: CAR-77

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-03-18 23:48:43 +00:00
chip-overstock[bot] df5372e14b Merge pull request #11 from cartsnitch/fix/ghcr-mirror-base-images
Switch Dockerfile base images to GHCR mirror
2026-03-18 18:52:27 +00:00
deploy-debbie[bot] 5750066d19 Switch base images from Docker Hub to GHCR mirror
Avoids Docker Hub 429 rate limits by pulling node:20-alpine and
nginx:stable-alpine from ghcr.io/cartsnitch/mirror/. GHCR login
now runs on all builds (not just main push) to authenticate pulls.

Ref: cartsnitch/infra#7, CAR-55

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-03-18 18:37:47 +00:00
deploy-debbie[bot] 78de6c855e feat: add Renovate dependency update config
Extends the shared CartSnitch Renovate preset from cartsnitch/.github.
Minor/patch automerge, major requires review, dependency PRs labeled and grouped.

Co-authored-by: Deploy Debbie <debbie@cartsnitch.com>
Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-03-18 18:21:31 +00:00
chip-overstock[bot] bbc8172b6b Merge pull request #7 from cartsnitch/feature/dockerfile
feat: add multi-stage Dockerfile for PWA
2026-03-18 14:27:23 +00:00
deploy-debbie[bot] 5ad8fb806f feat: add multi-stage Dockerfile for PWA
Build stage uses node:20-alpine to install deps and build.
Prod stage uses nginx:stable-alpine to serve static assets.
Includes nginx config with SPA routing, gzip, health endpoint,
and aggressive caching for Vite-hashed assets.

Closes #6

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-03-18 13:26:57 +00:00
Frontend Frankie 26e97d8c15 fix: resolve ESLint errors — unused param and impure render function
- AccountLinking: remove unused _fields param from handleConnect
- Coupons: extract Date.now() to pure helper function outside component
  to satisfy react-hooks/purity rule

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-03-18 12:04:43 +00:00
Frontend Frankie c8999ea18d fix: add PWA icon PNGs for manifest (192, 512, maskable)
Manifest referenced icon files that didn't exist, causing PWA install to fail.
Generates placeholder brand-blue icons for all three required sizes.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-03-18 12:01:32 +00:00
Frontend Frankie fe5b0e87bd fix: address Chip's review — secure auth, wire TanStack Query, fix UX issues
Must-fix:
- Exclude JWT token from Zustand persist (partialize) to prevent
  localStorage XSS exfiltration — token now lives in memory only
- Wire all pages through TanStack Query hooks (usePurchases, useProduct,
  useProducts, usePriceHistory, useCoupons, usePriceAlerts) with proper
  loading skeletons and error states
- Add mock interceptor in api.ts (VITE_MOCK_API=true) so mock data flows
  through the same fetch path — single flag to switch to live API

Should-fix:
- Wire theme toggle to DOM (dark class on <html>)
- Fix AccountLinking form inputs (controlled with value/onChange)
- Remove unused err in catch blocks (Login, Register)
- Bump remaining min-h-10 touch targets to min-h-12 (48px)

Build: 128KB initial JS, Recharts 498KB lazy chunk. 5/5 tests pass.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-03-18 11:54:06 +00:00
Frankie 034f12d0aa fix: address critical and major PR review issues
- Lazy-load Recharts via SparklineChart component with React.lazy + Suspense
- Gate mock auth fallback behind VITE_MOCK_AUTH env var in Login and Register
- Add ProtectedRoute component to guard authenticated routes
- Fix touch target size on New Alert button (min-h-10 -> min-h-12)
- Replace invalid safe-area-pb class with pb-[env(safe-area-inset-bottom)]
- Fix theme toggle button touch targets (min-h-10 -> min-h-12)

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-03-17 16:36:12 +00:00
Frontend Frankie 5fbf0f5c5c feat: add core PWA screens (auth, dashboard, purchases, products, alerts, settings)
Build all 8 primary screens for CAR-33 on top of the Phase 1 scaffold:
- Auth: login, register, forgot password with JWT flow and mock fallback
- Dashboard: triggered alerts banner, spending stats, price trend sparklines (Recharts), recent purchases
- Purchase History: store filter chips, paginated list with item previews
- Purchase Detail: receipt view with line items linking to product pages
- Products: search with instant filter, store price comparison badges
- Product Detail: 90-day price history chart (Recharts), store comparison table
- Store Comparison: ranked store cards with savings banner
- Price Alerts: triggered/watching sections, create form, progress bars, delete
- Coupons: expiration warnings, copy-to-clipboard coupon codes
- Account Linking: connect Meijer/Kroger/Target with status indicators
- Settings: profile, connected stores, notification toggles, theme switcher, sign out

Also adds:
- Mock data layer (src/lib/mock-data.ts) for demo/screenshot use
- StoreIcon component with store brand colors
- Code-split Recharts chunk (initial JS: 117KB, Recharts lazy: 498KB)
- All 48px+ touch targets, mobile-first Tailwind layout

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-03-17 12:24:31 +00:00
Chris Farhood 4e9c888e0f Rename frontend-CLAUDE.md to CLAUDE.md 2026-03-15 17:23:39 -04:00