- Program/PUAN_TURLERI/DilimKey/RankResults/UniturGrubu/ProgramNetSatiri/ SihirbazFacetleri artık src/types/yokatlas.ts'te; lib/db.ts yalnızca sorgu fonksiyonları barındırıyor - RaporSonuc/RaporKapsam/RaporParams/MaskeliRapor src/features/rapor/types/ rapor.ts'e taşındı; ölü kalan TercihSchema/RaporSchema silindi - 11 lib dosyasına import "server-only" eklendi; scripts'in düz node ile import ettiği dosyalara (db, appdb, rapor-havuzu, tadimlik-havuzu, ai/client, ai/cagri, credits) bilinçli eklenmedi - Davranış değişikliği yok; pnpm build yeşil Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
56 lines
1.9 KiB
TypeScript
56 lines
1.9 KiB
TypeScript
import { NextResponse, type NextRequest } from "next/server";
|
||
import { dilimAra, rankWindowFacets } from "@/lib/db";
|
||
import {
|
||
PUAN_TURLERI,
|
||
type DilimKey,
|
||
type PuanTuruKey,
|
||
} from "@/types/yokatlas";
|
||
import { KATEGORILER } from "@/lib/kategoriler";
|
||
|
||
// Sihirbaz modalı için: sıralamaya uygun kategori/il/üniversite tipi
|
||
// facet'leri. Kademeli filtre: `kategori` (tekrarlı) il adımını,
|
||
// `kategori` + `il` (tekrarlı) üniversite tipi adımını süzer — bir önceki
|
||
// adımın seçimi bir sonrakinin seçeneklerini daraltır (bkz. rankWindowFacets).
|
||
export function GET(request: NextRequest) {
|
||
const { searchParams } = request.nextUrl;
|
||
const sira = Number.parseInt(searchParams.get("sira") ?? "", 10);
|
||
const turParam = searchParams.get("tur") ?? "say";
|
||
const tur: PuanTuruKey =
|
||
turParam in PUAN_TURLERI ? (turParam as PuanTuruKey) : "say";
|
||
|
||
if (!Number.isFinite(sira) || sira < 1 || sira > 4_000_000) {
|
||
return NextResponse.json(
|
||
{ error: "Geçerli bir sıralama gerekli." },
|
||
{ status: 400 },
|
||
);
|
||
}
|
||
|
||
const kategoriler = [
|
||
...new Set(
|
||
searchParams
|
||
.getAll("kategori")
|
||
.filter((k) => (KATEGORILER as readonly string[]).includes(k)),
|
||
),
|
||
];
|
||
const iller = [
|
||
...new Set(searchParams.getAll("il").filter((i) => i.trim().length > 0)),
|
||
].slice(0, 5);
|
||
|
||
// ?dilimler=1: /meraklisina'daki canlı dilim şeridi için dilim başına
|
||
// toplam sayılar da eklenir (limit 0 → yalnızca COUNT çalışır)
|
||
const dilimToplam =
|
||
searchParams.get("dilimler") === "1"
|
||
? Object.fromEntries(
|
||
(["hayal", "dengeli", "garanti"] as DilimKey[]).map((d) => [
|
||
d,
|
||
dilimAra(sira, tur, d, { limit: 0 }).toplam,
|
||
]),
|
||
)
|
||
: undefined;
|
||
|
||
return NextResponse.json({
|
||
facetler: rankWindowFacets(sira, tur, { kategoriler, iller }),
|
||
...(dilimToplam ? { dilimToplam } : {}),
|
||
});
|
||
}
|