diff --git a/src/app/api/soru/route.ts b/src/app/api/soru/route.ts
index 9a5dfc9..7fe0123 100644
--- a/src/app/api/soru/route.ts
+++ b/src/app/api/soru/route.ts
@@ -13,7 +13,7 @@ import { sohbetAkisi } from "@/lib/ai/cagri";
import { listeOzetiCikar } from "@/lib/ai/rapor";
import type { RaporSonuc } from "@/features/rapor/types/rapor";
import type { RaporParams } from "@/features/rapor/types/rapor";
-import { secimOzeti } from "@/lib/sihirbaz";
+import { secimOzeti } from "@/features/sihirbaz/sihirbaz-sabitler";
import { PUAN_TURLERI } from "@/types/yokatlas";
import { ACIK_SATIR } from "@/lib/rapor-maske";
diff --git a/src/app/listem/liste-uretici.tsx b/src/app/listem/liste-uretici.tsx
index 53ab4f3..3a95942 100644
--- a/src/app/listem/liste-uretici.tsx
+++ b/src/app/listem/liste-uretici.tsx
@@ -13,12 +13,8 @@ import { Button } from "@/components/ui/button";
import { Skeleton } from "@/components/ui/skeleton";
import { listeOlustur } from "@/app/sonuc/actions";
import { olay, siraKovasi } from "@/lib/analitik";
-import {
- sonucHref,
- tercihProfiliOku,
- tercihProfiliSil,
- type TercihProfili,
-} from "@/lib/sihirbaz";
+import { sonucHref, type TercihProfili } from "@/features/sihirbaz/sihirbaz-sabitler";
+import { tercihProfiliOku, tercihProfiliSil } from "@/features/sihirbaz/sihirbaz-profil";
const URETIM_MESAJLARI = [
"Sıralamana uygun programlar taranıyor…",
diff --git a/src/app/listem/listem-bos-cta.tsx b/src/app/listem/listem-bos-cta.tsx
index bf401bc..f08c56f 100644
--- a/src/app/listem/listem-bos-cta.tsx
+++ b/src/app/listem/listem-bos-cta.tsx
@@ -5,7 +5,7 @@ import { ArrowRight } from "lucide-react";
import { Button } from "@/components/ui/button";
import { PagePixelDivider } from "@/components/pixel-decor";
import { useTercihProfili } from "@/components/manuel-liste/profil-kapisi-store";
-import { sonucHref } from "@/lib/sihirbaz";
+import { sonucHref } from "@/features/sihirbaz/sihirbaz-sabitler";
/**
* /listem boş hâlinin metni + CTA'sı: sıralamasını zaten girmiş adaya
diff --git a/src/app/odeme/sonuc/rapor-yok-cta.tsx b/src/app/odeme/sonuc/rapor-yok-cta.tsx
index 5c4d2d3..7b2bc68 100644
--- a/src/app/odeme/sonuc/rapor-yok-cta.tsx
+++ b/src/app/odeme/sonuc/rapor-yok-cta.tsx
@@ -4,7 +4,7 @@ import Link from "next/link";
import { ArrowRight } from "lucide-react";
import { Button } from "@/components/ui/button";
import { useTercihProfili } from "@/components/manuel-liste/profil-kapisi-store";
-import { sonucHref } from "@/lib/sihirbaz";
+import { sonucHref } from "@/features/sihirbaz/sihirbaz-sabitler";
/**
* Ödeme başarılı ama henüz Yapay Zeka listesi yokken gösterilen CTA: kayıtlı tercih
diff --git a/src/app/page.tsx b/src/app/page.tsx
index 3981de2..9728f11 100644
--- a/src/app/page.tsx
+++ b/src/app/page.tsx
@@ -18,7 +18,7 @@ import { Suspense } from "react";
import { ComparisonCell } from "@/features/pazarlama/components/landing-parcalari";
import { HeroBaslik } from "@/features/pazarlama/components/hero-baslik";
import { KapanisCta } from "@/features/pazarlama/components/hero-focus-button";
-import { HeroForm } from "@/components/hero-form";
+import { HeroForm } from "@/features/sihirbaz/components/hero-form";
import { Parallax } from "@/components/parallax";
import { Reveal } from "@/features/pazarlama/components/reveal";
import { SosyalKanitBandi } from "@/features/pazarlama/components/sosyal-kanit";
diff --git a/src/app/rehber/page.tsx b/src/app/rehber/page.tsx
index 4d4590f..ce21288 100644
--- a/src/app/rehber/page.tsx
+++ b/src/app/rehber/page.tsx
@@ -1,7 +1,7 @@
import { Suspense } from "react";
import type { Metadata } from "next";
import { JsonLd, breadcrumbJsonLd } from "@/lib/seo";
-import { CtaSiraForm } from "@/components/cta-sira-form";
+import { CtaSiraForm } from "@/features/sihirbaz/components/cta-sira-form";
import { SiteFooter } from "@/components/site-footer";
import { PagePixelDivider } from "@/components/pixel-decor";
import {
diff --git a/src/app/sonuc/actions.ts b/src/app/sonuc/actions.ts
index 69b9ae9..2164d7c 100644
--- a/src/app/sonuc/actions.ts
+++ b/src/app/sonuc/actions.ts
@@ -21,7 +21,7 @@ import type {
RaporParams,
RaporSonuc,
} from "@/features/rapor/types/rapor";
-import { sihirbazDogrula, type SihirbazSecimleri } from "@/lib/sihirbaz";
+import { sihirbazDogrula, type SihirbazSecimleri } from "@/features/sihirbaz/sihirbaz-sabitler";
import { raporMaskele } from "@/lib/rapor-maske";
diff --git a/src/app/sonuc/page.tsx b/src/app/sonuc/page.tsx
index d20b079..8cf27d0 100644
--- a/src/app/sonuc/page.tsx
+++ b/src/app/sonuc/page.tsx
@@ -4,12 +4,12 @@ import { PUAN_TURLERI, type PuanTuruKey } from "@/types/yokatlas";
import { getSession } from "@/lib/session";
import { kullanicininRaporu } from "@/lib/rapor-kaydi";
import { tadimlikSec } from "@/lib/tadimlik-havuzu";
-import { SihirbazBolumu } from "./sihirbaz-cagri-karti";
+import { SihirbazBolumu } from "@/features/sihirbaz/components/sihirbaz-cagri-karti";
import { TadimlikSatiri } from "./tadimlik-satiri";
import { ProgramTablosu } from "@/components/program-tablosu";
import { ManuelHarita } from "@/components/manuel-liste/manuel-harita";
import { SiteFooter } from "@/components/site-footer";
-import { SiraGerekli } from "./sira-gerekli";
+import { SiraGerekli } from "@/features/sihirbaz/components/sira-gerekli";
export const metadata: Metadata = {
title: "Tercih Listeni Kur",
diff --git a/src/app/sonuc/tadimlik-satiri.tsx b/src/app/sonuc/tadimlik-satiri.tsx
index bd01e18..3e55470 100644
--- a/src/app/sonuc/tadimlik-satiri.tsx
+++ b/src/app/sonuc/tadimlik-satiri.tsx
@@ -25,11 +25,8 @@ import { useGorunumOlayi } from "@/components/use-gorunum-olayi";
import { olay, siraKovasi } from "@/lib/analitik";
import { dilimdenRisk, riskHesapla } from "@/lib/risk";
import { turkishSlugify } from "@/lib/slug";
-import {
- PROFIL_DEGISTI_EVENT,
- sonucHref,
- tercihProfiliOku,
-} from "@/lib/sihirbaz";
+import { PROFIL_DEGISTI_EVENT, sonucHref } from "@/features/sihirbaz/sihirbaz-sabitler";
+import { tercihProfiliOku } from "@/features/sihirbaz/sihirbaz-profil";
import type { TadimlikSatir } from "@/lib/tadimlik-havuzu";
const GENEL = "genel";
diff --git a/src/components/arama-funnel-karti.tsx b/src/components/arama-funnel-karti.tsx
index fe0e364..84e6cec 100644
--- a/src/components/arama-funnel-karti.tsx
+++ b/src/components/arama-funnel-karti.tsx
@@ -10,7 +10,7 @@ import {
} from "lucide-react";
import { Button } from "@/components/ui/button";
import { TypingAnimation } from "@/components/ui/typing-animation";
-import { SIHIRBAZ_AC_EVENT, sonucHref } from "@/lib/sihirbaz";
+import { SIHIRBAZ_AC_EVENT, sonucHref } from "@/features/sihirbaz/sihirbaz-sabitler";
import {
profilToplamaAc,
useTercihProfili,
diff --git a/src/components/dev/dev-panel.tsx b/src/components/dev/dev-panel.tsx
index e37d8b3..a3aea11 100644
--- a/src/components/dev/dev-panel.tsx
+++ b/src/components/dev/dev-panel.tsx
@@ -12,7 +12,7 @@ import { useRouter } from "next/navigation";
import { Wrench, X } from "lucide-react";
import { toast } from "sonner";
import { authClient } from "@/lib/auth-client";
-import { tercihProfiliSil } from "@/lib/sihirbaz";
+import { tercihProfiliSil } from "@/features/sihirbaz/sihirbaz-profil";
import {
devAnindaGiris,
devAyarla,
diff --git a/src/components/manuel-liste/kayitli-liste-actions.ts b/src/components/manuel-liste/kayitli-liste-actions.ts
index b810b69..fc2affe 100644
--- a/src/components/manuel-liste/kayitli-liste-actions.ts
+++ b/src/components/manuel-liste/kayitli-liste-actions.ts
@@ -13,7 +13,7 @@
import { eq } from "drizzle-orm";
import { getSession } from "@/lib/session";
import { appDb, schema } from "@/lib/appdb";
-import { tercihProfiliDogrula, type TercihProfili } from "@/lib/sihirbaz";
+import { tercihProfiliDogrula, type TercihProfili } from "@/features/sihirbaz/sihirbaz-sabitler";
import {
MANUEL_LISTE_MAX,
dogrula,
diff --git a/src/components/manuel-liste/liste-senkron.tsx b/src/components/manuel-liste/liste-senkron.tsx
index 98457d5..be6a298 100644
--- a/src/components/manuel-liste/liste-senkron.tsx
+++ b/src/components/manuel-liste/liste-senkron.tsx
@@ -11,11 +11,8 @@
// - Sonrasında: liste/profil değişimleri ~2 sn debounce ile sunucuya yazılır.
import { useEffect, useRef } from "react";
-import {
- PROFIL_DEGISTI_EVENT,
- tercihProfiliOku,
- tercihProfiliYaz,
-} from "@/lib/sihirbaz";
+import { PROFIL_DEGISTI_EVENT } from "@/features/sihirbaz/sihirbaz-sabitler";
+import { tercihProfiliOku, tercihProfiliYaz } from "@/features/sihirbaz/sihirbaz-profil";
import { listeOku, sunucuylaBirlestir, useManuelListe } from "./store";
import { oturumDurumuBildir } from "./oturum-sinyali";
import { listeSenkronla, listeyiKaydet } from "./kayitli-liste-actions";
diff --git a/src/components/manuel-liste/profil-kapisi-store.ts b/src/components/manuel-liste/profil-kapisi-store.ts
index 39d0fbd..afd9b7f 100644
--- a/src/components/manuel-liste/profil-kapisi-store.ts
+++ b/src/components/manuel-liste/profil-kapisi-store.ts
@@ -5,13 +5,8 @@
import { useSyncExternalStore } from "react";
import type { Program } from "@/types/yokatlas";
-import {
- PROFIL_DEGISTI_EVENT,
- sonucHref,
- tercihProfiliOku,
- tercihProfiliTamamlandiMi,
- type TercihProfili,
-} from "@/lib/sihirbaz";
+import { PROFIL_DEGISTI_EVENT, sonucHref, type TercihProfili } from "@/features/sihirbaz/sihirbaz-sabitler";
+import { tercihProfiliOku, tercihProfiliTamamlandiMi } from "@/features/sihirbaz/sihirbaz-profil";
import {
ekle,
listedeMi,
diff --git a/src/components/manuel-liste/secimlerim-paneli.tsx b/src/components/manuel-liste/secimlerim-paneli.tsx
index 481c2cd..30ad6fe 100644
--- a/src/components/manuel-liste/secimlerim-paneli.tsx
+++ b/src/components/manuel-liste/secimlerim-paneli.tsx
@@ -13,7 +13,7 @@ import {
} from "lucide-react";
import { Button } from "@/components/ui/button";
import { RISK_ETIKET, type RiskSeviyesi } from "@/lib/risk";
-import { sonucHref } from "@/lib/sihirbaz";
+import { sonucHref } from "@/features/sihirbaz/sihirbaz-sabitler";
import {
tercihDegerlendir,
tercihListesiOzeti,
diff --git a/src/components/manuel-liste/store.ts b/src/components/manuel-liste/store.ts
index 388509b..1a1fabf 100644
--- a/src/components/manuel-liste/store.ts
+++ b/src/components/manuel-liste/store.ts
@@ -8,10 +8,8 @@
import { useSyncExternalStore } from "react";
import type { Program } from "@/types/yokatlas";
import { riskHesapla } from "@/lib/risk";
-import {
- tercihProfiliOku,
- type TercihProfili,
-} from "@/lib/sihirbaz";
+import { type TercihProfili } from "@/features/sihirbaz/sihirbaz-sabitler";
+import { tercihProfiliOku } from "@/features/sihirbaz/sihirbaz-profil";
import {
MANUEL_LISTE_MAX,
dogrula,
diff --git a/src/components/manuel-liste/tercih-profili-kapisi.tsx b/src/components/manuel-liste/tercih-profili-kapisi.tsx
index bafe0dc..d6cd283 100644
--- a/src/components/manuel-liste/tercih-profili-kapisi.tsx
+++ b/src/components/manuel-liste/tercih-profili-kapisi.tsx
@@ -25,14 +25,11 @@ import {
import {
SihirbazAdimlarLazy,
preloadSihirbazAdimlar,
-} from "@/components/sihirbaz-adimlar-lazy";
+} from "@/features/sihirbaz/components/sihirbaz-adimlar-lazy";
import type { SihirbazFacetleri } from "@/types/yokatlas";
import { olay, siraKovasi } from "@/lib/analitik";
-import {
- tercihProfiliYaz,
- type SihirbazSecimleri,
- type TercihProfili,
-} from "@/lib/sihirbaz";
+import { type SihirbazSecimleri, type TercihProfili } from "@/features/sihirbaz/sihirbaz-sabitler";
+import { tercihProfiliYaz } from "@/features/sihirbaz/sihirbaz-profil";
import { authClient } from "@/lib/auth-client";
import {
profilKapisiniKapat,
diff --git a/src/features/katalog/components/bolum-listesi.tsx b/src/features/katalog/components/bolum-listesi.tsx
index 8da25b4..e1d88a6 100644
--- a/src/features/katalog/components/bolum-listesi.tsx
+++ b/src/features/katalog/components/bolum-listesi.tsx
@@ -1,7 +1,7 @@
import Link from "next/link";
import { getAllBolumler, type BolumOzet } from "../katalog-queries";
import { KATEGORILER } from "@/lib/kategoriler";
-import { CtaSiraForm } from "@/components/cta-sira-form";
+import { CtaSiraForm } from "@/features/sihirbaz/components/cta-sira-form";
import { PagePixelDivider } from "@/components/pixel-decor";
import { Skeleton } from "@/components/ui/skeleton";
diff --git a/src/features/katalog/components/katalog-arama.tsx b/src/features/katalog/components/katalog-arama.tsx
index 79ab40f..3d26f97 100644
--- a/src/features/katalog/components/katalog-arama.tsx
+++ b/src/features/katalog/components/katalog-arama.tsx
@@ -13,7 +13,7 @@ import {
sonucaGitIste,
useTercihProfili,
} from "@/components/manuel-liste/profil-kapisi-store";
-import { PUAN_TURU_ETIKET } from "@/lib/sihirbaz";
+import { PUAN_TURU_ETIKET } from "@/features/sihirbaz/sihirbaz-sabitler";
import { olay } from "@/lib/analitik";
import {
ArrowRight,
diff --git a/src/features/katalog/components/universite-icerik.tsx b/src/features/katalog/components/universite-icerik.tsx
index d52e0f5..2e82786 100644
--- a/src/features/katalog/components/universite-icerik.tsx
+++ b/src/features/katalog/components/universite-icerik.tsx
@@ -10,7 +10,7 @@ import {
} from "../katalog-queries";
import { trBaslikDuzeni } from "@/lib/slug";
import { JsonLd, breadcrumbJsonLd, SITE_URL } from "@/lib/seo";
-import { CtaSiraForm } from "@/components/cta-sira-form";
+import { CtaSiraForm } from "@/features/sihirbaz/components/cta-sira-form";
import { SiteFooter } from "@/components/site-footer";
import { Sayfalama, SAYFA_BOYU } from "./sayfalama";
import { PagePixelDivider } from "@/components/pixel-decor";
diff --git a/src/features/katalog/components/universite-listesi.tsx b/src/features/katalog/components/universite-listesi.tsx
index 8608769..750ae6c 100644
--- a/src/features/katalog/components/universite-listesi.tsx
+++ b/src/features/katalog/components/universite-listesi.tsx
@@ -1,7 +1,7 @@
import Link from "next/link";
import { getAllUniversiteler, type UniOzet } from "../katalog-queries";
import { trBaslikDuzeni } from "@/lib/slug";
-import { CtaSiraForm } from "@/components/cta-sira-form";
+import { CtaSiraForm } from "@/features/sihirbaz/components/cta-sira-form";
import { PagePixelDivider } from "@/components/pixel-decor";
import { UniLogo } from "@/components/uni-logo";
import { Skeleton } from "@/components/ui/skeleton";
diff --git a/src/features/pazarlama/components/hero-focus-button.tsx b/src/features/pazarlama/components/hero-focus-button.tsx
index 47ba574..3ed43ee 100644
--- a/src/features/pazarlama/components/hero-focus-button.tsx
+++ b/src/features/pazarlama/components/hero-focus-button.tsx
@@ -4,7 +4,7 @@ import Link from "next/link";
import { ArrowRight } from "lucide-react";
import { Button } from "@/components/ui/button";
import { useTercihProfili } from "@/components/manuel-liste/profil-kapisi-store";
-import { sonucHref } from "@/lib/sihirbaz";
+import { sonucHref } from "@/features/sihirbaz/sihirbaz-sabitler";
export function HeroFocusButton() {
function handleClick() {
diff --git a/src/features/pazarlama/components/meraklisina-demo.tsx b/src/features/pazarlama/components/meraklisina-demo.tsx
index 86a259f..c37fd8c 100644
--- a/src/features/pazarlama/components/meraklisina-demo.tsx
+++ b/src/features/pazarlama/components/meraklisina-demo.tsx
@@ -17,7 +17,7 @@ import {
import Link from "next/link";
import { ArrowRight } from "lucide-react";
import { useTercihProfili } from "@/components/manuel-liste/profil-kapisi-store";
-import { PUAN_TURU_ETIKET, sonucHref } from "@/lib/sihirbaz";
+import { PUAN_TURU_ETIKET, sonucHref } from "@/features/sihirbaz/sihirbaz-sabitler";
import type { DilimKey, SihirbazFacetleri } from "@/types/yokatlas";
export type DemoVeri = {
diff --git a/src/features/rehber/components/rehber-makale.tsx b/src/features/rehber/components/rehber-makale.tsx
index 8f162a0..25d75bd 100644
--- a/src/features/rehber/components/rehber-makale.tsx
+++ b/src/features/rehber/components/rehber-makale.tsx
@@ -3,7 +3,7 @@ import Link from "next/link";
import { notFound } from "next/navigation";
import { getAllRehberler, getAllRehberSlugs, getRehber } from "../rehber-queries";
import { JsonLd, articleJsonLd, breadcrumbJsonLd } from "@/lib/seo";
-import { CtaSiraForm } from "@/components/cta-sira-form";
+import { CtaSiraForm } from "@/features/sihirbaz/components/cta-sira-form";
import { ElCizimiSema } from "./el-cizimi-sema";
import { RehberKapak } from "./rehber-kapak";
import { Skeleton } from "@/components/ui/skeleton";
diff --git a/src/components/cta-sira-form.tsx b/src/features/sihirbaz/components/cta-sira-form.tsx
similarity index 98%
rename from src/components/cta-sira-form.tsx
rename to src/features/sihirbaz/components/cta-sira-form.tsx
index 0611be5..37201a1 100644
--- a/src/components/cta-sira-form.tsx
+++ b/src/features/sihirbaz/components/cta-sira-form.tsx
@@ -24,16 +24,13 @@ import { SectionEyebrow } from "@/components/pixel-decor";
import {
SihirbazAdimlarLazy,
preloadSihirbazAdimlar,
-} from "@/components/sihirbaz-adimlar-lazy";
+} from "./sihirbaz-adimlar-lazy";
import { authClient } from "@/lib/auth-client";
import { olay, siraKovasi } from "@/lib/analitik";
import { useTercihProfili } from "@/components/manuel-liste/profil-kapisi-store";
import type { SihirbazFacetleri } from "@/types/yokatlas";
-import {
- sonucHref,
- tercihProfiliYaz,
- type SihirbazSecimleri,
-} from "@/lib/sihirbaz";
+import { sonucHref, type SihirbazSecimleri } from "@/features/sihirbaz/sihirbaz-sabitler";
+import { tercihProfiliYaz } from "@/features/sihirbaz/sihirbaz-profil";
// lib/db sunucu tarafı; etiketler client bundle'a sızmasın diye burada.
const PUAN_TURLERI_SECENEK = [
diff --git a/src/components/hero-form.tsx b/src/features/sihirbaz/components/hero-form.tsx
similarity index 97%
rename from src/components/hero-form.tsx
rename to src/features/sihirbaz/components/hero-form.tsx
index eb0343e..536cbc7 100644
--- a/src/components/hero-form.tsx
+++ b/src/features/sihirbaz/components/hero-form.tsx
@@ -15,7 +15,7 @@ import {
import {
SihirbazAdimlarLazy,
preloadSihirbazAdimlar,
-} from "@/components/sihirbaz-adimlar-lazy";
+} from "./sihirbaz-adimlar-lazy";
import { authClient } from "@/lib/auth-client";
import { olay, siraKovasi } from "@/lib/analitik";
import {
@@ -23,12 +23,8 @@ import {
useTercihProfili,
} from "@/components/manuel-liste/profil-kapisi-store";
import type { SihirbazFacetleri } from "@/types/yokatlas";
-import {
- PUAN_TURU_ETIKET,
- sonucHref,
- tercihProfiliYaz,
- type SihirbazSecimleri,
-} from "@/lib/sihirbaz";
+import { PUAN_TURU_ETIKET, sonucHref, type SihirbazSecimleri } from "@/features/sihirbaz/sihirbaz-sabitler";
+import { tercihProfiliYaz } from "@/features/sihirbaz/sihirbaz-profil";
// lib/db sunucu tarafı; etiketler client bundle'a sızmasın diye burada.
const PUAN_TURLERI_SECENEK = [
diff --git a/src/components/il-secim-haritasi.tsx b/src/features/sihirbaz/components/il-secim-haritasi.tsx
similarity index 100%
rename from src/components/il-secim-haritasi.tsx
rename to src/features/sihirbaz/components/il-secim-haritasi.tsx
diff --git a/src/components/sihirbaz-adimlar-lazy.tsx b/src/features/sihirbaz/components/sihirbaz-adimlar-lazy.tsx
similarity index 93%
rename from src/components/sihirbaz-adimlar-lazy.tsx
rename to src/features/sihirbaz/components/sihirbaz-adimlar-lazy.tsx
index 201dbc8..03cff3b 100644
--- a/src/components/sihirbaz-adimlar-lazy.tsx
+++ b/src/features/sihirbaz/components/sihirbaz-adimlar-lazy.tsx
@@ -45,7 +45,7 @@ function SihirbazAdimlarSkeleton() {
export const SihirbazAdimlarLazy = dynamic(
() =>
- import("@/components/sihirbaz-adimlar").then((m) => m.SihirbazAdimlar),
+ import("./sihirbaz-adimlar").then((m) => m.SihirbazAdimlar),
{
ssr: false,
loading: () => ,
@@ -54,5 +54,5 @@ export const SihirbazAdimlarLazy = dynamic(
/** Kullanıcı forma dokunduğu anda chunk'ı arka planda indir. */
export function preloadSihirbazAdimlar() {
- void import("@/components/sihirbaz-adimlar");
+ void import("./sihirbaz-adimlar");
}
diff --git a/src/components/sihirbaz-adimlar.tsx b/src/features/sihirbaz/components/sihirbaz-adimlar.tsx
similarity index 98%
rename from src/components/sihirbaz-adimlar.tsx
rename to src/features/sihirbaz/components/sihirbaz-adimlar.tsx
index 8cbf570..2197bd3 100644
--- a/src/components/sihirbaz-adimlar.tsx
+++ b/src/features/sihirbaz/components/sihirbaz-adimlar.tsx
@@ -15,17 +15,12 @@ import { toast } from "sonner";
import { cities } from "turkey-map-react/lib/data";
import { TransitionPanel } from "@/components/core/transition-panel";
import { Button } from "@/components/ui/button";
-import { IlSecimHaritasi } from "@/components/il-secim-haritasi";
+import { IlSecimHaritasi } from "./il-secim-haritasi";
import { normalizeIlAdi } from "@/lib/harita";
import { olay } from "@/lib/analitik";
import { trBaslikDuzeni } from "@/lib/slug";
import type { SihirbazFacetleri } from "@/types/yokatlas";
-import {
- ONCELIKLER,
- UNIVERSITE_TIPI_ETIKET,
- type SihirbazSecimleri,
- type UniversiteTipi,
-} from "@/lib/sihirbaz";
+import { ONCELIKLER, UNIVERSITE_TIPI_ETIKET, type SihirbazSecimleri, type UniversiteTipi } from "@/features/sihirbaz/sihirbaz-sabitler";
export function Cip({
secili,
diff --git a/src/app/sonuc/sihirbaz-cagri-karti.tsx b/src/features/sihirbaz/components/sihirbaz-cagri-karti.tsx
similarity index 98%
rename from src/app/sonuc/sihirbaz-cagri-karti.tsx
rename to src/features/sihirbaz/components/sihirbaz-cagri-karti.tsx
index 32721ae..4a4412b 100644
--- a/src/app/sonuc/sihirbaz-cagri-karti.tsx
+++ b/src/features/sihirbaz/components/sihirbaz-cagri-karti.tsx
@@ -11,13 +11,8 @@ import { PixelField } from "@/components/pixel-decor";
import { useGorunumOlayi } from "@/components/use-gorunum-olayi";
import { olay } from "@/lib/analitik";
import type { SihirbazFacetleri } from "@/types/yokatlas";
-import {
- SIHIRBAZ_AC_EVENT,
- SIHIRBAZ_STORAGE_KEY,
- sihirbazDogrula,
- tercihProfiliYaz,
- type SihirbazSecimleri,
-} from "@/lib/sihirbaz";
+import { SIHIRBAZ_AC_EVENT, SIHIRBAZ_STORAGE_KEY, sihirbazDogrula, type SihirbazSecimleri } from "@/features/sihirbaz/sihirbaz-sabitler";
+import { tercihProfiliYaz } from "@/features/sihirbaz/sihirbaz-profil";
import { SihirbazModal } from "./sihirbaz-modal";
// Üretim /listem'de koşar (bkz. listem/liste-uretici.tsx); sihirbaz
diff --git a/src/app/sonuc/sihirbaz-modal.tsx b/src/features/sihirbaz/components/sihirbaz-modal.tsx
similarity index 91%
rename from src/app/sonuc/sihirbaz-modal.tsx
rename to src/features/sihirbaz/components/sihirbaz-modal.tsx
index 79b928a..ee87813 100644
--- a/src/app/sonuc/sihirbaz-modal.tsx
+++ b/src/features/sihirbaz/components/sihirbaz-modal.tsx
@@ -6,9 +6,9 @@ import {
DialogDescription,
DialogTitle,
} from "@/components/ui/dialog";
-import { SihirbazAdimlarLazy } from "@/components/sihirbaz-adimlar-lazy";
+import { SihirbazAdimlarLazy } from "./sihirbaz-adimlar-lazy";
import type { SihirbazFacetleri } from "@/types/yokatlas";
-import type { SihirbazSecimleri } from "@/lib/sihirbaz";
+import type { SihirbazSecimleri } from "@/features/sihirbaz/sihirbaz-sabitler";
/**
* Sihirbaz modalı artık yalnızca adımları toplar; üretim, önizleme ve liste
diff --git a/src/app/sonuc/sira-gerekli.tsx b/src/features/sihirbaz/components/sira-gerekli.tsx
similarity index 97%
rename from src/app/sonuc/sira-gerekli.tsx
rename to src/features/sihirbaz/components/sira-gerekli.tsx
index aa84c48..4c9cc12 100644
--- a/src/app/sonuc/sira-gerekli.tsx
+++ b/src/features/sihirbaz/components/sira-gerekli.tsx
@@ -9,7 +9,7 @@ import Link from "next/link";
import { ArrowLeft, Trophy } from "lucide-react";
import { Button } from "@/components/ui/button";
import { PagePixelDivider } from "@/components/pixel-decor";
-import { sonucHref } from "@/lib/sihirbaz";
+import { sonucHref } from "@/features/sihirbaz/sihirbaz-sabitler";
import {
sonucaGitIste,
useProfilKapisi,
diff --git a/src/features/sihirbaz/sihirbaz-profil.ts b/src/features/sihirbaz/sihirbaz-profil.ts
new file mode 100644
index 0000000..77bc42a
--- /dev/null
+++ b/src/features/sihirbaz/sihirbaz-profil.ts
@@ -0,0 +1,49 @@
+// Ortak tercih profilinin localStorage katmanı — yalnızca client'ta anlamlı.
+// Şema, doğrulama ve sabitler sihirbaz-sabitler.ts'te yaşar.
+
+import {
+ PROFIL_DEGISTI_EVENT,
+ SIHIRBAZ_STORAGE_KEY,
+ tercihProfiliDogrula,
+ type TercihProfili,
+} from "./sihirbaz-sabitler";
+
+function profilDegistiginiYayinla(): void {
+ window.dispatchEvent(new Event(PROFIL_DEGISTI_EVENT));
+}
+
+/** Client'ta SIHIRBAZ_STORAGE_KEY'den doğrulanmış profil okur. */
+export function tercihProfiliOku(): TercihProfili | null {
+ if (typeof window === "undefined") return null;
+ try {
+ const ham = localStorage.getItem(SIHIRBAZ_STORAGE_KEY);
+ if (!ham) return null;
+ return tercihProfiliDogrula(JSON.parse(ham));
+ } catch {
+ return null;
+ }
+}
+
+/** Ortak profili yazar; hero ve Yapay Zeka sihirbazıyla aynı anahtarı kullanır. */
+export function tercihProfiliYaz(profil: TercihProfili): void {
+ if (typeof window === "undefined") return;
+ const dogru = tercihProfiliDogrula(profil);
+ if (!dogru) return;
+ try {
+ localStorage.setItem(SIHIRBAZ_STORAGE_KEY, JSON.stringify(dogru));
+ } catch {}
+ profilDegistiginiYayinla();
+}
+
+/** Profili siler (ör. Yapay Zeka listesi üretilip seçimler tüketildiğinde). */
+export function tercihProfiliSil(): void {
+ if (typeof window === "undefined") return;
+ try {
+ localStorage.removeItem(SIHIRBAZ_STORAGE_KEY);
+ } catch {}
+ profilDegistiginiYayinla();
+}
+
+export function tercihProfiliTamamlandiMi(): boolean {
+ return tercihProfiliOku() !== null;
+}
diff --git a/src/lib/sihirbaz.ts b/src/features/sihirbaz/sihirbaz-sabitler.ts
similarity index 77%
rename from src/lib/sihirbaz.ts
rename to src/features/sihirbaz/sihirbaz-sabitler.ts
index a3e485c..1e6a948 100644
--- a/src/lib/sihirbaz.ts
+++ b/src/features/sihirbaz/sihirbaz-sabitler.ts
@@ -1,8 +1,10 @@
-// Sonuç sayfasındaki sihirbaz modalının seçim şeması, doğrulaması ve prompt özeti.
+// Sihirbazın seçim şeması, doğrulaması ve prompt özeti — izomorfik katman:
+// hem client bileşenleri hem server action'ları/AI motoru buradan okur.
+// localStorage'a dokunan profil yardımcıları sihirbaz-profil.ts'te yaşar.
// Kategoriler/iller sıralamaya göre dinamik üretilir (bkz. rankWindowFacets);
// öncelikler statik kalır (veriye bağlı değil, tercih niyeti).
-import { KATEGORILER } from "./kategoriler";
+import { KATEGORILER } from "@/lib/kategoriler";
import type { UniturGrubu } from "@/types/yokatlas";
export const ONCELIKLER = [
@@ -43,10 +45,6 @@ export const PROFIL_DEGISTI_EVENT = "kolaytercih:profil-degisti";
// orkestratörünü (SihirbazBolumu) bu olayla açar.
export const SIHIRBAZ_AC_EVENT = "kolaytercih:sihirbaz-ac";
-function profilDegistiginiYayinla(): void {
- window.dispatchEvent(new Event(PROFIL_DEGISTI_EVENT));
-}
-
export interface SihirbazSecimleri {
kategoriler: string[];
iller: string[];
@@ -128,42 +126,6 @@ export function tercihProfiliDogrula(girdi: unknown): TercihProfili | null {
return { sira, tur: p.tur, secimler };
}
-/** Client'ta SIHIRBAZ_STORAGE_KEY'den doğrulanmış profil okur. */
-export function tercihProfiliOku(): TercihProfili | null {
- if (typeof window === "undefined") return null;
- try {
- const ham = localStorage.getItem(SIHIRBAZ_STORAGE_KEY);
- if (!ham) return null;
- return tercihProfiliDogrula(JSON.parse(ham));
- } catch {
- return null;
- }
-}
-
-/** Ortak profili yazar; hero ve Yapay Zeka sihirbazıyla aynı anahtarı kullanır. */
-export function tercihProfiliYaz(profil: TercihProfili): void {
- if (typeof window === "undefined") return;
- const dogru = tercihProfiliDogrula(profil);
- if (!dogru) return;
- try {
- localStorage.setItem(SIHIRBAZ_STORAGE_KEY, JSON.stringify(dogru));
- } catch {}
- profilDegistiginiYayinla();
-}
-
-/** Profili siler (ör. Yapay Zeka listesi üretilip seçimler tüketildiğinde). */
-export function tercihProfiliSil(): void {
- if (typeof window === "undefined") return;
- try {
- localStorage.removeItem(SIHIRBAZ_STORAGE_KEY);
- } catch {}
- profilDegistiginiYayinla();
-}
-
-export function tercihProfiliTamamlandiMi(): boolean {
- return tercihProfiliOku() !== null;
-}
-
/** Profildeki sıra/tur ile sonuç sayfası URL'i — tüm uygulama aynı sorguyu kullanır. */
export function sonucHref(
profil: Pick,
diff --git a/src/lib/ai/rapor.ts b/src/lib/ai/rapor.ts
index e0bcb95..7d6e305 100644
--- a/src/lib/ai/rapor.ts
+++ b/src/lib/ai/rapor.ts
@@ -17,7 +17,7 @@ import {
type Dilim,
type AdayProgram,
} from "../rapor-havuzu";
-import { secimOzeti } from "../sihirbaz";
+import { secimOzeti } from "@/features/sihirbaz/sihirbaz-sabitler";
import { RISK_ETIKET, dilimdenRisk, riskHesapla } from "../risk";
// Yapay zekâdan istenen küçük şema (kullanıcı kararı, 6 Ağu 2026): riskNotu
diff --git a/src/lib/tercih-degerlendirme.ts b/src/lib/tercih-degerlendirme.ts
index fd5e86a..7a54aed 100644
--- a/src/lib/tercih-degerlendirme.ts
+++ b/src/lib/tercih-degerlendirme.ts
@@ -1,6 +1,6 @@
import { kategoriEslesir } from "./kategoriler";
import { riskHesapla, type RiskSeviyesi } from "./risk";
-import type { TercihProfili } from "./sihirbaz";
+import type { TercihProfili } from "@/features/sihirbaz/sihirbaz-sabitler";
export type DegerlendirilecekProgram = {
isim: string;