feat: kimlik doğrulama, ödeme, kredi ve AI rapor sihirbazı ekle
- better-auth ile giriş/oturum yönetimi (src/lib/auth, giris sayfası) - iyzico ödeme entegrasyonu ve paket satın alma akışı - kredi sistemi ve uygulama veritabanı şeması (drizzle) - AI destekli rapor üretimi ve tercih sihirbazı - rapor yazdırma sayfası ve site header/kullanıcı menüsü Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
133
src/lib/rapor-havuzu.ts
Normal file
133
src/lib/rapor-havuzu.ts
Normal file
@@ -0,0 +1,133 @@
|
||||
import {
|
||||
searchByRank,
|
||||
type Program,
|
||||
type PuanTuruKey,
|
||||
type UniturGrubu,
|
||||
PUAN_TURLERI,
|
||||
} from "./db";
|
||||
import { kategoriEslesir } from "./kategoriler";
|
||||
|
||||
export type Dilim = "hayal" | "dengeli" | "garanti";
|
||||
|
||||
export interface AdayProgram extends Program {
|
||||
dilim: Dilim;
|
||||
}
|
||||
|
||||
export interface RaporParams {
|
||||
sira: number;
|
||||
tur: PuanTuruKey;
|
||||
// Sihirbaz seçimleri (yeni akış)
|
||||
kategoriler?: string[];
|
||||
iller?: string[];
|
||||
universiteTipi?: UniturGrubu | "farketmez";
|
||||
oncelikler?: string[];
|
||||
// Eski akış alanları (geriye uyum — eski kayıtlı raporlar)
|
||||
il?: string;
|
||||
notlar?: string;
|
||||
}
|
||||
|
||||
export interface HavuzSonuc {
|
||||
havuz: AdayProgram[];
|
||||
// Havuz 24'e ulaşmak için hangi filtreler gevşetildi
|
||||
gevsetildi: ("kategori" | "il")[];
|
||||
}
|
||||
|
||||
const HEDEF = 24;
|
||||
const LIMIT = 60;
|
||||
|
||||
function dilimEkle(r: {
|
||||
hayal: Program[];
|
||||
dengeli: Program[];
|
||||
garanti: Program[];
|
||||
}): AdayProgram[] {
|
||||
return [
|
||||
...r.hayal.map((p) => ({ ...p, dilim: "hayal" as const })),
|
||||
...r.dengeli.map((p) => ({ ...p, dilim: "dengeli" as const })),
|
||||
...r.garanti.map((p) => ({ ...p, dilim: "garanti" as const })),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Deterministik aday havuzu: Claude bu havuzdan SEÇER, asla uydurmaz.
|
||||
* Sihirbaz seçimlerine (kategori/il/üniversite tipi) göre filtreler; havuz
|
||||
* 24'ün altına düşerse kademeli gevşetir (önce il, sonra kategori) ki liste
|
||||
* her zaman kurulabilsin.
|
||||
*/
|
||||
export function havuzOlustur(params: RaporParams): HavuzSonuc {
|
||||
const uniturGrubu =
|
||||
params.universiteTipi && params.universiteTipi !== "farketmez"
|
||||
? params.universiteTipi
|
||||
: undefined;
|
||||
const kategoriler = params.kategoriler ?? [];
|
||||
const iller = [
|
||||
...(params.il ? [params.il] : []),
|
||||
...(params.iller ?? []),
|
||||
].filter((v, i, a) => v && a.indexOf(v) === i);
|
||||
|
||||
const kategoriFiltre = (havuz: AdayProgram[]) =>
|
||||
kategoriler.length > 0
|
||||
? havuz.filter((p) => kategoriEslesir(p.isim, kategoriler))
|
||||
: havuz;
|
||||
|
||||
// 1. Tam filtre: iller + üniversite tipi (SQL), kategori (JS)
|
||||
const tamHam = dilimEkle(
|
||||
searchByRank(params.sira, params.tur, {
|
||||
iller: iller.length > 0 ? iller : undefined,
|
||||
uniturGrubu,
|
||||
limitPerBucket: LIMIT,
|
||||
}),
|
||||
);
|
||||
const tamFiltreli = kategoriFiltre(tamHam);
|
||||
if (tamFiltreli.length >= HEDEF) {
|
||||
return { havuz: tamFiltreli, gevsetildi: [] };
|
||||
}
|
||||
|
||||
// 2. Kategori gevşet: aynı illerdeki kategori-dışı programlarla doldur
|
||||
if (kategoriler.length > 0 && tamHam.length >= HEDEF) {
|
||||
return { havuz: tamHam, gevsetildi: ["kategori"] };
|
||||
}
|
||||
|
||||
// 3. İl gevşet: il filtresini kaldırıp kategoriye geri dön
|
||||
const gevsetildi: ("kategori" | "il")[] = [];
|
||||
if (iller.length > 0) gevsetildi.push("il");
|
||||
const ilsizHam = dilimEkle(
|
||||
searchByRank(params.sira, params.tur, {
|
||||
uniturGrubu,
|
||||
limitPerBucket: LIMIT,
|
||||
}),
|
||||
);
|
||||
const ilsizFiltreli = kategoriFiltre(ilsizHam);
|
||||
if (ilsizFiltreli.length >= HEDEF) {
|
||||
return { havuz: ilsizFiltreli, gevsetildi };
|
||||
}
|
||||
|
||||
// 4. Hem il hem kategori gevşet: elde ne varsa
|
||||
if (kategoriler.length > 0) gevsetildi.push("kategori");
|
||||
return { havuz: ilsizHam, gevsetildi };
|
||||
}
|
||||
|
||||
/** Prompt'a enjekte edilecek kompakt satır (token tasarrufu). */
|
||||
export function havuzuKompaktJson(havuz: AdayProgram[]): string {
|
||||
return JSON.stringify(
|
||||
havuz.map((p) => ({
|
||||
id: p.id,
|
||||
isim: p.isim,
|
||||
uni: p.universite,
|
||||
unitur: p.unitur,
|
||||
il: p.il,
|
||||
dilim: p.dilim,
|
||||
sira: {
|
||||
y2025: p.sira2025,
|
||||
y2024: p.sira2024,
|
||||
y2023: p.sira2023,
|
||||
y2022: p.sira2022,
|
||||
},
|
||||
kontenjan2025: p.kontenjan2025,
|
||||
yerlesen2025: p.yerlesen2025,
|
||||
})),
|
||||
);
|
||||
}
|
||||
|
||||
export function turLabel(tur: PuanTuruKey): string {
|
||||
return PUAN_TURLERI[tur];
|
||||
}
|
||||
Reference in New Issue
Block a user