Commit Graph

17 Commits

Author SHA1 Message Date
afaeec93d7 feat(analytics): heatmaps + feature-flag hook + first A/B test
- Enable PostHog heatmaps (coordinate-only; autocapture stays off so the
  PII-heavy logged-in dashboard never ships VIN/OEM text to PostHog).
- Add reusable feature-flag plumbing: subscribeFeatureFlag in lib/posthog
  and a useFeatureFlag React hook (works for boolean flags + experiments).
- Wire experiment `demo-cta-copy` into DemoFooterCta: control = current
  "sınırsız sorgulama" framing, benefit = B2B OEM value hook. Variant is
  tagged on demo_to_register_click; exposure tracked via $feature_flag_called.

PostHog experiment 82775 created in draft (primary metric: demo→user_signed_up,
test accounts excluded). Launches after this reaches prod.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-04 01:27:14 +03:00
232c9ccc7a feat(pl24): make "bk. tablo:" BOM cross-references navigable
PL24 BOM emits "see table NNN-NNN" reference rows (oem N/A, target code in
remark) with NO upstream link. Resolve the code against the vehicle's
illustration index (codes live in category names as {NNN-NNN}) and render
jump links. Unresolved targets (branch not seeded yet) deep-link a pre-filled
catalog search via ?q=.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-02 18:55:42 +03:00
e4b13c6abb fix(web): mobile schema page traps users above the parts list (#76)
On mobile (iOS Safari, 390px), the schema viewport's one-finger touchmove
handler called setPan() unconditionally — even at zoom 1 with nothing to
pan — which makes iOS suppress the native page scroll. Users couldn't reach
the parts list below the fold (real trial session: 16 rage clicks, 0 OEM
codes copied, no purchase).

- use-schema-interaction: gate one-finger pan on zoom > 1 so the gesture
  falls through to native page scroll when not zoomed in.
- schema-viewer: set touch-action (pan-y pinch-zoom at zoom 1, none when
  zoomed) on the viewport; shrink mobile schema height 400px -> 280px so the
  first parts rows peek below the fold and signal "more below".
- parts-panel: after a hotspot tap, scrollIntoView uses block:"start" on
  mobile (panel is below the fold) and block:"center" on desktop, so the
  selection is actually visible.

Tests: new Vitest hook test asserts no pan at zoom<=1, pans at zoom>1, and
pinch-zoom still works; new parts-panel scroll test asserts mobile vs desktop
block target. Also fixes a pre-existing typo in the empty-state test ("Geri
don" -> "Geri dön").

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-02 12:34:47 +03:00
078076b619 feat(demo): public /demo namespace serving pre-warmed VW Golf 2003 catalog
Replaces the old marketing "guided tour" /demo with a real, fully-functional
catalog browsing experience for the pre-warmed example vehicle. No auth
required, no upstream calls — entirely served from prod DB.

Backend (apps/api/src/demo):
* New @Public() controller exposing five endpoints under /api/demo:
  - GET /vehicle                    → demo vehicle metadata
  - GET /categories/tree            → top-level category tree
  - GET /categories/search?q=       → cross-tree search
  - GET /categories/:id             → getCategoryWithParts (parts+schema+hotspots)
  - GET /categories/:id/children    → drill children
* DemoService validates every category id against DEMO_VEHICLE_ID before any
  downstream service call — the public surface can't be used to read an
  arbitrary vehicle's catalog (1-row SELECT, NotFound on miss or wrong owner).
* Vehicle id is env-driven (DEMO_VEHICLE_ID, defaults to the pre-warmed
  WVWZZZ1JZ3W597935 — VW Golf 2003 with 277 cats / 9841 parts / 178 schemas
  fully drilled in prod).
* Wires CategoriesModule (already exports CategoriesService) — zero new
  business logic, just a thin public façade.

Frontend (apps/web):
* /demo (replaces old marketing page): vehicle header + top categories grid
  reading /api/demo/* + sticky DemoBanner with sign-up CTA.
* /demo/categories/$categoryId: drill page rendering either a children grid
  (parent) or the existing SchemaViewer + parts panel (leaf) — same shape
  the dashboard uses, so hotspot overlay, breadcrumb trail, retry on
  upstream loadError all just work.
* DemoBanner: sticky top, "Örnek araç: {label} — Kayıt Ol" CTA. The
  "Yeni VIN sorgula" explicit paywall trigger lands in a follow-up task.
* PostHog events: demo_loaded (source query-param-aware),
  demo_category_clicked, demo_category_detail_viewed, demo_to_register_click
  (banner / footer / category_footer placements).
* usePageMeta gains an opt-in `noindex` flag — demo sets it to noindex,follow
  for the first 4-6 weeks per spec; cleaned up on unmount so SPA navigation
  doesn't carry it to the next route.
2026-06-02 00:07:29 +03:00
efd42ade4a fix(web): align remaining "50+ marka" claims to the real count (27)
Follow-up to the landing fix: the credibility strip (subscription/checkout),
meta description, auth-layout badge and blog copy still claimed "50+
marka" while the catalog supports 27. Align all to 27 for consistency.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-27 11:59:46 +03:00
001ad1986c feat(web): unify vehicle drill-down breadcrumb & back navigation
The vehicle category flow had two competing navigation models: the grid
drilled in place (no URL change, own breadcrumb) while the category route
had a separate breadcrumb reconstructed from the cached tree plus a back
button with different semantics. The route breadcrumb collapsed on
refresh/deep-link and for lazily-fetched deep nodes, and browser-back from
an in-grid drill ejected the user out of the whole flow.

Make the URL + a server-provided ancestor trail the single source of truth:

- API: getCategoryWithParts now returns `ancestors[]` (root→parent) via a
  recursive CTE, so breadcrumbs are complete regardless of client cache.
- New shared <CategoryBreadcrumb> (Arama → vehicle → ancestors → current)
  used by both the vehicle and category pages.
- Category page back button derives the parent from `ancestors` (no more
  cache-path race); cache reconstruction (findCategoryPath) removed.
- CategoryGrid drills via route navigation per level (each level a URL +
  history entry), seeding the query cache for instant render. Browser-back
  now goes up one level and deep levels are shareable/refreshable.
- Tree & Columns intentionally keep their in-place paradigm.
- a11y: aria-labels on back buttons and the breadcrumb nav.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-25 22:55:01 +03:00
6e5c4b262d fix(web): align catalog figures site-wide to 50+ marka / 1M+ parça
The pricing/subscription credibility strip stated 50+ marka / 1M+ parça
(the current real figures) while the rest of the site still showed the
outdated 27+ marka / 243K parça — so the same visitor saw "1M+ parts" on
pricing and "243K parts" on register. Updated every catalog-scale claim
(SEO/OG/Twitter meta, page-meta default, homepage stat cards + feature
cards + CTA list, auth promo panel, blog prose) to the consistent
50+ marka / 1M+ parça. Also sorted blog imports for biome.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-25 22:07:55 +03:00
df85ebad83 feat(web): show retry prompt when a category fails to load from source
Some checks failed
QA Gate (P0/P1) / Test affected app (pull_request) Has been cancelled
When getCategoryWithParts reports loadError (the PL24 catalog fetch failed
rather than the category being genuinely empty), the leaf view now renders a
"Katalog şu an yüklenemedi — tekrar dene" alert with a retry button instead of
the misleading "Bu kategori için parça bulunamadı" empty state. Genuine empty
leaves are unaffected.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-25 04:36:46 +03:00
e5c852b537 feat(blog): data-driven blog API + DB for content-pipeline publishing
Makes the blog publishable from the Süper Panel content pipeline (via n8n).
Backend mirrors the changelog module; frontend keeps the existing hand-authored
posts and merges in API-backed ones (no content migration, no regression).

API (apps/api):
- blog_posts Drizzle table (slug unique, title, meta_description, body_markdown,
  tags, cover_image, status, source, published_at)
- blog module: GET /blog/posts (public list), GET /blog/posts/:slug (public),
  POST /blog/posts/internal (Bearer BLOG_AUTOMATION_TOKEN, mirrors
  changelog/internal) — returns { ...post, url }
- BlogService: Drizzle + Redis cache, defensive Turkish-aware slugify +
  uniqueness; registered in app.module

Web (apps/web):
- use-blog hooks (list + by-slug, react-query, 30m staleTime)
- blog list: static + API merged, dedup by slug, newest first
- blog detail: static post renders as before; API post renders body_markdown
  via react-markdown (remark-gfm) styled to match existing prose
- add react-markdown + remark-gfm

Deploy: set BLOG_AUTOMATION_TOKEN (and optional PUBLIC_WEB_URL) on the api,
run drizzle-kit db:push to create blog_posts.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-24 01:48:10 +03:00
Fusion
85ebd35048 feat(FN-188): add Changelog tab to dashboard settings
Some checks failed
Sync dev → Gitea / Mirror dev to Gitea (push) Has been cancelled
Squash-recovery of fusion/fn-188 onto dev — original branch was based on
main (dccd4fa) due to baseBranch=None drift in Fusion settings; rebase
onto dev surfaced unrelated main-only commits (EMEX/PL24/Corgi) as false
conflicts. This commit applies only FN-188's 23-file changelog patch.

- apps/api: ChangelogModule (controller, service, DTO, spec, schema)
- apps/web: ChangelogTab (timeline + accordion), useChangelog hook, i18n
- packages/shared: changelog Zod schemas + types
- packages/ui: Accordion component + Badge stage variant
- docs/INDEX.md: changelog feature documented

Lint, typecheck, all 169 api tests + 2 web tests pass.
2026-05-11 20:05:16 +00:00
Fusion
f4fea1e429 feat(FN-094): add comment line for deployment verification
Some checks failed
Sync dev → Gitea / Mirror dev to Gitea (push) Has been cancelled
- Added a comment line to main.ts for deployment verification purposes
2026-05-11 02:07:03 +00:00
Sase Dev
c03addcadc fix: meta description 150 karaktere uzatıldı, apple-touch-icon eklendi
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-22 14:28:25 +00:00
Sase Dev
7194393e6d feat: SEO altyapısı — pre-render, meta tags, blog posts, robots/sitemap
- vite-plugin-prerender yerine Playwright tabanlı post-build pre-render scripti
  (apps/web/scripts/prerender.mjs): 10 public route statik HTML'e dönüştürülüyor
- usePageMeta hook: her public route'da özgün title/description/canonical/OG tags
- index.html: favicon.svg, canonical, OG/Twitter Card, geliştirilmiş title+desc
- apps/web/public/: robots.txt, sitemap.xml (10 URL), favicon.svg
- nginx HSTS header eklendi (Strict-Transport-Security)
- Blog post sayfaları: blog_/$slug.tsx (4 tam yazı, 600-800 kelime)
- blog.tsx: post kartlarına Link eklendi
- Homepage: Schema.org JSON-LD (Organization + SoftwareApplication)
- Footer: placeholder href="#" sosyal linkler kaldırıldı
- deploy.sh + deploy.yml: playwright install chromium + prerender adımı

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-22 14:15:35 +00:00
Sase Dev
f3f3f57756 feat: propagate PL24 part metadata, improve auth UX with Google sign-in prominence
- Add unavailable/remark/modelCodes/presel fields to categories and parts DB schema
- Pass PL24 unavailable flag through pipeline instead of filtering out records
- Show unavailable categories/parts at reduced opacity in grid, tree, and parts panel
- Display part remark and model codes as secondary info in parts table
- Move Google sign-in button above email form on login/register pages with branded icon
- Add public email existence check endpoint for better login error messages
- Update INDEX.md documentation

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 11:11:28 +00:00
Sase Dev
f2126754a6 feat: add OEM code copy tracking, PostHog analytics, Postal email integration
- Add oem_code_copies table and analytics module for tracking part code copies
- Integrate PostHog for frontend product analytics (VIN decode, OEM copy events)
- Switch email service from stub to Postal API with proper error handling
- Add copy button to parts panel with clipboard + server-side logging
- Add admin copy-logs page with filtering and top-copied-codes view
- Add VIN report endpoint for users to flag unrecognized chassis numbers
- Add Postal email env vars to config schema

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 18:09:07 +00:00
Sase Dev
996d614d50 feat: admin user creation, Vite migration, dialog fix, pl24 integration
- Add POST /admin/users endpoint with password hashing and role support
- Add user creation dialog to admin users page
- Migrate web from Next.js to Vite + TanStack Router
- Fix Dialog component positioning for Tailwind CSS v4
- Add @source directive for @sase/ui package scanning
- Add pl24 integration parsers and vehicle decode flow
- Backup old Next.js app to apps/web-nj

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-12 14:24:58 +00:00
Sase Dev
56a3c8bfaa feat: sase.tr v2 full application implementation
Complete rewrite of sase.tr VIN lookup platform with modern stack:

Backend (NestJS 10 + Drizzle ORM + PostgreSQL + Redis + BullMQ):
- 34 DB models (core + PL24 + EMEX schemas)
- Auth via Better Auth (email/password + social)
- Brands, Plans, Subscriptions, Payments (iyzico + EFT)
- VIN decode orchestration (Corgi + PL24 + EMEX + NHTSA)
- Interactive schema viewer backend (MinIO storage)
- EMEX scraping integration (Puppeteer + BullMQ workers)
- Translation module (EN→TR automotive dictionary)
- Admin dashboard API (stats, user mgmt, payment approval)
- Rate limiting, Helmet security, file upload validation

Frontend (Next.js 15 + Tailwind v4 + shadcn/ui + TanStack Query + Zustand):
- 20 routes: auth, dashboard, VIN search, schema viewer, admin
- Interactive schema viewer with zoom/pan/hotspot highlighting
- Subscription management with brand selector
- Payment flow (iyzico 3D Secure + EFT with receipt upload)
- i18n support (TR/EN)
- Error boundaries, loading skeletons, 404 page

Infrastructure:
- 85 tests (52 backend + 33 frontend, Vitest)
- CI/CD (GitHub Actions: lint, typecheck, test, build, deploy)
- Zero-downtime deploy script (PM2)
- Env validation script

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-12 02:03:56 +00:00