Commit Graph

27 Commits

Author SHA1 Message Date
8e45d00173 feat(vinpin): vision-loop decode driver (OCR) — reliable VDI automation
Replace the brittle clipboard/fixed-coord extraction with an OCR vision loop:
screenshot -> detect state (login/grid/portal/eper/modal via tesseract keywords)
-> act -> verify -> retry/recover. Adds portal->catalogue detection (the seat
non-deterministically opens a multi-brand portal with no VIN field), not-found
handling, and ffmpeg crop+upscale -> tesseract.js for the decode modal. Only the
model token + year are needed (matcher-tolerant), so OCR garbling is harmless.

Validated live against a trial seat: 6/6 of the ePER-present Fiat VINs decoded to
the correct model (EGEA/DOBLO); 2 genuine "vehicle not found" coverage gaps
reported as null. 8/8 correct outcomes. Still flag-gated off by default; tesseract
is dynamically imported only inside the worker. Warm-session persistence under
swiftshader is the remaining hardening item (currently re-logins per VIN).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-26 11:00:07 +03:00
532e1ad9ef feat(part-prices): parça kodu bazlı tedarikçi fiyat geçmişi + OEM sayfasında p50/p95/p99 grafiği
- pg: part_price_tracks + part_price_daily (0018) — (kod, kaynak, gün) başına
  stoktaki tekliflerin p50/p95/p99 + teklif sayısı; source='supplier' şimdilik,
  perakende ileride aynı tabloya 'retail' olarak girer. Tedarikçi kimliği yok.
- API: GET /part-prices/series (ilk istekte takip history'sinden lazy-backfill,
  sonrası salt-pg + Redis) ve POST /part-prices/current-batch (sayfadaki kodlar
  için canlı güncel istatistik). P-servisi sözleşmesi: asla throw yok, fail-open.
- Worker: part-price-refresh cron'u 19:30 Europe/Istanbul (takip sync'i 19:05'te
  bitiyor) — izlenen kodlara bugünün satırını upsert eder, sku_map'i artımlı
  bakar, Redis cache düşürür. SUPPLIER_PRICE_DB_* yoksa sessiz no-op.
- Kaynak köprüsü: takip.sku_map (code_norm → product_id; tam sku / ilk-boşluk /
  ilk-tire sonrası normalize adayları) vmi MySQL'inde kurulu; 6,8M satır.
- Web: OEM detayında "Tedarikçi fiyat analizi" kartı (güncel medyan + P95/P99 +
  teklif sayısı + 30g delta, 30G/90G/Tümü aralıklı step grafik, recharts) ve
  article/muadil/OE satırlarında fiyat çipi → dialog'da tam geçmiş.
- Fix(p): td snapshot'ında gerçek üretici kodu articles.name'de (article_number
  %96 upstream sayısal ID) — sayfa artık kopyalanabilir gerçek kodu gösteriyor.
- compose: SUPPLIER_PRICE_DB_ENABLED/URL api+worker bloklarına eklendi.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-12 13:33:37 +03:00
72c3fe0dc2 feat(surveys): replace Formbricks with self-rendered PostHog API surveys
Formbricks CE turned out to gate person-based targeting (setUserId/attributes
→ 403 enterprise) — the exact flexibility surveys need. PostHog already holds
the person properties, so surveys move back there in API mode: posthog-js
evaluates eligibility (event triggers, targeting flags like
subscription_status=active, wait periods, per-distinct_id dedup) via
getActiveMatchingSurveys, and we render the popover ourselves — zero PostHog
branding, sase.tr dark-theme styling.

- lib/surveys.ts: display manager + capture payload builders that mirror
  posthog-js's own "survey shown/dismissed/sent" shapes exactly
  ($survey_response_<qid>, $set $survey_dismissed/<id>[/iter], seenSurvey_*,
  lastSeenSurveyDate) so the PostHog Surveys results UI works unchanged
- components/survey-popover.tsx: single_choice (+Diğer), open text, rating/NPS
- posthog.ts: capture/pageview/identify now schedule survey checks; register
  deploy_env (dev.sase.tr ships the key now → staging traffic is filterable)
- remove @formbricks/js, its CSP entries and build args

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-10 00:40:18 +03:00
597391bbdf feat(surveys): Formbricks in-app survey bridge over PostHog events
Self-hosted Formbricks (anket.sase.tr) replaces PostHog surveys (free-tier
branding). PostHog stays the single instrumentation source: capture() forwards
allowlisted trigger events (trial_urgency_banner_viewed, subscription_cancelled,
onboarding_completed, vin_decode_error, empty_catalog_cta_clicked) to the
Formbricks SDK, identify/reset/people-properties mirror into Formbricks
attributes, and $pageview registers SPA route changes for no-code triggers.

- apps/web/src/lib/formbricks.ts: lazy fire-and-forget wrapper (inert without
  VITE_FORMBRICKS_APP_URL + VITE_FORMBRICKS_ENV_ID)
- CSP: allow anket.sase.tr in connect-src/img-src
- Dockerfile + compose: bake the two VITE_ build args

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-09 23:44:45 +03:00
Süper Panel
c6d65e0a89 fix(observability): regenerate pnpm-lock.yaml for @sentry/react
PR #68 added `@sentry/react ^9.0.0` to apps/web/package.json without
updating pnpm-lock.yaml — the merge deploy (zwso4wc44skscw8k0ocw8wwo)
failed at `pnpm install --frozen-lockfile`:

  ERR_PNPM_OUTDATED_LOCKFILE: specifiers in the lockfile don't match
  specifiers in package.json:
  * 1 dependencies were added: @sentry/react@^9.0.0

Regenerated with pnpm@10.29.3 (matches the Dockerfile activation).
Only +80 lines (the new sentry deps); no other importers touched.
2026-06-01 18:20:42 +03:00
4724a71113 feat(api): source-DB lookup-first for pcat/emex catalog fetches
Adds an optional local-dump lookup layer in front of the live PartsCatalogs and
EMEX scrapes. When enabled, getCategoryWithPartsInner queries a Postgres
(pcat) or MariaDB (emex) dump for the requested schema/group's parts and
hotspots; on miss it falls through to the existing upstream call unchanged.
Hits avoid the live API, its cooldown, and its rate-limits — direct DB latency.

- New CatalogSourceDbModule with PcatSourceDbService + EmexSourceDbService
  (raw SQL, no Drizzle schema modeling — dump shapes are frozen snapshots).
- pcat lookup keys on schema_images.schema_ext_id (the dump's column that
  matches sase's pcat groupId; observed ~7% hit rate on prod's 6596 unique
  groupIds, of which ~10% have schema_parts → ~3-5% net parts coverage).
  Joins schema_parts → parts directly; the dump's part_groups+part_group_items
  linkage covers 0 of our hits, so we skip that path entirely.
- emex lookup uses (catalog_id, ssd) → vehicles.id then (vehicle_id, group_id)
  → vehicle_parts → parts + part_images. The ssd is already persisted into
  vehicles.rawData.ssd by the existing emex.mapper, no extra capture needed.

Gated behind CATALOG_SOURCE_DB_ENABLED + PCAT_SOURCE_DB_URL / EMEX_SOURCE_DB_URL.
All three default unset, so this commit is a no-op until prod env is configured.
Adds mysql2 dep for the MariaDB client.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-06-01 00:35:45 +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
2ba2a2703c feat(FN-350): cleanup — FN-344 and FN-347 already absent from board
Commits merged:
- chore(FN-350): cleanup — FN-344 and FN-347 already absent from board

Files changed:
pnpm-lock.yaml | 71 +++++++++-------------------------------------------------
 1 file changed, 10 insertions(+), 61 deletions(-)

Fusion-Task-Id: FN-350

Fusion-Task-Lineage: 43d43125-cdac-4ab3-8b8e-d709ef190c7d
2026-05-14 05:23:27 +00:00
Sase Dev
6a0b36a7a0 feat: replace Iyzico with Stripe + single-page subscription stepper
Subscription/checkout flow rewritten end-to-end. The plan-card "Devam Et"
button silently wiped brand selection on re-click and the actual proceed
button lived offscreen — fixed by collapsing plan/brands/payment/confirm
into a single vertical stepper with one sticky CTA.

Backend
- Stripe Hosted Checkout (`/payments/stripe/checkout`) + webhook
  (`/payments/stripe/webhook`, raw body) replacing the stubbed Iyzico
  module. Webhook activates subscription on `checkout.session.completed`,
  expires the pending subscription on cancel/expire so users can retry.
- New `bank_accounts` table — multiple rows, single `is_active` enforced
  by a partial unique index. Admin CRUD under `/admin/bank-accounts`
  with multipart QR upload to MinIO; atomic `/activate` swap in a
  transaction; `GET /payments/bank-info` returns the active row.
- `payments` gains `stripe_session_id`, `stripe_payment_intent_id`,
  `bank_account_id`. EFT flow now reads the active bank account at
  payment time and stores the FK for reconciliation.
- Env: `IYZICO_*` removed, `STRIPE_*` added (validated by zod schema).
- `main.ts` `rawBody: true` for Stripe signature verification.
- Drizzle 0003 snapshot id collision fixed (VIEW-only migration shared
  prevId with 0002, blocking new generates).

Frontend
- `/dashboard/subscription` rewritten as a 4-step vertical stepper with
  step-aware sticky bottom CTA; plan re-selection is idempotent and
  preserves brand state. `/dashboard/subscription/pay` deleted; Stripe
  returns to the same page via `?stripe=success|cancelled` and the UI
  polls `/subscriptions/me` until the webhook activates the row.
- New components: `bank-transfer-card.tsx` (DB-driven IBAN + Kolay Adres
  + uploaded QR image + receipt upload) and `stripe-checkout-button.tsx`.
- Active subscription view, trial onboarding/urgency banner, downgrade
  and cancel dialogs preserved.
- TR/EN i18n: new `subscription.steps.*`, `subscription.stickyCta.*`,
  `payment.stripe.*`, `payment.bank.*`; provider label updated.

PostHog: `method: "iyzico"` → `"stripe"`; new events `iban_copied`,
`kolay_adres_copied`, `qr_viewed`, `eft_initiated`,
`stripe_redirect_returned`.

Deploy runs `db:migrate` which applies 0004_hot_quicksilver
(additive: new table + nullable columns; safe to apply on prod).
Operator must add `STRIPE_SECRET_KEY`, `STRIPE_PUBLISHABLE_KEY`,
`STRIPE_WEBHOOK_SECRET` to env and create the first
`bank_accounts` row via the admin endpoint before the bank tab works.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-13 22:42:28 +00:00
Fusion
d855b564bf feat(FN-281): add payment_success and payment_failed PostHog events (+1 more)
Some checks failed
Sync dev → Gitea / Mirror dev to Gitea (push) Has been cancelled
Commits merged:
- fix(FN-281): make result search param truly optional to fix typecheck
- feat(FN-281): add payment_success and payment_failed PostHog events

Files changed:
apps/api/package.json                              |    1 +
 apps/api/src/app.module.ts                         |    2 +
 apps/api/src/payments/payments.service.spec.ts     |   99 +-
 apps/api/src/payments/payments.service.ts          |   40 +
 apps/api/src/posthog/posthog.module.ts             |    9 +
 apps/api/src/posthog/posthog.service.ts            |   64 ++
 .../web/src/components/payment/payment-content.tsx |   24 +-
 apps/web/src/routeTree.gen.ts                      | 1110 ++++++++++----------
 apps/web/src/routes/dashboard/subscription/pay.tsx |   24 +-
 packages/config/src/index.ts                       |    4 +
 pnpm-lock.yaml                                     |   30 +
 11 files changed, 827 insertions(+), 580 deletions(-)

Fusion-Task-Id: FN-281
2026-05-13 06:30:58 +00:00
Fusion
e87aba8829 feat(FN-190): move drizzle-kit to production dependencies (+8 more)
Some checks failed
Sync dev → Gitea / Mirror dev to Gitea (push) Has been cancelled
Commits merged:
- feat(FN-190): complete Step 9 — add Migration Workflow section to docs/INDEX.md
- fix(FN-190): apply biome import sorting and formatting
- feat(FN-190): complete Step 7 — write unit tests for migrate runner (5 tests)
- feat(FN-190): complete Step 6 — replace db:push with db:migrate in deploy workflow
- feat(FN-190): complete Step 5 — update Dockerfile with drizzle/ copy and start.sh CMD
- feat(FN-190): complete Step 4 — add db:migrate and db:migrate:dist scripts
- feat(FN-190): complete Step 3 — write migrate runner with bootstrap logic
- feat(FN-190): complete Step 2 — generate baseline Drizzle migration (46 tables)
- feat(FN-190): complete Step 1 — move drizzle-kit to production dependencies

Files changed:
.github/workflows/deploy.yml                    |    2 +-
 Dockerfile                                      |    6 +-
 apps/api/drizzle/0000_brief_guardian.sql        |  658 +++
 apps/api/drizzle/meta/0000_snapshot.json        | 5167 +++++++++++++++++++++++
 apps/api/drizzle/meta/_journal.json             |   13 +
 apps/api/package.json                           |    4 +-
 apps/api/src/database/__tests__/migrate.spec.ts |  179 +
 apps/api/src/database/migrate.ts                |  160 +
 apps/api/start.sh                               |    8 +
 docs/INDEX.md                                   |   24 +-
 pnpm-lock.yaml                                  |    6 +-
 11 files changed, 6220 insertions(+), 7 deletions(-)

Fusion-Task-Id: FN-190
2026-05-11 22:03:33 +00: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
66f30a475c fix: move undici to production dependencies
Some checks failed
CI / Lint, Typecheck, Test & Build (push) Has been cancelled
undici was in devDependencies, causing MODULE_NOT_FOUND crash in
production where only prod deps are installed. Move to dependencies
since emex.service.ts imports ProxyAgent at the top level.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-06 11:45:50 +00:00
cfbf85c5c0 feat: add Coolify deployment config (Docker Compose + ServeStatic)
Some checks failed
CI / Lint, Typecheck, Test & Build (push) Has been cancelled
Deploy / Deploy to Production (push) Has been cancelled
- Add multi-stage Dockerfile (node:22-alpine, pnpm, Chromium for Playwright)
- Add docker-compose.coolify.yml with api, worker, redis services
- Add @nestjs/serve-static for serving Vite frontend from NestJS
- Add .dockerignore

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 12:53:53 +00:00
Sase Dev
f2189a014b perf: lazy load Remotion and PostHog to reduce initial bundle by ~355 KB
- Remotion Player + compositions (SchemaDemo, DashboardDemo, EcommerceDemo)
  replaced with React.lazy wrappers in routes/index.tsx — now split into
  separate chunks loaded only when the landing page sections are visible
- posthog-js static import replaced with a dynamic load() wrapper in
  lib/posthog.ts; all exported functions remain fire-and-forget with the
  same API signature
- subscription/index.tsx updated to use new setPeopleProperties() helper
  instead of the raw posthog instance

Initial chunk: 1,082 KB → 727 KB (-33%), gzip 324 KB → 212 KB

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-28 23:17:54 +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
f1a27810db feat: add parts catalogs integration, catalog prefetch worker, and vehicle select modal
Integrate external parts catalogs API with auth service, add BullMQ-based
catalog prefetch worker for background data caching, expand vehicles service
with shared vehicle support, and add vehicle select modal to frontend.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 18:14:36 +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
dcbeb83ccc feat: add OpenTelemetry observability, Faro frontend monitoring, remove legacy Next.js app
- Add OpenTelemetry SDK with tracing, metrics, and OTLP export for API and worker
- Integrate Grafana Faro for frontend real-user monitoring
- Instrument health checks, database, Bull queues, and HTTP exception filter
- Add Grafana dashboard JSON for service overview
- Remove deprecated apps/web-nj (Next.js) — fully replaced by Vite+React frontend
- Update nginx config with OTEL collector proxy
- Minor UI fixes in schema viewer, category components, and subscription flow

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 17:20:49 +00:00
Sase Dev
87d8eea298 feat: onboarding trial flow, Google sign-in, dark mode hotspot fixes
- Move trial creation from auth hook to dedicated /subscriptions/trial endpoint
  with eligibility checks (3-day Full Paket trial)
- Add animated onboarding progress (Remotion) with confetti on completion
- Register redirects to subscription page with welcome flow
- Add Google social login/signup support with config injection
- Improve hotspot overlay visibility in dark mode
- Show "Panele Git" on landing page when authenticated
- Turkish translations for API error messages
- Add toast utility wrapper, UUID generation for auth IDs

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 14:53:57 +00:00
Sase Dev
bcc614a0c8 feat: add Remotion animated demos to landing page, show all pricing plans
Replace static mockups with Remotion Player animations:
- SchemaDemo: 3x3 grid with spring animations, highlight, part info card
- DashboardDemo: 5-scene product flow (VIN input, vehicle info, categories, schema, OEM codes)
- Both support dark/light theme via isDark prop, autoplay + loop

Expand pricing section from single teaser to all 4 plans with horizontal scroll on mobile.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 07:35:41 +00:00
Sase Dev
4a06ba5fdb feat: Ford legacy support, EMEX browser pooling, collapsible sidebar
- Add PL24 Ford legacy service for fordt_parts architecture
- Refactor EMEX to use persistent browser pool instead of per-call instances
- Make vehicle decode resilient: fallback to PL24 when Corgi doesn't recognize VIN
- Add collapsible sidebar with persistent user preference
- Improve brand access guard and categories service
- Add debug/test scripts for VIN e2e testing

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-14 22:25:06 +00:00
Sase Dev
a8eb8f4bdc refactor(emex): rewrite EMEX integration, add category fallback
Replace browser-based Puppeteer scraper with standalone scraper wrapper.
Add EMEX as fallback source for categories when PL24 is unavailable.
Update vehicle decoding to use new synchronous EMEX API.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-12 19:48:03 +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
ffa9781eb9 fix: auth login flow, Next.js 16 upgrade, ESM/CJS compatibility
- Upgrade Next.js 15 → 16.1 and rename middleware.ts → proxy.ts
- Fix ESM/CJS compatibility: remove "type": "module" from config/shared packages, switch to commonjs
- Fix Better Auth integration: text IDs for sessions/accounts/verifications, wildcard route @All("**"), proper password hash for admin seed
- Fix auth-client to use window.location.origin instead of hardcoded localhost:4000
- Fix api-client, forgot-password, reset-password to use relative /api/ URLs (via Next.js proxy)
- Fix TimeoutInterceptor DI by using useValue instead of useClass
- Add Playwright E2E login tests for localhost and v2.sase.tr
- Add missing UI components: vin-input, vehicle-card, category-tree

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-12 02:54:15 +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