@palbase/backend 38.0.16 → 39.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin/palbase-backend.cjs +46 -1
- package/dist/bin/palbase-backend.cjs.map +1 -1
- package/dist/bin/palbase-backend.js +5 -5
- package/dist/{chunk-LFUNRWUE.js → chunk-4J6I4KVQ.js} +67 -3
- package/dist/{chunk-LFUNRWUE.js.map → chunk-4J6I4KVQ.js.map} +1 -1
- package/dist/{chunk-7WAGQ3VR.js → chunk-AR2I4M7I.js} +497 -17
- package/dist/chunk-AR2I4M7I.js.map +1 -0
- package/dist/{chunk-YANGWAIM.js → chunk-H7EKL6HC.js} +2 -2
- package/dist/{chunk-EHKEMHB4.js → chunk-JJSR4BUX.js} +49 -5
- package/dist/chunk-JJSR4BUX.js.map +1 -0
- package/dist/{chunk-CS6NQ6PO.js → chunk-JPTFYHP3.js} +2 -2
- package/dist/{chunk-CS6NQ6PO.js.map → chunk-JPTFYHP3.js.map} +1 -1
- package/dist/{chunk-X7UR3VXA.js → chunk-XZWOMPD3.js} +3 -2
- package/dist/chunk-XZWOMPD3.js.map +1 -0
- package/dist/{chunk-PDD55QWN.js → chunk-ZNQDL466.js} +2 -2
- package/dist/db/index.cjs +378 -14
- package/dist/db/index.cjs.map +1 -1
- package/dist/db/index.d.cts +1 -1
- package/dist/db/index.d.ts +1 -1
- package/dist/db/index.js +3 -3
- package/dist/engine/index.cjs +46 -1
- package/dist/engine/index.cjs.map +1 -1
- package/dist/engine/index.d.cts +3 -3
- package/dist/engine/index.d.ts +3 -3
- package/dist/engine/index.js +5 -5
- package/dist/{index-CI7S0Wqv.d.cts → index-B0mjUnxy.d.cts} +25 -2
- package/dist/{index-CUy50OLU.d.ts → index-eN4KzGa5.d.ts} +555 -29
- package/dist/{index-DRx880KY.d.cts → index-pK2At5Yc.d.cts} +555 -29
- package/dist/{index-Ogi30dbt.d.ts → index-yDno9Ju9.d.ts} +25 -2
- package/dist/index.cjs +629 -17
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +216 -8
- package/dist/index.d.ts +216 -8
- package/dist/index.js +75 -6
- package/dist/index.js.map +1 -1
- package/dist/openapi/index.cjs.map +1 -1
- package/dist/openapi/index.d.cts +2 -2
- package/dist/openapi/index.d.ts +2 -2
- package/dist/openapi/index.js +2 -2
- package/dist/{registry-C7UCkQf0.d.cts → registry-9dNeVN5d.d.cts} +1 -1
- package/dist/{registry-DJcvbomD.d.ts → registry-B8ddZiMY.d.ts} +1 -1
- package/dist/test/index.cjs +19 -0
- package/dist/test/index.cjs.map +1 -1
- package/dist/test/index.d.cts +1 -1
- package/dist/test/index.d.ts +1 -1
- package/dist/test/index.js +20 -2
- package/dist/test/index.js.map +1 -1
- package/docs/README.md +1 -1
- package/docs/database.md +129 -0
- package/docs/llms-full.txt +512 -33
- package/docs/schema.md +382 -32
- package/package.json +1 -1
- package/template/package.json +1 -1
- package/dist/chunk-7WAGQ3VR.js.map +0 -1
- package/dist/chunk-EHKEMHB4.js.map +0 -1
- package/dist/chunk-X7UR3VXA.js.map +0 -1
- /package/dist/{chunk-YANGWAIM.js.map → chunk-H7EKL6HC.js.map} +0 -0
- /package/dist/{chunk-PDD55QWN.js.map → chunk-ZNQDL466.js.map} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/db/foreign-key.ts","../src/db/policy.ts","../src/db/guard.ts","../src/db/backfill.ts","../src/db/schema.ts","../src/db/extensions.ts","../src/db/raw.ts","../src/db/embedding.ts","../src/db/typed-db.ts"],"sourcesContent":["import type { PolicyExpr, PolicyExprRef } from \"./policy.js\";\nimport type { ColumnMap, TableHandle } from \"./schema.js\";\n\n// `schema.ts` bu modülü import ediyor, yani buradan ORAYA bir DEĞER import'u\n// döngü kurardı ve ESM'de biri diğerini `undefined` görürdü. `TABLE_META` zaten\n// `Symbol.for` ile kayıtlı bir global sembol — aynı anahtarı burada da sormak\n// tam olarak aynı sembolü verir ve döngüyü baştan siler. Tip import'u (`type`)\n// derlemede silindiği için döngü yaratmaz.\nconst TABLE_META: typeof import(\"./schema.js\").TABLE_META = Symbol.for(\n \"palbase.table.meta\",\n) as typeof import(\"./schema.js\").TABLE_META;\n\n/**\n * REF_TARGET, bir referansın HEDEF TABLO NESNESİ — serileştirilmez.\n *\n * Hedefin ADI builder anında biliniyor ama ŞEMASI bilinmiyor: şemayı\n * `defineSchema` damgalıyor ve o, `defineTable` callback'lerinden SONRA koşuyor.\n * Bu yüzden nesnenin kendisi taşınıyor ve niteleme `resolveReferences`'ta,\n * kolon başına yolun kullandığı AYNI `declaringSchemaOf` haritasıyla yapılıyor.\n *\n * Sembol anahtar: `JSON.stringify` sembol anahtarlarını atlar, yani wire'a\n * çıkmaz (NFR-006).\n */\nexport const REF_TARGET: unique symbol = Symbol.for(\"palbase.ref.target\");\n\n/** `ON UPDATE` / `ON DELETE` eylemleri — Postgres'in kabul ettiği kapalı küme. */\nexport type FkAction = \"cascade\" | \"restrict\" | \"set null\" | \"set default\" | \"no action\";\n\n/** `MATCH` türü. `partial` Postgres'te HENÜZ uygulanmadı, o yüzden yok. */\nexport type FkMatch = \"simple\" | \"full\";\n\n/** Bir tablo düzeyi FOREIGN KEY bildirimi — C-1/C-2 (FR-001). */\nexport interface ForeignKeyDef {\n name: string;\n columns: string[];\n refTable: string;\n refColumns: string[];\n onUpdate?: FkAction;\n onDelete?: FkAction;\n match?: FkMatch;\n}\n\n/**\n * `foreignKey(\"<ad>\")` — tablo düzeyinde, ÇOK SÜTUNLU FOREIGN KEY (C-1, FR-001).\n *\n * ```ts\n * foreignKeys: (c) => [\n * foreignKey(\"settlement_entry_household\")\n * .on(c.col(\"household_id\"), c.col(\"entry_id\"))\n * .references(entries, \"household_id\", \"id\")\n * .onDelete(\"cascade\"),\n * ]\n * ```\n *\n * NEDEN KOLON ÜZERİNDEKİ `.references()` YETMİYOR. O tek sütunlu ve tek\n * hedeflidir. Çok kiracılı bütünlüğün istediği şey\n * `FOREIGN KEY (household_id, entry_id) REFERENCES entries (household_id, id)`:\n * çocuğun ebeveyni yalnız var olmakla kalmaz, AYNI KİRACIYA ait olmak\n * zorundadır. Kolon başına model bunu ifade edemez.\n *\n * İki yol BİRBİRİNİ DÜŞÜRMEZ: bu bildirim kendi adıyla izlenir, kolon\n * üzerindekiler `<tablo>_<kolon>_fkey` ile. Aynı tabloda ikisi birden olabilir.\n */\nexport class ForeignKeyBuilder {\n readonly _def: ForeignKeyDef;\n\n constructor(name: string) {\n if (name.trim() === \"\") {\n throw new Error(\n \"foreignKey(ad): foreign key'in adı boş olamaz — Palbase kısıtları ADA göre uzlaştırır.\",\n );\n }\n this._def = { name, columns: [], refTable: \"\", refColumns: [] };\n }\n\n /** Yerel sütunlar. SIRA KORUNUR — hedef sütunlarla birebir eşleşir. */\n on(...cols: PolicyExprRef[]): this {\n this._def.columns = cols.map((c) => {\n const e = c.expr;\n if (e.kind !== \"col\") {\n throw new Error(\n `foreignKey(${this._def.name}).on(): yalnız kolon referansı alır — ifade bir FK'nın parçası olamaz.`,\n );\n }\n return e.name;\n });\n return this;\n }\n\n /**\n * Hedef tablo ve sütunları. Sütun sayısı `.on()`'unkiyle eşit OLMALI ve bu\n * burada, bildirim yazılırken kontrol edilir — bozuk bir FK wire'a hiç çıkmaz.\n */\n references<C extends ColumnMap, N extends string>(\n table: TableHandle<C, N>,\n ...cols: (Extract<keyof C, string>)[]\n ): this {\n if (cols.length === 0) {\n throw new Error(\n `foreignKey(${this._def.name}).references(): en az bir hedef sütun gerekir.`,\n );\n }\n this._def.refTable = table[TABLE_META].name;\n this._def.refColumns = [...cols];\n // Hedefin NESNESİ de taşınıyor: şeması `defineSchema` damgalayana kadar\n // bilinmiyor ve `resolveReferences` orada nitelikli adı yazıyor.\n Object.defineProperty(this._def, REF_TARGET, {\n value: table[TABLE_META], enumerable: false, configurable: true,\n });\n return this;\n }\n\n onUpdate(action: FkAction): this {\n this._def.onUpdate = action;\n return this;\n }\n\n onDelete(action: FkAction): this {\n this._def.onDelete = action;\n return this;\n }\n\n /**\n * `MATCH FULL`: referans veren sütunların HEPSİ NULL olmadıkça kısıt\n * değerlendirilir. Varsayılan `MATCH SIMPLE`'da tek bir NULL kısıtı atlatır —\n * `freeze` bunu bilerek kullanır, sıradan bir FK'da genelde istenmez.\n */\n match(m: FkMatch): this {\n this._def.match = m;\n return this;\n }\n}\n\nexport function foreignKey(name: string): ForeignKeyBuilder {\n return new ForeignKeyBuilder(name);\n}\n\n/**\n * Bildirimi normalize eder ve TUTARLILIĞINI burada doğrular.\n *\n * Uzunluk uyuşmazlığı push'ta da reddediliyor (FR-002) ama orada mesaj canlıya\n * gidiyor; burada yazarın editöründe patlıyor ve bozuk bildirim wire'a hiç\n * çıkmıyor. İki kapı da gerekli: biri yazar için, biri deploy için.\n */\nexport function toForeignKeyDef(b: ForeignKeyBuilder | ForeignKeyDef): ForeignKeyDef {\n const def = b instanceof ForeignKeyBuilder ? b._def : b;\n if (def.columns.length === 0) {\n throw new Error(`foreignKey(${def.name}): en az bir yerel sütun gerekir — .on(...) çağırın.`);\n }\n if (def.refColumns.length === 0 || def.refTable === \"\") {\n throw new Error(`foreignKey(${def.name}): hedef tablo ve sütunlar gerekir — .references(...) çağırın.`);\n }\n if (def.columns.length !== def.refColumns.length) {\n throw new Error(\n `foreignKey(${def.name}): ${def.columns.length} yerel sütun (${def.columns.join(\", \")}) ` +\n `ama ${def.refColumns.length} hedef sütun (${def.refColumns.join(\", \")}) — iki liste eşit uzunlukta olmalı.`,\n );\n }\n return def;\n}\n\n/**\n * Bir KOŞULLU (\"donan\") FOREIGN KEY bildirimi — C-5 (FR-012).\n *\n * `columns` çocuğun donan sütunları, `refColumns` ebeveynin onlara karşılık\n * gelen anahtar sütunları; ikisi SIRAYLA eşleşir. `when` doğruyken FK\n * değerlendirilir, yanlışken hiç değerlendirilmez.\n */\nexport interface FreezeDef {\n name: string;\n when: PolicyExpr;\n columns: string[];\n refTable: string;\n refColumns: string[];\n}\n\n/** Builder'ın YAZILMAKTA olan hâli: `when` henüz atanmamış olabilir. */\ntype FreezeDraft = Omit<FreezeDef, \"when\"> & { when?: PolicyExpr };\n\n/**\n * `freeze(\"<ad>\")` — KOŞULLU FK: bir koşul sağlandığı sürece bir demeti dondurur\n * (C-5, FR-012).\n *\n * ```ts\n * freeze: (c) => [\n * freeze(\"pay_settled_inv\")\n * .when(c.col(\"status\").eq(\"settled\"))\n * .columns(\"inv_id\", \"amount\", \"currency\")\n * .references(invoices, \"id\", \"amount\", \"currency\"),\n * ]\n * ```\n *\n * NEDEN TRIGGER DEĞİL. Üretilen şey bir CONSTRAINT: ebeveyndeki demet üzerinde\n * bir UNIQUE, çocukta `when` sağlanmıyorken NULL veren `STORED` generated\n * sütunlar, ve bunlardan `ON UPDATE RESTRICT ON DELETE RESTRICT` bir FK.\n * `MATCH SIMPLE`'ın NULL kaçışı — \"referans veren sütunlardan biri NULL ise satır\n * kısıtı sağlamak zorunda değildir\" — \"koşullu FK\"yı `WHERE` olmadan veriyor.\n *\n * Trigger'a göre üç bedava üstünlük (canlı pg'de ölçüldü, spec Research\n * Appendix): TERS YÖN de kapanır (uyuşmayan bir çocuk `settled` yapılamaz —\n * trigger yalnız ebeveyni korurdu); koşul kalkınca donma KENDİLİĞİNDEN çözülür;\n * `pg_dump`/restore'da FK gibi davranır.\n *\n * Donan sütunlar `NOT NULL` OLMALI: nullable bir sütun `MATCH SIMPLE`'ın aynı\n * kaçışını koşuldan BAĞIMSIZ olarak açar ve donma sessizce hiç kurulmaz. Push o\n * bildirimi reddeder (FR-014).\n */\nexport class FreezeBuilder {\n readonly _def: FreezeDraft;\n\n constructor(name: string) {\n if (name.trim() === \"\") {\n throw new Error(\n \"freeze(ad): freeze kısıtının adı boş olamaz — Palbase kısıtları ADA göre uzlaştırır.\",\n );\n }\n this._def = { name, columns: [], refTable: \"\", refColumns: [] };\n }\n\n /**\n * DONMA KOŞULU — çocuk satırının kendi kolonları üzerinde bir yüklem.\n *\n * Generated sütunlara `CASE WHEN <koşul> THEN <sütun> END` olarak iner; yani\n * koşul yanlışken sütunlar NULL olur ve FK o satır için hiç değerlendirilmez.\n */\n when(pred: PolicyExprRef): this {\n this._def.when = pred.expr;\n return this;\n }\n\n /** Çocuğun DONAN sütunları. SIRA KORUNUR — hedef sütunlarla birebir eşleşir. */\n columns(...cols: string[]): this {\n if (cols.length === 0) {\n throw new Error(\n `freeze(${this._def.name}).columns(): en az bir donan sütun gerekir — hiçbirini vermeyen bir freeze hiçbir şeyi dondurmaz.`,\n );\n }\n this._def.columns = [...cols];\n return this;\n }\n\n /**\n * Ebeveyn tablo ve donan demetin ORADAKİ karşılığı. Zincirin SON halkası:\n * bildirim burada tamamlanır ve tutarlılığı burada doğrulanır, yani\n * `.references()`'ı unutmuş bir freeze `FreezeDef` üretmediği için tabloya\n * hiç giremez.\n */\n references<C extends ColumnMap, N extends string>(\n table: TableHandle<C, N>,\n ...cols: (Extract<keyof C, string>)[]\n ): FreezeDef {\n if (cols.length === 0) {\n throw new Error(\n `freeze(${this._def.name}).references(): en az bir hedef sütun gerekir.`,\n );\n }\n this._def.refTable = table[TABLE_META].name;\n this._def.refColumns = [...cols];\n Object.defineProperty(this._def, REF_TARGET, {\n value: table[TABLE_META], enumerable: false, configurable: true,\n });\n return toFreezeDef(this);\n }\n}\n\nexport function freeze(name: string): FreezeBuilder {\n return new FreezeBuilder(name);\n}\n\n/**\n * Bildirimi normalize eder ve TUTARLILIĞINI burada doğrular — `toForeignKeyDef`\n * ile aynı gerekçe: bozuk bir bildirim yazarın editöründe patlar, wire'a hiç\n * çıkmaz.\n */\nexport function toFreezeDef(b: FreezeBuilder | FreezeDef): FreezeDef {\n const def: FreezeDraft = b instanceof FreezeBuilder ? b._def : b;\n if (def.columns.length === 0) {\n throw new Error(`freeze(${def.name}): en az bir donan sütun gerekir — .columns(...) çağırın.`);\n }\n if (def.refColumns.length === 0 || def.refTable === \"\") {\n throw new Error(`freeze(${def.name}): hedef tablo ve sütunlar gerekir — .references(...) çağırın.`);\n }\n if (def.columns.length !== def.refColumns.length) {\n throw new Error(\n `freeze(${def.name}): ${def.columns.length} donan sütun (${def.columns.join(\", \")}) ` +\n `ama ${def.refColumns.length} hedef sütun (${def.refColumns.join(\", \")}) — iki liste eşit uzunlukta olmalı.`,\n );\n }\n if (def.when === undefined) {\n throw new Error(\n `freeze(${def.name}): donma koşulu gerekir — .when(...) çağırın. Koşulsuz bir freeze sıradan bir FK'dır; onun için foreignKey(...) var.`,\n );\n }\n const out: FreezeDef = {\n name: def.name,\n when: def.when,\n columns: [...def.columns],\n refTable: def.refTable,\n refColumns: [...def.refColumns],\n };\n // Kopya hedefin nesnesini TAŞIMALI, yoksa niteleme yapılamaz ve çapraz\n // şemalı bir freeze sessizce `public`'e yazılır.\n const target = (def as { [REF_TARGET]?: object })[REF_TARGET];\n if (target !== undefined) {\n Object.defineProperty(out, REF_TARGET, { value: target, enumerable: false, configurable: true });\n }\n return out;\n}\n","import { z } from \"zod\";\nimport { TABLE_META } from \"./schema.js\";\nimport { REF_TARGET } from \"./foreign-key.js\";\nimport type { ColumnMap, TableDef, TableHandle } from \"./schema.js\";\n\n/**\n * policy.ts — the RLS policy authoring DSL.\n *\n * `policy(name)` returns a fluent builder that mirrors the `ColumnBuilder`\n * style in columns.ts: each chainable method mutates the underlying\n * definition and returns the builder so calls compose. The terminal value is\n * a plain {@link PolicyDef} — the exact JSON shape the runtime's\n * `schema_extract.js` reads off the bundled module and the Go side parses into\n * `PolicyJSON` (CONTRACT-POLICY).\n *\n * @example\n * import { policy } from \"@palbase/backend\";\n *\n * policy(\"owner_select\")\n * .for(\"select\")\n * .to(\"authenticated\")\n * .using(\"owner = (select auth.uid())\");\n */\n\n\n// ---------------------------------------------------------------------------\n// C-4 — politika ifadesinin YAPISI (FR-022). SÖZLEŞME BURADA DONAR.\n//\n// T016 (`existsIn`), T027 (Go emitter) ve T028 (korelasyonlu EXISTS) bu tipi\n// tüketir; şekli değiştirmek üç tarafı birden kırar.\n//\n// NEDEN string değil de yapı: bir string ifadeyi ne TypeScript ne Go okuyabilir.\n// Kolon adı yanlışsa hata `CREATE POLICY` anında Postgres'ten gelir — deploy\n// sırasında, yazma anında değil. Dahası InitPlan sarmalaması (`auth.uid()` →\n// `(select auth.uid())`, satır başına bir kez yerine statement başına bir kez)\n// ve `TO <rol>` daraltması ancak yapı üstünde GÜVENLE verilebilir; string\n// üzerinde regex'le yapmak, yorum içindeki bir `auth.uid()`'yi de sarmalar.\n// ---------------------------------------------------------------------------\n\n/** Politika ifadesinin düğümleri. DÜZ VERİ: tele bu şekilde gider. */\nexport type PolicyExpr =\n | {\n kind: \"col\";\n name: string;\n /**\n * Hangi tablonun kolonu (FR-023). Yoksa POLİTİKANIN KENDİ tablosu —\n * Postgres politika ifadesinde onu niteliksiz çözer. Doluysa bir\n * `existsIn` alt-sorgusunun takma adı.\n *\n * Bu ayrım korelasyonun tamamı: ayırt edilmezse `team_id = team_id`\n * üretilir, her satır için doğrudur, ve politika HİÇBİR ŞEYİ süzmez —\n * yani tüm belgeler herkese görünür.\n */\n alias?: string;\n }\n | { kind: \"authUid\" }\n | { kind: \"lit\"; value: string | number | boolean | null }\n | { kind: \"binop\"; op: PolicyBinOp; left: PolicyExpr; right: PolicyExpr }\n | { kind: \"and\"; parts: PolicyExpr[] }\n | { kind: \"or\"; parts: PolicyExpr[] }\n | { kind: \"not\"; expr: PolicyExpr }\n | { kind: \"isNull\"; expr: PolicyExpr; negated: boolean }\n | {\n /**\n * Korelasyonlu `EXISTS (SELECT 1 FROM <table> <alias> WHERE <predicate>)`.\n *\n * FR-024 BAĞLAYICI: alt-sorgu DOĞRUDAN üretilir, bir `SECURITY DEFINER`\n * fonksiyona SARILMAZ. Ölçüldü (spec Research Appendix, pg16): doğrudan\n * alt-sorguda hedef tablonun KENDİ RLS'i uygulanıyor — yani sızıntı\n * kanalı yok. Sarmalama ise onu bypass ederdi.\n */\n kind: \"exists\";\n table: string;\n alias: string;\n /**\n * POLİTİKANIN KENDİ tablosunun adı — korelasyonun çalışması için ŞART.\n *\n * ÖLÇÜLDÜ (canlı pg16): alt-sorgu içinde niteliksiz bir kolon adı\n * Postgres tarafından İÇ tabloya çözülüyor. Yani dış kolon niteliksiz\n * bırakılınca `pb_e1.team_id = pb_e1.team_id` üretiliyor — her satır\n * için doğru, ve politika HİÇBİR ŞEYİ süzmüyor: iki farklı kullanıcı\n * da tüm belgeleri gördü. Dış tablo adı burada taşınıyor ki emitter\n * `\"documents\".\"team_id\"` yazabilsin.\n */\n outer: string;\n predicate: PolicyExpr;\n };\n\n/** Karşılaştırma operatörleri. `in` sağ tarafta liste bekler. */\nexport type PolicyBinOp = \"eq\" | \"neq\" | \"gt\" | \"gte\" | \"lt\" | \"lte\" | \"in\";\n\n/**\n * Bir ifadenin ETRAFINDAKİ akıcı sarmalayıcı.\n *\n * Düğüm (`expr`) düz veri kalıyor, metotlar sarmalayıcıda yaşıyor: `_def.using`\n * serileştiğinde metotlu bir nesne değil, tam olarak tele gidecek şekil olsun\n * diye. `.using()` sarmalayıcıyı açar.\n */\nexport class PolicyExprRef {\n constructor(readonly expr: PolicyExpr) {}\n\n private bin(op: PolicyBinOp, other: PolicyOperand): PolicyExprRef {\n return new PolicyExprRef({ kind: \"binop\", op, left: this.expr, right: toExpr(other) });\n }\n\n eq(other: PolicyOperand): PolicyExprRef { return this.bin(\"eq\", other); }\n neq(other: PolicyOperand): PolicyExprRef { return this.bin(\"neq\", other); }\n gt(other: PolicyOperand): PolicyExprRef { return this.bin(\"gt\", other); }\n gte(other: PolicyOperand): PolicyExprRef { return this.bin(\"gte\", other); }\n lt(other: PolicyOperand): PolicyExprRef { return this.bin(\"lt\", other); }\n lte(other: PolicyOperand): PolicyExprRef { return this.bin(\"lte\", other); }\n\n /**\n * `IS NULL` / `IS NOT NULL` — `= NULL` SQL'de her zaman UNKNOWN'dır, o yüzden\n * niyet ayrı bir düğümle yazılır. Partial index'in en sık koşulu\n * (`WHERE deleted_at IS NULL`) tam olarak bu.\n */\n isNull(negated = false): PolicyExprRef {\n return new PolicyExprRef({ kind: \"isNull\", expr: this.expr, negated });\n }\n\n and(...others: PolicyExprRef[]): PolicyExprRef {\n return new PolicyExprRef({ kind: \"and\", parts: [this.expr, ...others.map((o) => o.expr)] });\n }\n or(...others: PolicyExprRef[]): PolicyExprRef {\n return new PolicyExprRef({ kind: \"or\", parts: [this.expr, ...others.map((o) => o.expr)] });\n }\n not(): PolicyExprRef {\n return new PolicyExprRef({ kind: \"not\", expr: this.expr });\n }\n}\n\n/**\n * Bir tablonun `existsIn` için ANNOTATION hâli — iki bildirim birbirini\n * başlatırken çıkarım döngüsünü kıran şey.\n *\n * ÖLÇÜLDÜ: `memberships.household_id` `households.id`'ye referans verirken\n * `households`'ın politikası `existsIn(memberships, …)` yazarsa TypeScript\n * ikisini de TS7022 ile `any`'ye düşürüyor. Kesinti sadece hata mesajı değil:\n * `m.col(…)` de `any` olduğu için politika gövdesindeki YANLIŞ YAZILMIŞ bir\n * kolon adı sessizce derleniyor — RLS yolunda fail-open. Aynı ölçümde\n * `existsIn`'in jeneriğini kaldırmak (tamamen jeneriksiz imza dahil) döngüyü\n * KIRMADI: döngü çıkarımdan değil, iki `const`'un birbirini başlatmasından\n * geliyor ve TypeScript'te tek çaresi bir tip annotation'ı.\n *\n * Bu, `references((): AnyColumn => y.id)`'nin tablo düzeyindeki karşılığı — ama\n * `AnyColumn`'dan farklı olarak KOLON ADLARINI SİLMEZ:\n *\n * ```ts\n * const memberships: TableRef<\"id\" | \"household_id\" | \"user_id\", \"memberships\"> =\n * defineTable(\"memberships\", { columns: { … } });\n * ```\n *\n * Adlar `Cols`'ta durduğu için `m.col(\"user\")` hâlâ DERLENMEZ, ve `N` verildiği\n * için tablo `defineSchema` içinde anahtarını kaybetmez. Kolon adlarını silen\n * gevşek bir `AnyTable` KASITLI OLARAK YOK: onu yazan kişi döngüyü susturur ve\n * politikasının kolon denetimini kapattığını fark etmez.\n */\nexport type TableRef<Cols extends string, N extends string = string> =\n TableHandle<Record<Cols, ColumnMap[string]>, N>;\n\n/** `.eq()` gibi metotların sağ tarafı: başka bir ifade ya da düz bir değer. */\nexport type PolicyOperand = PolicyExprRef | string | number | boolean | null;\n\n/**\n * Düz değer LİTERAL olur, kolon referansı OLMAZ.\n *\n * `.eq(\"owner\")` bir string karşılaştırmasıdır — `owner` kolonuna referans\n * değil. İkisi karışırsa politika sessizce yanlış satırları gösterir ve RLS'te\n * bunun adı yetki atlamasıdır. Kolon istiyorsan `p.col(\"owner\")` yazacaksın.\n */\nfunction toExpr(v: PolicyOperand): PolicyExpr {\n return v instanceof PolicyExprRef ? v.expr : { kind: \"lit\", value: v };\n}\n\n/**\n * Politika ifadesi bağlamı — `defineTable`'ın `policies` callback'ine verilir.\n *\n * Kolon adları TABLONUN KENDİ kolonlarıyla sınırlıdır (FR-022). Bu, `policies`\n * bir dizi değil de callback olduğu için mümkün: TypeScript `columns`'tan\n * `C`'yi çıkarıp callback'i onunla bağlamlandırıyor. `policy(\"x\")` tek başına\n * çağrıldığında hangi tabloda olduğunu bilemezdi.\n */\nexport interface PolicyExprCtx<Cols extends string = string> {\n /** Bu tablonun bir kolonu. Bilinmeyen ad DERLENMEZ. */\n col(name: Cols): PolicyExprRef;\n /**\n * \"Bu satırın sahibi olduğum bir takıma ait mi?\" — üyelik tabanlı kiracılık\n * (FR-023), korelasyonlu bir `EXISTS` alt-sorgusu olarak.\n *\n * ```ts\n * policies: (p) => [\n * policy(\"team_read\").for(\"select\").using(\n * p.existsIn(teamMembers, (m) =>\n * m.col(\"team_id\").eq(p.col(\"team_id\"))\n * .and(m.col(\"user_id\").eq(p.auth.uid()))),\n * ),\n * ]\n * ```\n *\n * `m` ÜYELİK tablosunun kolonlarını, `p` bu tablonunkileri verir; ikisi de\n * tipli ve SQL'de farklı nitelenirler. Karışsalardı `team_id = team_id`\n * üretilir ve politika hiçbir şeyi süzmezdi.\n *\n * ÇIKARIM DÖNGÜSÜ: `table` iki bildirim birbirini başlatıyorsa (üyelik tablosu\n * bu tabloya `references` veriyor, bu tablo da ona `existsIn` atıyor) o\n * bildirime {@link TableRef} annotation'ı gerekir — yoksa TypeScript ikisini\n * de TS7022 ile `any`'ye düşürür ve `m.col(…)` sessizce her adı kabul eder.\n *\n * ÖZYİNELEME TUZAĞI: üyelik tablosunun KENDİ politikası `existsIn`\n * KULLANMAZ — `user_id = auth.uid()` yazar. İki tablo birbirini\n * sorgularsa Postgres sorgu anında\n * `infinite recursion detected in policy for relation …` der. Asimetri\n * kasıtlıdır: üyelik tablosu basit olanı alır, diğer her tablo ona\n * alt-sorgu ATAR.\n */\n existsIn<C extends ColumnMap, N extends string>(\n table: TableHandle<C, N>,\n predicate: (row: PolicyExprCtx<Extract<keyof C, string>>) => PolicyExprRef,\n ): PolicyExprRef;\n /** Çağıranın kimliği. SQL'e `(select auth.uid())` olarak iner (InitPlan). */\n auth: { uid(): PolicyExprRef };\n /** Düz bir değer — karşılaştırmanın sağ tarafında açıkça literal demek için. */\n lit(v: string | number | boolean | null): PolicyExprRef;\n and(...parts: PolicyExprRef[]): PolicyExprRef;\n or(...parts: PolicyExprRef[]): PolicyExprRef;\n not(part: PolicyExprRef): PolicyExprRef;\n}\n\n/**\n * İfade bağlamını kurar. `defineTable` bunu kendi kolon adlarıyla çağırır;\n * testler ve elle kullanım için de dışa açık.\n */\nexport function exprCtx<Cols extends string = string>(\n _columns?: readonly Cols[],\n depth = 0,\n /**\n * POLİTİKANIN KENDİ tablosu — her derinlikte AYNI kalır.\n *\n * Alt-sorgunun içinde takma adsız duran bir kolon, dış sorgudaki tabloya\n * bağlanmak zorundadır; Go tarafı onu bu adla nitelendiriyor. Değer iç içe\n * geçmede ORTA tablonun adına kayıyordu (`meta.name` aşağı veriliyordu) ve\n * sonuç canlıda `ERROR: missing FROM-clause entry for table \"…\"` oluyordu —\n * yani iç içe `existsIn` içinden politikanın kendi kolonuna erişmek imkânsızdı\n * (nihai inceleme I-1, ölçüldü). Kök tablo aşağı DEĞİŞMEDEN taşınır.\n */\n ownTable = \"\",\n): PolicyExprCtx<Cols> {\n // Takma ad DERİNLİKTEN türetiliyor, bir sayaçtan değil: aynı şema iki kez\n // yüklendiğinde (test, sonra deploy) sayaç farklı değer üretir ve golden\n // çıktı sebepsiz değişirdi. Derinlik ifadenin kendi şeklinden gelir.\n const alias = `pb_e${depth}`;\n return {\n col: (name) =>\n new PolicyExprRef(depth === 0 ? { kind: \"col\", name } : { kind: \"col\", name, alias }),\n auth: { uid: () => new PolicyExprRef({ kind: \"authUid\" }) },\n lit: (v) => new PolicyExprRef({ kind: \"lit\", value: v }),\n and: (...parts) => new PolicyExprRef({ kind: \"and\", parts: parts.map((p) => p.expr) }),\n or: (...parts) => new PolicyExprRef({ kind: \"or\", parts: parts.map((p) => p.expr) }),\n not: (part) => new PolicyExprRef({ kind: \"not\", expr: part.expr }),\n existsIn: (table, predicate) => {\n const meta = (table as { [TABLE_META]: { name: string; columns: ColumnMap } })[TABLE_META];\n const inner = exprCtx(Object.keys(meta.columns), depth + 1, ownTable);\n const node: PolicyExpr = {\n kind: \"exists\",\n table: meta.name,\n alias: `pb_e${depth + 1}`,\n outer: ownTable,\n predicate: predicate(inner as never).expr,\n };\n // Hedefin NESNESİ taşınıyor — bir POLİTİKA için çıplak ad yeterli\n // (`CREATE POLICY` anında çözülür), ama bir GUARD gövdesi ÇALIŞMA ANINDA\n // ayrıştırılıyor ve `SET search_path = pg_catalog, pg_temp` altında\n // niteliksiz ad hiç çözülmüyor (D-012). `resolveReferences` bunu\n // niteliyor; nitelenen şema YANLIŞ olursa hata kullanıcının yazması\n // sırasında gelir.\n Object.defineProperty(node, REF_TARGET, {\n value: meta, enumerable: false, configurable: true,\n });\n return new PolicyExprRef(node);\n },\n };\n}\n\n/** The SQL command a policy applies to. `\"all\"` covers SELECT/INSERT/UPDATE/DELETE. */\nexport type PolicyCommand = \"all\" | \"select\" | \"insert\" | \"update\" | \"delete\";\n\n/** Whether a policy is permissive (OR-combined, the default) or restrictive\n * (AND-combined). Mirrors Postgres `CREATE POLICY ... AS PERMISSIVE|RESTRICTIVE`. */\nexport type PolicyMode = \"permissive\" | \"restrictive\";\n\n/**\n * The compiled, serializable policy definition — the EXACT shape consumed by\n * `schema_extract.js` → Go `PolicyJSON` (CONTRACT-POLICY).\n *\n * - `roles`: the DB roles this policy applies to (`TO` clause). An empty array\n * means the policy applies to PUBLIC (all roles) — the Postgres default.\n * - `using`: the `USING (...)` row-visibility expression, or `null` when none.\n * - `withCheck`: the `WITH CHECK (...)` write-validation expression, or `null`.\n * - `permissive`: `true` for `AS PERMISSIVE` (default), `false` for restrictive.\n */\nexport interface PolicyDef {\n name: string;\n command: PolicyCommand;\n roles: string[];\n /** Yapı (FR-022) ya da ham string (FR-028 kaçış kapağı). */\n using: string | PolicyExpr | null;\n withCheck: string | PolicyExpr | null;\n permissive: boolean;\n}\n\n/**\n * Fluent RLS policy builder.\n *\n * Defaults (documented, applied at construction):\n * - `command`: `\"all\"` — applies to every SQL command unless `.for(...)` narrows it.\n * - `roles`: `[\"authenticated\"]` — the common case is \"rule applies to signed-in\n * users\". Call `.to(...)` to override; pass `.to()` with no roles (or never\n * call it after a reset) to target PUBLIC.\n * - `using` / `withCheck`: `null` — no row filter / write check until set.\n * - `permissive`: `true` — `AS PERMISSIVE` (policies OR together).\n *\n * Each method mutates `_def` in place and returns `this`, so the chain is a\n * single builder instance (no per-call allocation, like a tagged-template\n * compile target). The terminal `PolicyDef` is read directly off `_def` by\n * `schema_extract.js`.\n */\n/** Quote an identifier for the policy expression. Table and column names reach\n * here from the schema author; neither is allowed to become syntax. */\nfunction quote(name: string): string {\n return `\"${name.replace(/\"/g, '\"\"')}\"`;\n}\n\n/**\n * Bir politikanın adreslenebileceği Postgres rolleri.\n *\n * Serbest string DEĞİL, çünkü küme SABİT: bunları palbase provision ediyor,\n * kiracı yeni bir PG rolü yaratmıyor. Serbest bırakıldığında `authenitcated`\n * gibi bir harf hatası derlenip migration'a kadar gidiyordu — Drizzle'da da\n * aynı boşluk ölçüldü (`to` tipi `(string & {})`, yazım hatası DDL'e geçiyor).\n *\n * Çalışma anı zaten fail-closed (bilinmeyen rol kapıyı kapatıyor,\n * `session_rls_fail_closed_integration_test.go`); bu, aynı cevabı derleme\n * anına taşıyor.\n *\n * `backend_*` ikizleri elle YAZILMAZ — `NormalizeDeclaredPolicies` onları\n * kendisi ekliyor; yine de kabul ediliyor ki elle yazan kod kırılmasın.\n */\nexport type PolicyRole =\n | \"anon\"\n | \"authenticated\"\n | \"service_role\"\n | \"backend_anon\"\n | \"backend_authenticated\"\n | \"backend_service_role\";\n\nexport class PolicyBuilder {\n readonly _def: PolicyDef;\n\n constructor(name: string) {\n this._def = {\n name,\n command: \"all\",\n roles: [\"authenticated\"],\n using: null,\n withCheck: null,\n permissive: true,\n };\n }\n\n /** Restrict the policy to a single SQL command (default `\"all\"`). */\n for(command: PolicyCommand): this {\n this._def.command = command;\n return this;\n }\n\n /**\n * Set the DB roles the policy applies to (the `TO` clause), replacing any\n * previously-set roles. Call with no arguments to target PUBLIC (all roles).\n *\n * @example\n * policy(\"p\").to(\"authenticated\")\n * policy(\"p\").to(\"authenticated\", \"service_role\")\n * policy(\"p\").to() // PUBLIC\n */\n to(...roles: PolicyRole[]): this {\n this._def.roles = roles;\n return this;\n }\n\n /**\n * `USING (...)` satır görünürlüğü ifadesi.\n *\n * Tercih edilen biçim YAPI'dır (FR-022) — `policies` callback'inin verdiği\n * bağlamla kurulur ve kolon adları derlemede doğrulanır:\n *\n * ```ts\n * policies: (p) => [\n * policy(\"owner_read\").for(\"select\").using(p.col(\"owner\").eq(p.auth.uid())),\n * ]\n * ```\n *\n * Ham string KAÇIŞ KAPAĞI olarak kalır (FR-028): yapının ifade edemediği bir\n * şey gerektiğinde yol kapanmaz. Ama o yolda kolon adı doğrulaması yoktur ve\n * hata deploy anında Postgres'ten gelir.\n */\n using(expr: string | PolicyExprRef): this {\n this._def.using = expr instanceof PolicyExprRef ? expr.expr : expr;\n return this;\n }\n\n /**\n * \"Rows of THIS table whose owner the caller is a member of\" — the membership\n * pattern, written so it cannot recurse.\n *\n * THE TRAP IT EXISTS FOR. Written by hand, membership policies point at each\n * other: `channels` is visible to members, so its policy reads\n * `channel_members`; `channel_members` is visible to members, so its policy\n * reads `channels`. Postgres refuses the pair at query time with `infinite\n * recursion detected in policy for relation ...`, and the error names the\n * relation but not the cycle. The way out is asymmetry — the MEMBERSHIP table\n * is protected by `user_id = auth.uid()` and nothing else, and every other\n * table subqueries INTO it. That shape was in the platform's own schema and\n * written down nowhere; a customer recovered it by reading that schema.\n *\n * `(select auth.uid())` rather than a bare call: the scalar subquery is\n * evaluated ONCE per statement instead of per row.\n *\n * @example\n * // channels: visible to members. The membership table gets the simple one.\n * policy(\"member_read\").for(\"select\").to(\"authenticated\")\n * .memberOf(\"channel_members\", \"channel_id\")\n * // → id IN (SELECT \"channel_id\" FROM \"channel_members\"\n * // WHERE \"user_id\" = (select auth.uid()))\n */\n memberOf(\n membershipTable: string,\n foreignKey: string,\n options: { column?: string; userColumn?: string } = {},\n ): this {\n if (this._def.using !== null) {\n // Silently AND-ing the two would hide whichever the author meant; silently\n // replacing would hide the one they wrote. Neither is a thing to guess.\n throw new Error(\n `policy(${this._def.name}).memberOf(): this policy already has a using() expression. ` +\n \"Write one or the other — memberOf IS the using expression.\",\n );\n }\n const column = options.column ?? \"id\";\n const userColumn = options.userColumn ?? \"user_id\";\n this._def.using =\n `${quote(column)} IN (SELECT ${quote(foreignKey)} FROM ${quote(membershipTable)} ` +\n `WHERE ${quote(userColumn)} = (select auth.uid()))`;\n return this;\n }\n\n /** `WITH CHECK (...)` yazma doğrulaması — `using` ile aynı iki biçim. */\n withCheck(expr: string | PolicyExprRef): this {\n this._def.withCheck = expr instanceof PolicyExprRef ? expr.expr : expr;\n return this;\n }\n\n /** Set the policy mode: `\"permissive\"` (default, OR-combined) or\n * `\"restrictive\"` (AND-combined). */\n as(mode: PolicyMode): this {\n this._def.permissive = mode === \"permissive\";\n return this;\n }\n}\n\n/**\n * Start authoring an RLS policy. Returns a {@link PolicyBuilder}; the resulting\n * `PolicyBuilder` is accepted directly in a table's `policies: [...]` array\n * (its `_def` is read at schema-extract time).\n *\n * @param name The policy name. Palbase reconciliation keys policies by\n * `(table, name)`, so names must be unique per table.\n */\nexport function policy(name: string): PolicyBuilder {\n return new PolicyBuilder(name);\n}\n\n// ---------------------------------------------------------------------------\n// Tipli CHECK (FR-009, FR-010).\n// ---------------------------------------------------------------------------\n\n/**\n * Adlandırılmış bir CHECK kısıtı — telin bugünkü şekli, HARFİYEN.\n *\n * `expr` STRING kalıyor: `TableJSON.checks` bugün de `{ name, expr }[]` ve Go\n * tarafındaki `CheckJSON.Expr` bir string. Tipli `check()` ifadeyi bildirim\n * anında SQL'e derleyip aynı yere koyuyor, yani string dalıyla tipli dal telde\n * AYNI şeye iniyor: `NormalizeDeclaredChecks` ikisini de canlı Postgres'e\n * sorarak kanonikleştiriyor (böylece değişmemiş bir CHECK churn olarak\n * yeniden diff'lenmiyor) ve `schema-json.ts` yeni bir alan taşımıyor.\n */\nexport interface CheckDef {\n name: string;\n /** Derlenmiş SQL. Tipli dalda `check()` üretir, string dalda yazar verir. */\n expr: string;\n}\n\n/**\n * CHECK bağlamı POLİTİKA bağlamından DAR — Postgres'in kendi cümlesiyle:\n *\n * \"CHECK expressions cannot contain subqueries nor refer to variables other\n * than columns of the current row\" — sql-createtable\n *\n * `existsIn` doğrudan bir alt sorgu; `auth.uid()` da SQL'e `(SELECT auth.uid())`\n * olarak iniyor (InitPlan sarmalaması bir tercih değil — çıplak çağrı satır\n * başına yeniden değerlendiriliyor), yani o da alt sorgu. İkisi de BİLDİRİM\n * anında reddediliyor: reddi apply'a bırakmak, migration'ın ortasında\n * Postgres'in \"cannot use subquery in check constraint\" hatasıyla ölmesi\n * demekti — hangi tablo, hangi kısıt demeden.\n *\n * Go tarafındaki ikizi `validateCheckNode` (`policy_expr.go`); orada aynı küme\n * `freeze`'in `when` koşulu için dayatılıyor (generated sütun ifadesi de alt\n * sorgu içeremez).\n */\nfunction assertCheckNode(node: PolicyExpr, name: string): void {\n switch (node.kind) {\n case \"exists\":\n throw new Error(\n `check(${name}): \\`existsIn(...)\\` is a subquery and PostgreSQL forbids subqueries in a CHECK constraint — express a cross-table rule as a composite FOREIGN KEY (foreignKeys), or as a guard.`,\n );\n case \"authUid\":\n throw new Error(\n `check(${name}): \\`auth.uid()\\` renders as a subquery \\`(SELECT auth.uid())\\` and PostgreSQL forbids subqueries in a CHECK constraint — a caller-dependent rule belongs in an RLS policy, not a CHECK.`,\n );\n case \"binop\":\n assertCheckNode(node.left, name);\n assertCheckNode(node.right, name);\n return;\n case \"and\":\n case \"or\":\n for (const part of node.parts) assertCheckNode(part, name);\n return;\n case \"not\":\n case \"isNull\":\n assertCheckNode(node.expr, name);\n return;\n default:\n return;\n }\n}\n\n/** Karşılaştırma operatörlerinin SQL karşılığı — Go'daki `policyBinOps`'un ikizi. */\nconst CHECK_BIN_OPS: Partial<Record<PolicyBinOp, string>> = {\n eq: \"=\",\n neq: \"<>\",\n gt: \">\",\n gte: \">=\",\n lt: \"<\",\n lte: \"<=\",\n};\n\n/** Literal — `policyLiteralSQL`'in (Go) ikizi. Tırnak KAÇILIR: değer sözdizimi olamaz. */\nfunction literalSQL(v: string | number | boolean | null): string {\n if (v === null) return \"NULL\";\n if (typeof v === \"boolean\") return v ? \"true\" : \"false\";\n if (typeof v === \"number\") {\n if (!Number.isFinite(v)) {\n // NaN/Infinity SQL'de bir sayı literali değil; sessizce `NaN` yazmak\n // Postgres'ten sözdizimi hatası getirirdi — deploy anında.\n throw new Error(`check(): ${v} bir SQL sayı literali değil.`);\n }\n return String(v);\n }\n return `'${v.replace(/'/g, \"''\")}'`;\n}\n\n/** Doğrulanmış bir CHECK düğümünü SQL'e derler. */\nfunction checkNodeSQL(node: PolicyExpr, name: string): string {\n switch (node.kind) {\n case \"col\":\n // Takma ad YOK: CHECK yalnız GEÇERLİ SATIRIN kolonlarını görebiliyor, ve\n // takma ad ancak bir `exists` alt sorgusunun içinde doğardı — o da yasak.\n return quote(node.name);\n case \"lit\":\n return literalSQL(node.value);\n case \"binop\": {\n const op = CHECK_BIN_OPS[node.op];\n if (op === undefined) {\n throw new Error(`check(${name}): \\`${node.op}\\` bir CHECK ifadesinde desteklenmiyor.`);\n }\n return `(${checkNodeSQL(node.left, name)} ${op} ${checkNodeSQL(node.right, name)})`;\n }\n case \"and\":\n case \"or\": {\n if (node.parts.length === 0) {\n // Boş bir konjonksiyon `true`, boş bir disjonksiyon `false`. Anlamı\n // yazmak, hiçbir şey yazmayıp kısıtı sessizce genişletmekten iyi.\n return node.kind === \"and\" ? \"(true)\" : \"(false)\";\n }\n const joiner = node.kind === \"and\" ? \" AND \" : \" OR \";\n return `(${node.parts.map((p) => checkNodeSQL(p, name)).join(joiner)})`;\n }\n case \"not\":\n return `(NOT ${checkNodeSQL(node.expr, name)})`;\n case \"isNull\":\n return `(${checkNodeSQL(node.expr, name)} IS ${node.negated ? \"NOT NULL\" : \"NULL\"})`;\n default: {\n // `exists`/`authUid` yukarıda reddedildi; buraya düşen, cebre sonradan\n // eklenmiş ve CHECK için sınıflandırılmamış bir düğümdür. REDDEDİLİR:\n // sınıflandıramadığını geçiren bir kapı, kısıtı sessizce zayıflatır.\n const kind = (node as { kind: string }).kind;\n throw new Error(`check(${name}): \\`${kind}\\` düğümü bir CHECK ifadesinde tanınmıyor.`);\n }\n }\n}\n\n/**\n * `check(\"<ad>\", <ifade>)` — TİPLİ CHECK kısıtı (FR-009).\n *\n * İfade POLİTİKA ifade cebirinin ta kendisiyle yazılıyor; bu DSL'de iki ayrı\n * ifade dili olmaması kurulu ilke. Kolon adları `checks` callback'inin verdiği\n * bağlamdan geliyor, yani yanlış yazılmış bir ad DERLENMİYOR — bugün string\n * biçiminde o hata ancak `ALTER TABLE ... ADD CONSTRAINT` anında Postgres'ten\n * geliyor.\n *\n * ```ts\n * defineTable(\"payments\", {\n * columns: { amount: integer().notNull(), currency: text().notNull() },\n * checks: (c) => [\n * check(\"payments_amount_pos\", c.col(\"amount\").gt(0)),\n * check(\"payments_currency_set\", c.col(\"currency\").isNull(true)),\n * ],\n * })\n * ```\n *\n * @param name Kısıtın adı. CHECK'ler ADA göre uzlaştırılıyor (gövde farkı\n * DROP + ADD demek), o yüzden ad tablo başına tekil olmalı.\n */\nexport function check(name: string, expr: PolicyExprRef): CheckDef {\n if (name.trim() === \"\") {\n throw new Error(\"check(): kısıtın adı boş olamaz — CHECK'ler ADA göre uzlaştırılıyor.\");\n }\n assertCheckNode(expr.expr, name);\n return { name, expr: checkNodeSQL(expr.expr, name) };\n}\n\n/**\n * `can` alanının YANIT şeması (FR-004, D-14).\n *\n * Bir satırın `can`'i, tablonun adlandırılmış UPDATE policy'lerinden o satır ve\n * çağıran için `true` dönenlerin adıdır (engine `canColumns`). Yanıt şemaları\n * elle yazılan zod olduğu için (`dto/*.ts`) bu alan OpenAPI'ye ancak buradan\n * girer: `z.object({ …, can: can(transfers) })`. Enum değerleri policy\n * TANIMINDAN gelir — elle yazılan policy adı yoktur; iki codegen (`emitter.ts`\n * enum→union, swiftgen enum→`case`) tipli sabitleri buradan üretir.\n *\n * SÖZLEŞME (FR-005): `can` ARAYÜZ içindir; yetki kararı için kullanılamaz;\n * eksik olabilir (render edilemeyen policy düşer); sunucu her istekte yeniden\n * karar verir. Ham string policy'de kolon adlarını NİTELİKSİZ yazın — motor\n * ifadeyi `t` alias'ı altında seçer, `transfers.status` orada çözülmez; yorum\n * (`--`, `/*`) ve `auth.has_permission(...)`'ın `(select …)` sarmalı olmadan\n * çağrılması da o policy'yi `can`'den düşürür (warn ile). Yalnız `.for(\"update\")`\n * policy'leri `can`'e girer; `.for(\"all\")` UPDATE'i yönetir ama yankılanmaz.\n * `(select …)` sarmalayıcısını motor bir METİN kapısıyla arar (tırnaklı/boşluklu\n * yazımların sonlu olmayan kümesini DOĞRULAMAZ): bir çağrının satır başına\n * koşup koşmadığının ölçümü EXPLAIN ANALYZE'dır ve demo koşusunda (T016)\n * alınır — yavaş bir `can` yanlış değildir, kapı yalnız yaygın yanlışı yakalar.\n * `can` adı rezervedir: `can` kolonu olan tabloda yankı yok (bu fonksiyon fırlatır),\n * `can` adlı ilişki (`can` tablosu, `can_id` FK, `as`/`reverseAs: \"can\"`) ise\n * `defineTable`'da reddedilir.\n * AS RESTRICTIVE policy'ler Postgres'te olduğu gibi her izinli policy'ye AND'lenir;\n * `TO <rol>` listesi oturum rolüyle kapılanır.\n */\nexport function can<C extends ColumnMap>(table: TableDef<C>): z.ZodArray<z.ZodEnum<[string, ...string[]]>> {\n // `defineTable`'ın döndürdüğü tutamaç (kolonlar + sembol) TableDef DEĞİLDİR —\n // `columns` alanı yoktur; şablon bir zamanlar `can(notes)` öğretiyordu (W1 h1-r4 N-13).\n // `undefined`/`null` first, by name: `can(publicSchema.tables.transfers)` with a table the\n // schema does not declare must not die as a TypeError inside the bundle.\n if (table === undefined || table === null) {\n throw new Error(\n \"can(<table>): received \" + String(table) + \" — the schema declares no such table (check the name against db/*.ts; can(publicSchema.tables.<name>))\",\n );\n }\n const def = table as unknown as { name?: unknown; columns?: unknown; policies?: unknown };\n if (typeof def.name !== \"string\" || def.columns === null || typeof def.columns !== \"object\" || !Array.isArray(def.policies)) {\n throw new Error(\n \"can(<table>): expects the schema's table definition — can(publicSchema.tables.notes) — not the defineTable handle (`notes`)\",\n );\n }\n if (Object.prototype.hasOwnProperty.call(table.columns, \"can\")) {\n throw new Error(\n `can(${table.name}): the table declares a column named \"can\", so the row carries that column and no policy echo — rename the column to get can`,\n );\n }\n const rel = reservedCanRelation(table.name, table.columns);\n if (rel !== null) {\n throw new Error(`can(${table.name}): ${rel}`);\n }\n // Motorla aynı süzgeç (59 bayt): tipte/enum'da olup telde hiç gelmeyecek ad olmasın.\n const names = table.policies\n .filter((p) => p.command === \"update\" && p.permissive !== false && Buffer.byteLength(`can:${p.name}`, \"utf8\") <= 63)\n .map((p) => p.name);\n if (names.length === 0) {\n const all = table.policies.filter((p) => p.command === \"all\").map((p) => p.name);\n const hint = all.length > 0\n ? ` The table's ${all.map((n) => `\"${n}\"`).join(\", \")} ${all.length === 1 ? \"policy is\" : \"policies are\"} for(\"all\") — for(\"all\") governs UPDATE but is not a named update policy and never appears in can.`\n : \"\";\n throw new Error(\n `can(${table.name}): the table declares no update policy — there is nothing a row could echo. ` +\n `Name one with policy(\"<name>\").for(\"update\").using(…) first.${hint}`,\n );\n }\n return z.array(z.enum(names as [string, ...string[]]));\n}\n\n/**\n * `can` bir İLİŞKİ adı olarak da rezervedir: `row.can` literal union'ı ile\n * `relations.can` aynı satırda iki ayrı şey olurdu ve `can(table)` yanıt\n * şemasına koyduğu enum'u çalışma zamanındaki ilişki dizisiyle 500'e çevirirdi\n * (W1 h2-r3 N-2). `defineTable` bunu beyan anında reddeder; burada aynı kural\n * ham `TableDef` için tekrar sorulur. Döneni bir hata cümlesidir, `null` = temiz.\n * Yalnız BU tablonun kendi kolonlarından türeyen adlar görülebilir: tablo adı\n * `can` (ters ilişkinin varsayılan adı) ve `reverseAs: \"can\"` de defineTable'da düşer.\n */\nexport function reservedCanRelation(tableName: string, columns: ColumnMap): string | null {\n if (tableName === \"can\") {\n return `a table named \"can\" would put a relation named \"can\" on every parent it references — rename the table`;\n }\n for (const [col, b] of Object.entries(columns)) {\n const def = (b as { _def: { referencesThunk?: unknown; selfRefColumn?: string; refAs?: string; reverseAs?: string; owns?: boolean } })._def;\n // `selfReferences` de bir ilişki doğurur (`references` şemada sonradan kurulur) — W1 h1-r4 N-10.\n if (def.referencesThunk === undefined && def.selfRefColumn === undefined) continue;\n if (def.reverseAs === \"can\") {\n return `column \"${col}\" names its reverse relation \"can\" — the parent's rows would carry a relation where can is reserved; pick another reverseAs`;\n }\n const forward = def.owns === true ? \"owner\" : (def.refAs ?? (col.endsWith(\"_id\") ? col.slice(0, -3) : col));\n if (forward === \"can\") {\n return `column \"${col}\" would be read as a relation named \"can\" (${def.refAs === undefined ? \"derived from the column name\" : \"its as: option\"}) — can is reserved for the policy echo; rename it`;\n }\n }\n return null;\n}\n","import { exprCtx } from \"./policy.js\";\nimport type { PolicyExpr, PolicyExprCtx, PolicyExprRef } from \"./policy.js\";\nimport type { ColumnMap, TableHandle } from \"./schema.js\";\n\n/**\n * guard.ts — DAR REDDEDİCİ YÜZEY (C-3, FR-015…FR-021).\n *\n * Bildirimsel kısıtların yetişemediği beş madde kaldı: write-once alanlar,\n * durum makinesi geçişleri, sabit olmayan yüklemle çapraz satır kontrolü, işlem\n * düzeyinde toplam, ve alan diline ait teşhis. RLS yolu bunlara KAPALI: `OLD` ve\n * `NEW` bir politika ifadesinde ad olarak YOKTUR (ölçüldü — red, ad çözümleme\n * düzeyinde `CREATE POLICY` anında gelir: `missing FROM-clause entry for table\n * \"new\"`), ve `USING`/`WITH CHECK` iki ayrı satıra karşı ayrı ayrı\n * değerlendirilir; tek ifadede iki satırı yan yana getiren bir kapsam yok.\n *\n * YAZAR ÜÇ ŞEY YAZAR: hangi olay · hangi koşul · ne diyerek reddet. Kalan sekiz\n * knob'un güvenli varsayılanı var ve bu yüzeyde HİÇ görünmüyor: `BEFORE` ·\n * `FOR EACH ROW` (Postgres'in varsayılanı `STATEMENT` ve bir guard için yanlış) ·\n * `UPDATE OF` listesi `WHEN`'den türetilir · `SET search_path = pg_catalog,\n * pg_temp` HER ZAMAN · `SECURITY INVOKER` (asla `DEFINER`) · `NOT DEFERRABLE` ·\n * `REFERENCING`/`FROM` üretilmez · `DROP IF EXISTS` + `CREATE`. Bir yeteneği\n * yüzeye çıkarmak onu politika hâline getirir; bunlar politika DEĞİL, güvenli\n * varsayılan (FR-017).\n *\n * Global bir kaçış kapısı KASITLI OLARAK YOK: django-pgtrigger'ın\n * `SET pgtrigger.ignore`'u herhangi bir oturumun guard'ı atlamasına izin veriyor\n * ve bir BaaS'ta bu kabul edilemez.\n */\n\n// `schema.ts` bu modülü import ediyor, yani buradan ORAYA bir DEĞER import'u\n// ESM'de döngü kurardı — bu dosyada `schema.js`'ten gelen HER ŞEY `type`.\n// Tablonun adına inen tek yol `exprCtx().existsIn`, ve o `policy.ts`'te.\n\n/** Guard'ın tetiklendiği yazma fiili. */\nexport type GuardEvent = \"insert\" | \"update\" | \"delete\";\n\n/**\n * Bir guard bildirimi — C-3/C-4 (FR-015).\n *\n * `when` satırın KENDİ kolonları üzerinde bir yüklem (trigger'ın `WHEN` yan\n * tümcesine iner), `exists` ise çapraz satır yüklemi (gövdedeki `EXISTS`\n * bloğuna). İkisi ayrı alan çünkü Postgres bir trigger'ın `WHEN` yan tümcesinde\n * ALT SORGUYA İZİN VERMİYOR (`ERROR: cannot use subquery in trigger WHEN\n * condition` — ölçüldü); ayrımı wire'da yapmak, emitter'ın yükleme bakıp\n * tahmin etmesinden daha dürüst (FR-019).\n */\nexport interface GuardDef {\n name: string;\n event: GuardEvent;\n when?: PolicyExpr;\n exists?: PolicyExpr;\n message: string;\n detail?: string;\n hint?: string;\n column?: string;\n}\n\n/** Builder'ın YAZILMAKTA olan hâli: olay ve mesaj henüz atanmamış olabilir. */\ntype GuardDraft = Omit<GuardDef, \"event\" | \"message\"> & {\n event?: GuardEvent;\n message?: string;\n};\n\n/**\n * `guard(\"<ad>\")` — bir yazmayı ALAN DİLİYLE reddeden trigger (C-3, FR-015).\n *\n * ```ts\n * guards: (g) => [\n * guard(\"documents_frozen_body\")\n * .on(\"update\")\n * .when(g.col(\"status\").eq(\"archived\"))\n * .refuse(\"Arşivlenmiş belgenin gövdesi değiştirilemez\", { column: \"body\" }),\n * ]\n * ```\n *\n * ADI ZORUNLU (FR-016). Postgres aynı olaya bağlı trigger'ları ADA GÖRE\n * alfabetik sırayla koşar ve başka bir sıra tutamacı YOKTUR: adsız üretilmiş bir\n * guard, sırası kendi kontrolünde olmayan bir guard demektir.\n *\n * Teşhis: red `PB001` SQLSTATE'i ile gelir — `23514` KULLANILMAZ, o gerçek bir\n * CHECK ihlalinin kodu ve istemci ikisini ayırt edemezdi. Guard'ın adı\n * `CONSTRAINT` alanına gider, yani istemci mesajı PARSE ETMEDEN hangi guard'ın\n * reddettiğini okur (FR-021).\n */\nexport class GuardBuilder {\n readonly _def: GuardDraft;\n\n constructor(name: string) {\n if (name.trim() === \"\") {\n throw new Error(\n \"guard(ad): guard'ın adı boş olamaz — Postgres aynı olaydaki trigger'ları ADA GÖRE alfabetik koşuyor ve başka sıra tutamacı yok.\",\n );\n }\n this._def = { name };\n }\n\n /** Hangi yazma fiilinde bakılacak. */\n on(event: GuardEvent): this {\n this._def.event = event;\n return this;\n }\n\n /**\n * Satırın KENDİ kolonları üzerinde koşul — trigger'ın `WHEN` yan tümcesi.\n *\n * Emitter karşılaştırmaları `IS DISTINCT FROM` ile yazar (`<>` NULL'da yanlış\n * cevap verir) ve geçen sütunlardan bir `UPDATE OF (…)` listesi türetir\n * (FR-018).\n */\n when(pred: PolicyExprRef): this {\n this._def.when = pred.expr;\n return this;\n }\n\n /**\n * ÇAPRAZ SATIR koşulu — gövdedeki `EXISTS` bloğuna iner, `WHEN`'e DEĞİL:\n * Postgres trigger `WHEN`'inde alt sorgu kabul etmiyor (FR-019).\n *\n * Yüklem içinde takma adsız kalan kolon guard'ın KENDİ satırıdır (`NEW`/`OLD`);\n * `r.col(...)` hedef tablonun kolonlarını verir ve ayrı nitelenir. Bu yüzden\n * düğümün `outer` alanı BOŞ kalır: bir guard'ın \"dış satır\"ı bir tablo takma\n * adı değildir.\n */\n exists<C extends ColumnMap, N extends string>(\n table: TableHandle<C, N>,\n predicate: (row: PolicyExprCtx<Extract<keyof C, string>>) => PolicyExprRef,\n ): this {\n // Politikaların `existsIn`'i ile AYNI makine: takma ad derinlikten türüyor,\n // iç bağlam hedef tablonun kolonlarıyla kuruluyor. İkinci bir kopyası\n // olsaydı iki korelasyon lehçesi doğardı.\n this._def.exists = exprCtx().existsIn(table, predicate).expr;\n return this;\n }\n\n /**\n * REDDİN KENDİSİ ve zincirin son halkası: mesaj olmadan bir guard tamamlanmaz.\n *\n * `detail`/`hint` Postgres'in aynı adlı alanlarına, `column` ise `COLUMN`\n * alanına gider — istemci hangi alanın reddedildiğini mesajı parse etmeden\n * okur.\n */\n refuse(\n message: string,\n opts?: { detail?: string; hint?: string; column?: string },\n ): GuardDef {\n this._def.message = message;\n if (opts?.detail !== undefined) this._def.detail = opts.detail;\n if (opts?.hint !== undefined) this._def.hint = opts.hint;\n if (opts?.column !== undefined) this._def.column = opts.column;\n return toGuardDef(this);\n }\n}\n\nexport function guard(name: string): GuardBuilder {\n return new GuardBuilder(name);\n}\n\n/**\n * Bildirimi normalize eder ve TUTARLILIĞINI bildirim anında doğrular —\n * `toForeignKeyDef` ile aynı gerekçe: eksik bir guard yazarın editöründe patlar,\n * wire'a hiç çıkmaz.\n */\nexport function toGuardDef(b: GuardBuilder | GuardDef): GuardDef {\n const def: GuardDraft = b instanceof GuardBuilder ? b._def : b;\n if (def.event === undefined) {\n throw new Error(`guard(${def.name}): hangi olayda bakacağı gerekir — .on(\"insert\"|\"update\"|\"delete\") çağırın.`);\n }\n if (def.when === undefined && def.exists === undefined) {\n throw new Error(\n `guard(${def.name}): bir koşul gerekir — .when(...) ya da .exists(...) çağırın. Koşulsuz bir guard o olaydaki HER yazmayı reddeder.`,\n );\n }\n if (def.message === undefined || def.message.trim() === \"\") {\n throw new Error(\n `guard(${def.name}): boş mesaj kabul edilmez — reddin mesajı guard'ın kullanıcıya ulaşan TEK çıktısı.`,\n );\n }\n return {\n name: def.name,\n event: def.event,\n ...(def.when !== undefined ? { when: def.when } : {}),\n ...(def.exists !== undefined ? { exists: def.exists } : {}),\n message: def.message,\n ...(def.detail !== undefined ? { detail: def.detail } : {}),\n ...(def.hint !== undefined ? { hint: def.hint } : {}),\n ...(def.column !== undefined ? { column: def.column } : {}),\n };\n}\n","/**\n * backfill.ts — DDL'DEN AYRI, İZLENEN, BİR KEZ KOŞAN fiil (C-6, FR-033/FR-034).\n *\n * Bir sütun eklemek bildirimseldir; o sütunu DOLDURMAK değildir. Doldurma\n * bugüne kadar `raw()` içinde yaşıyordu ve `raw()` her deploy'da yeniden\n * koşulan bir DDL bloğu — yani veri düzeltmesi ya elle bir kez çalıştırılıyor\n * (kayıt yok, tekrarı belirsiz) ya da idempotent yazılmak zorunda kalıyordu.\n *\n * `backfills:` o işi kendi aşamasına alır: DDL'den SONRA, kendi işleminde ve\n * ADI BAŞINA BİR KEZ. Kayıt `public.palbase_backfills` tablosunda tutulur, yani\n * \"koştu mu\" sorusunun cevabı veritabanının kendisinde durur.\n */\n\n/** Bir backfill bildirimi — C-6 (FR-033). */\nexport interface BackfillDef {\n name: string;\n sql: string;\n}\n\n/**\n * `backfill(\"<ad>\", \"<sql>\")` — bir kez koşacak veri düzeltmesi.\n *\n * ```ts\n * backfills: [\n * backfill(\"ledger_currency_try\", \"UPDATE ledger SET currency = 'TRY' WHERE currency IS NULL\"),\n * ]\n * ```\n *\n * AD, KAYDIN TA KENDİSİ. \"Bu koştu mu?\" sorusu ada göre cevaplanıyor, gövdeye\n * göre değil: adı sabit tutup SQL'i değiştirmek İKİNCİ bir koşu ÜRETMEZ. Bir\n * düzeltmeyi düzeltmek istiyorsan yeni bir ad verirsin — aynı adın altında\n * değişen bir gövde, canlıda hangi sürümün koştuğunu belirsiz bırakırdı.\n *\n * Bu yüzden BOŞ SQL de reddediliyor: boş bir gövde adı kayda geçirir ve o adı\n * KALICI olarak yakar — sonradan yazılan gerçek SQL \"zaten koştu\" diye hiç\n * çalışmaz, hiçbir yerde hata da vermez.\n *\n * SQL verbatim emit edilir (`raw()` ve `policy().using(\"…\")` ile aynı güven\n * duruşu) ve `raw()` ile AYNI ayrıcalıklı DDL bağlantısında koşar — yalnızca\n * KENDİ AŞAMASINDA, yani DDL'den ayrı bir `Exec`'te. Ayrım budur ve tek başına\n * bir güvenlik iddiası DEĞİLDİR.\n *\n * Bu yorum daha önce \"ayrıcalıklı DDL bağlantısında değil\" diyordu ve YANLIŞTI.\n * Yanlış olduğu ölçüldü, ve niçin kayda geçtiği önemli: tam olarak bir\n * inceleyicinin \"backfill güvenli\" diye geçmesine sebep olacak cümleydi.\n *\n * Bu yüzden gövde `raw()` ile AYNI AST yetki kapısından geçiyor: rol yaratan,\n * sahiplik devreden, yetki dağıtan ya da `search_path` kaydıran bir ifade\n * taşıyan bir backfill push'u reddeder. Veri düzeltmesi veri düzeltmesidir.\n */\nexport function backfill(name: string, sql: string): BackfillDef {\n if (name.trim() === \"\") {\n throw new Error(\n \"backfill(ad, sql): backfill'in adı boş olamaz — 'bir kez koştu' kaydı ADA göre tutuluyor.\",\n );\n }\n if (sql.trim() === \"\") {\n throw new Error(\n `backfill(${name}): SQL boş olamaz — boş bir gövde adı kayda geçirip KALICI olarak yakar; sonradan yazılan gerçek SQL \"zaten koştu\" diye hiç çalışmaz.`,\n );\n }\n return { name, sql };\n}\n","import type { ColumnBuilder } from \"./columns.js\";\nimport { qualifiedTableKey } from \"./schema-json.js\";\nimport { PolicyBuilder, check, exprCtx, reservedCanRelation } from \"./policy.js\";\nimport type { CheckDef, PolicyDef, PolicyExprCtx, PolicyExpr, PolicyExprRef } from \"./policy.js\";\nimport type { PalbaseExtension } from \"./extensions.js\";\nimport { ForeignKeyBuilder, FreezeBuilder, REF_TARGET, foreignKey, freeze, toForeignKeyDef, toFreezeDef } from \"./foreign-key.js\";\nimport type { ForeignKeyDef, FreezeDef } from \"./foreign-key.js\";\nimport { GuardBuilder, guard, toGuardDef } from \"./guard.js\";\nimport type { GuardDef } from \"./guard.js\";\nimport { backfill } from \"./backfill.js\";\nimport type { BackfillDef } from \"./backfill.js\";\nimport type { RawConstraintDef } from \"./raw.js\";\nimport type { ChatModelRef, EmbeddingModelRef } from \"./embedding.js\";\n\n/**\n * A map of column builders keyed by column name — the value you write under\n * the `columns` key of `defineTable(\"<name>\", { columns })`.\n *\n * The default `Record<string, ColumnBuilder>` keeps bare references compiling\n * without a type argument.\n */\nexport type ColumnMap = Record<string, ColumnBuilder>;\n\n/**\n * The author-facing value written under each table key:\n * `{ columns, rls?, policies? }`.\n *\n * - `columns`: the column map (required).\n * - `rls`: enable + FORCE row-level security on this table. **Defaults to\n * `true`**, and is forced on when `policies` is non-empty. A table with RLS\n * and no policies is deny-all, which is the starting state: nothing reads it\n * until a policy says who may. Set `rls: false` only for a genuinely public\n * table — it is an explicit opt-out that a reviewer can grep for, not\n * something you get by forgetting.\n * - `policies`: the RLS policies for this table, authored with `policy(name)`.\n * Each entry may be a {@link PolicyBuilder} (the normal `policy(...)` chain)\n * or a raw {@link PolicyDef} object.\n *\n * The `C` type parameter preserves the precise per-column phantom types so the\n * typed `Database.public.*` surface keeps inferring insert/row shapes.\n */\n/** Arama metriği — tek kelime; opclass ve operatör bundan türetilir, asla yüzeye çıkmaz (D-5/D-6). */\nexport type SearchMetric = \"cosine\" | \"euclidean\" | \"inner_product\";\n\n/** Bir vektör arama kolu. `model` varsa auto-embed: platform yazma+sorgu embedding'ini üstlenir (D-9). */\nexport interface VectorSearchDecl {\n /** Hedef vector kolonu; tabloda TEK vector kolonu varsa atlanabilir (Go apply çözer, FR-010). */\n column?: string;\n /** Varsa auto-embed. Deskriptor düz veridir — şemayla serileşir (C-3). */\n model?: EmbeddingModelRef;\n /** model varsa ZORUNLU: embed kaynak kolonları = trigger'ın UPDATE OF listesi (C-2). */\n from?: string[];\n metric?: SearchMetric;\n /** Kaynak metin değişince ara-dönem davranışı (yalnız auto-embed'de):\n * \"null\" (vars.) — embedding anında NULL'lanır; satır yeni vektör yazılana\n * dek anlamsal aramada aday değildir. Bayat eşleşme asla servis edilmez.\n * \"keep\" — eski vektör aramada kalır, platform yenisini yazınca sessizce\n * değişir. Görünürlük penceresi sıfır; bedeli saniyeler süren bayat\n * eşleşme riski (Confluence-tipi sync yükleri için). */\n staleness?: \"null\" | \"keep\";\n}\n\n/** Tablonun arama beyanı — İKİ biçim (D-007, tek yüzey):\n *\n * YENİ (önerilen): `{ from, model, ... }` — `from` kolonları hem FTS'e hem\n * embed'e girer. Tabloda vector kolonu declare edilmişse SATIR-modu; yoksa\n * CHUNK-modu otomatiktir (D-010): vektörler türev `__palbase_chunks`\n * tablosunda yaşar, içerik otomatik bölünür. `text: false` FTS'i kapatır,\n * `text: [..]` FTS kolonlarını from'dan ayırır. `chunks` yalnız ince ayar.\n *\n * ESKİ: `text: string[]` + `vector: {...}` — aynen çalışır, wire çıktısı\n * bayt-aynı kalır (NFR-B1). İki biçim KARIŞTIRILAMAZ. */\nexport interface SearchDecl {\n text?: string[] | boolean;\n vector?: VectorSearchDecl | VectorSearchDecl[];\n /** Yeni biçim: arama kaynağı kolonlar (FTS + embed). Varlığı yeni biçimi seçer. */\n from?: string[];\n /** Yeni biçim: auto-embed modeli (zorunlu — BYO için eski biçimi kullanın). */\n model?: EmbeddingModelRef;\n metric?: SearchMetric;\n staleness?: \"null\" | \"keep\";\n /** Chunk-modu ince ayarı (yalnız vector kolonsuz tabloda anlamlı). */\n chunks?: { size?: number; overlap?: number };\n /** Sorgu-yeniden-yazımı: tek yönlü eş anlamlı haritası (FR-026). */\n synonyms?: Record<string, string[]>;\n /** Geçerlilik kolonları türetilir; arama varsayılan yalnız günceli tarar (FR-029). */\n validity?: boolean;\n}\n\n/** Hafıza beyanı (FR-032, D-019): kaynak tablonun yazımlarından platform\n * fact damıtır ve `into` tablosuna yazar. Hedef NORMAL declared tablodur —\n * kendi search/unique/validity beyanlarıyla. Okuma = Database.$search(into).\n * subject default \"owner\": fact'in kime ait olduğu kolonu (iki tabloda da). */\nexport interface MemoryDecl {\n from: string[];\n into: string;\n extract: ChatModelRef;\n subject?: string;\n}\n\n/**\n * Bir index bildiriminin girdi şekli (FR-041…043).\n *\n * `columns` ile `expression` birbirinin alternatifidir: biri kolon listesi,\n * diğeri `lower(email)` gibi bir ifade. `where` partial index koşuludur ve\n * filtre şekli sorgu tarafındaki `WhereFilter` ile aynıdır — iki ayrı filtre\n * dili olmaz.\n */\n/**\n * Bir index'in TEL şekli — `IndexJSON` ile aynı alanlar (T002).\n *\n * Bildirilmeyen alan HİÇ yazılmaz: sıfır değer yazmak, bildirmeyen her index'i\n * diff'te değişmiş gösterir ve her deploy'a boş bir migration ekler.\n */\nexport interface IndexDef {\n name: string;\n /**\n * `CREATE UNIQUE INDEX` (FR-007). `unique: [{name, columns}]` bir UNIQUE\n * CONSTRAINT üretir ve constraint'in `WHERE`'i olamaz; `index()` partial\n * olabilir ama unique olamıyordu. İki yarım vardı, birleşmiyorlardı.\n */\n unique?: boolean;\n columns?: string[];\n expression?: string;\n where?: PolicyExpr;\n sort?: \"asc\" | \"desc\";\n nulls?: \"first\" | \"last\";\n include?: string[];\n}\n\n/**\n * `index(\"<ad>\")` — C-5 (FR-041…043).\n *\n * ```ts\n * indexes: (c) => [\n * index(\"orders_open\")\n * .on(c.col(\"status\")) // kolon TİPLİ\n * .where(c.col(\"deleted_at\").isNull()) // partial\n * .include([\"total\"]), // covering\n * ]\n * ```\n *\n * `policy()` ile AYNI dili konuşur: `where` politika ifade yapısının ta kendisi.\n * Üçüncü bir filtre lehçesi açmak, aynı sorunun iki yazımı demekti.\n *\n * Kolon bağlamı callback'ten geliyor çünkü index tablo tanımının İÇİNDE\n * bildiriliyor — `orders.status` yazmak, `orders` bağlaması o noktada henüz\n * kurulmadığı için mümkün değil (T015'te `policies` için ölçülen aynı kısıt).\n */\nexport class IndexBuilder {\n readonly _def: IndexDef;\n\n constructor(name: string) {\n if (name.trim() === \"\") {\n throw new Error(\"index(ad): index'in adı boş olamaz — Palbase index'leri ADA göre uzlaştırır.\");\n }\n this._def = { name };\n }\n\n /**\n * `CREATE UNIQUE INDEX` (FR-007). `.where()` ile birlikte PARTIAL UNIQUE\n * index verir (FR-007b) — \"NULL'lar serbest, non-NULL'lar tekil\" kalıbının\n * tek bildirimsel yolu.\n */\n unique(): this {\n this._def.unique = true;\n return this;\n }\n\n /** Index'in kolonları. SIRA KORUNUR — çok kolonlu bir index'in anlamı sırasıdır. */\n on(...cols: PolicyExprRef[]): this {\n this._def.columns = cols.map((c) => {\n const e = c.expr;\n if (e.kind !== \"col\") {\n throw new Error(`index(${this._def.name}).on(): yalnız kolon referansı alır — ifade için onExpression(\"…\") kullanın.`);\n }\n return e.name;\n });\n return this;\n }\n\n /**\n * İfade index'i (`lower(email)`), kolon yerine.\n *\n * Metin VERBATIM emit ediliyor — `policy().using(\"…\")` ile aynı güven duruşu.\n * Tipli yapı bunu ifade edemiyor ve kaçış kapağını kapatmak, yazarı elle\n * migration yazmaya iterdi.\n */\n onExpression(expr: string): this {\n this._def.expression = expr;\n return this;\n }\n\n /** Partial index koşulu — politika ifade dilinin ta kendisi. */\n where(expr: PolicyExprRef): this {\n this._def.where = expr.expr;\n return this;\n }\n\n /** Sıra. Tek yönlü index'te sıra genelde önemsizdir; ORDER BY ile eşleşen\n * bir index arandığında değildir. */\n desc(): this {\n this._def.sort = \"desc\";\n return this;\n }\n\n asc(): this {\n this._def.sort = \"asc\";\n return this;\n }\n\n /** NULL'ların yeri — `ORDER BY … NULLS LAST` ile eşleşmesi için. */\n nulls(where: \"first\" | \"last\"): this {\n this._def.nulls = where;\n return this;\n }\n\n /** Covering index (`INCLUDE`): index-only scan için taşınan ama\n * ARANMAYAN kolonlar. */\n include(cols: string[]): this {\n this._def.include = cols;\n return this;\n }\n}\n\nexport function index(name: string): IndexBuilder {\n return new IndexBuilder(name);\n}\n\nexport interface TableInput<C extends ColumnMap = ColumnMap> {\n columns: C;\n rls?: boolean;\n /**\n * Bu tablonun RLS politikaları — TABLONUN KENDİ KOLONLARININ bir fonksiyonu\n * olarak (FR-022).\n *\n * Callback olmasının sebebi tip: `columns`'tan çıkarılan `C`, TypeScript\n * tarafından buraya bağlamlandırılıyor, yani `p.col(\"ownerr\")` yazım hatası\n * DERLEME hatası oluyor. Düz bir dizide `policy(\"x\")` tek başına çağrıldığı\n * için hangi tabloda olduğunu bilemez, ve yanlış kolon adı ancak deploy\n * anında `CREATE POLICY` çalışırken Postgres'ten dönerdi. Bir RLS\n * politikasında yanlış kolon adı yetki hatasıdır; derlemede yakalanır.\n *\n * ```ts\n * policies: (p) => [\n * policy(\"owner_read\").for(\"select\").using(p.col(\"owner\").eq(p.auth.uid())),\n * ]\n * ```\n */\n policies?: (p: PolicyExprCtx<Extract<keyof C, string>>) => (PolicyBuilder | PolicyDef)[];\n /**\n * KOŞAN SÜRÜMÜN \"BU TABLOYU ARTIK OKUMUYORUM\" SÖZÜ — düşürmenin ilk yarısı.\n *\n * `ColumnDef.ignored`'ın tablo karşılığı ve aynı sebeple var: şema rayı, koşan\n * sürümün hâlâ BEYAN ettiği bir şeyi düşürmeyi reddeder — sıfır satırlı bir\n * tablo için bile, çünkü koşan sürümün bir SELECT'i ona dokunuyor olabilir.\n *\n * ONSUZ TABLO HİÇ DÜŞMÜYORDU (ölçüldü, canlı push 06.09.2026): rayın tavsiyesi\n * *\"beyandan çıkar ve bir kez deploy et\"*ti, ama beyandan çıkarmak düşürmeyi\n * ÜRETEN şeyin ta kendisi — o deploy'da da koşan sürüm tabloyu beyan ediyor\n * olur ve aynı red gelir. Kolonun çıkış yolu vardı, tablonun yoktu.\n *\n * İşaretlemek hiçbir DDL üretmez; ilk deploy'u BEDAVA yapan şey bu.\n *\n * ```ts\n * const cloud_images = defineTable(\"cloud_images\", { ignored: true, columns: { … } });\n * ```\n */\n ignored?: boolean;\n /** Composite/named primary key (ordered column names). Omit for single-column inline .primaryKey(). */\n primaryKey?: string[];\n /** Named multi-column UNIQUE constraints. */\n unique?: { name: string; columns: string[] }[];\n /** Named raw-SQL DDL objects (EXCLUDE, triggers, views) that the typed DSL cannot express. */\n raw?: RawConstraintDef[];\n /**\n * Named first-class CHECK constraints. Diffed by NAME with a BODY compare:\n * a changed `expr` (after pg normalization) recreates the constraint\n * (DROP + ADD). `name` is identifier-validated.\n *\n * İKİ BİÇİM, TEK TEL (FR-009, FR-011):\n *\n * - DİZİ — `expr` verbatim yayılan güvenilen SQL (policy `using` gibi).\n * Bugünkü biçim, olduğu gibi kabul edilmeye devam ediyor.\n * - CALLBACK — `(c) => [check(name, c.col(\"amount\").gt(0))]`: ifade POLİTİKA\n * ifade cebiriyle yazılıyor ve kolon adları DERLEME anında doğrulanıyor.\n * Callback olması bunun şartı: `checks` düz bir dizi olsaydı TypeScript\n * `columns`'tan kolon adlarını çıkarıp ifadeyi onlarla bağlamlandıramazdı.\n *\n * Yanlış yazılmış bir kolon adı string biçiminde ancak\n * `ALTER TABLE … ADD CONSTRAINT` anında — deploy'un ORTASINDA — Postgres'ten\n * dönüyor. Tipli biçim aynı cevabı yazma anına taşıyor.\n *\n * Tipli ifade CHECK bağlamının DAR kümesine tabi: `existsIn` ve `auth.uid()`\n * alt sorgu oldukları için `check()` tarafından reddediliyor (FR-010).\n */\n checks?: CheckDef[] | ((c: PolicyExprCtx<Extract<keyof C, string>>) => CheckDef[]);\n /**\n * Plain (non-unique) btree indexes over an ordered column list, emitted as\n * standalone `CREATE INDEX [IF NOT EXISTS] name ON table (col1, col2)`\n * statements (NOT a table clause — a separate migration statement category).\n * Structural compare by NAME (no expression normalization). `name` and each\n * column are identifier-validated by the Go differ.\n *\n * NAME is the WHOLE diff key. Editing `.where()`, `.onExpression()`,\n * `.include()` or the sort under a name that is already live does NOTHING —\n * the deploy matches the name, sees the index, and skips. Give a changed\n * definition a new name.\n *\n * Scope, via `index(name)`: `.on(...cols)` · `.onExpression(sql)` (expression\n * index) · `.where(pred)` (partial index, typed predicate) · `.unique()`\n * (UNIQUE, and WITH `.where()` a PARTIAL UNIQUE index) · `.include(cols)`\n * (covering) · `.asc()`/`.desc()`/`.nulls()`. Predicates and expressions are\n * probed against the live database before the push — as a prepared statement\n * AND as a real CREATE INDEX on an empty `LIKE` clone, which is what catches\n * a subquery predicate or a non-IMMUTABLE function before the apply.\n *\n * `index(n).unique().where(p)` is the ONE declarative way to say \"NULLs are\n * free, non-NULLs are unique\" — the table-level `unique:` cannot carry a\n * predicate, because it renders a CONSTRAINT and PostgreSQL has no partial\n * unique CONSTRAINT (only a partial unique INDEX).\n *\n * NOT expressible here: another index method (gin/gist/brin/hash), an\n * opclass, or CONCURRENTLY.\n */\n indexes?: (p: PolicyExprCtx<Extract<keyof C, string>>) => (IndexBuilder | IndexDef)[];\n /**\n * Canlıdan DÜŞÜRÜLECEK constraint adları (FR-008).\n *\n * Differ additive: canlıda olup bildirimde olmayan bir constraint asla\n * düşürülmez — beyan dosyası veritabanının nesnelerine sahip değildir. Bu\n * alan o kuralın TEK istisnası ve açıkça yazılmış olması gerekiyor.\n *\n * Ad bilinçli olarak `retired` DEĞİL: bu DSL'de `retired` zaten \"emekliye\n * ayrılmış ÇAĞRI biçimi\" demek (`schema-retired-call.test.ts`).\n */\n dropConstraints?: string[];\n /**\n * Tablo düzeyinde, ÇOK SÜTUNLU FOREIGN KEY'ler (FR-001).\n *\n * Kolon üzerindeki `.references()` tek sütunlu ve tek hedeflidir; çok kiracılı\n * bütünlüğün istediği `FOREIGN KEY (tenant_id, child_id) REFERENCES parent\n * (tenant_id, id)`'yi ifade edemez. İki yol birbirini DÜŞÜRMEZ: bu bildirim\n * kendi adıyla, kolon üzerindekiler `<tablo>_<kolon>_fkey` ile izlenir.\n */\n foreignKeys?: (p: PolicyExprCtx<Extract<keyof C, string>>) => (ForeignKeyBuilder | ForeignKeyDef)[];\n /**\n * KOŞULLU FK'lar — bir koşul sağlandığı sürece donan demetler (FR-012).\n *\n * \"Ödeme `settled` olduğu sürece faturanın tutarı değişemez\" bir trigger\n * istemiyor: koşul sağlanmıyorken NULL veren `STORED` generated sütunlar ve\n * onlardan `ON UPDATE RESTRICT` bir FK, `MATCH SIMPLE`'ın NULL kaçışı\n * üzerinden aynı şeyi CONSTRAINT olarak veriyor.\n *\n * `foreignKeys` ile aynı sebeple callback: `when` yüklemi TABLONUN KENDİ\n * kolonlarından çözülüyor ve yanlış ad derleme hatası oluyor.\n */\n freeze?: (p: PolicyExprCtx<Extract<keyof C, string>>) => (FreezeBuilder | FreezeDef)[];\n /**\n * Bu tablonun GUARD'ları — bildirimsel kısıtın yetişemediği yazma redleri\n * (FR-015).\n *\n * Yazar üç şey yazar: hangi olay · hangi koşul · ne diyerek reddet. `BEFORE`,\n * `FOR EACH ROW`, `SECURITY INVOKER`, pinlenmiş `search_path` ve `UPDATE OF`\n * türetimi güvenli VARSAYILAN — bu yüzeyde görünmezler (FR-017).\n *\n * `policies` ile aynı sebeple callback: koşul TABLONUN KENDİ kolonlarından\n * çözülüyor ve yanlış bir ad derleme hatası oluyor. Bir guard'da yanlış kolon\n * adı, hiç ateşlemeyen bir guard demektir — güvenlik yolunda fail-open.\n */\n guards?: (p: PolicyExprCtx<Extract<keyof C, string>>) => (GuardBuilder | GuardDef)[];\n /**\n * BİR KEZ koşacak veri düzeltmeleri — DDL'den AYRI bir aşamada (FR-033).\n *\n * Sütun eklemek bildirimseldir, o sütunu DOLDURMAK değildir: doldurma bugüne\n * kadar her deploy'da yeniden koşan bir `raw()` bloğunun içindeydi. Burası o\n * işin kendi aşaması; kayıt ada göre tutuluyor ve aynı ad ikinci kez koşmuyor\n * (FR-034).\n *\n * `policies`/`guards`'ın aksine düz bir dizi: bir backfill'in yüklemi yok,\n * gövdesi verbatim SQL — bağlamlandıracak bir kolon adı da yok.\n */\n backfills?: BackfillDef[];\n /**\n * appendOnly (FR-030): tablo yalnız INSERT kabul eder — UPDATE/DELETE hem\n * veritabanı yetkisiyle hem üretilen tipte reddedilir (T017/T018).\n * Ledger deseninin veri katmanından istediği TEK şey budur: bakiye türetilmiş\n * bir değerdir ve entry log'u değiştirilebilirse doğruluğunu kaybeder.\n */\n appendOnly?: boolean;\n /** Arama beyanı — bkz. SearchDecl. */\n search?: SearchDecl;\n /** Hafıza beyanı — bkz. MemoryDecl (FR-032). */\n memory?: MemoryDecl;\n}\n\n/**\n * A table definition — the runtime value the Go runtime's `schema_extract.js`\n * reads. It keys tables by `tableDef.name`, reads `tableDef.columns` for the\n * column DDL, and `tableDef.rls` + `tableDef.policies` for RLS.\n *\n * `defineSchema` derives `name` from the object key, so authors never repeat\n * the table name. `rls`/`policies` are always present after normalization\n * (defaulted to `true`/`[]`).\n *\n * The `C` type parameter preserves the precise per-column phantom types so that\n * downstream mapped types (InsertShape, RowShape) can discriminate on them.\n */\nexport interface TableDef<C extends ColumnMap = ColumnMap> {\n name: string;\n columns: C;\n rls: boolean;\n /** Koşan sürümün \"bu tabloyu okumuyorum\" sözü — bkz. TableInput.ignored. */\n ignored?: boolean;\n policies: PolicyDef[];\n primaryKey?: string[];\n unique?: { name: string; columns: string[] }[];\n /** Named raw-SQL DDL objects emitted verbatim on deploy. Tracked by name. */\n raw?: RawConstraintDef[];\n /** Named first-class CHECK constraints. Diffed by name + (normalized) body.\n * İki yazım biçimi de (dizi / callback) BURAYA iner — bkz. TableInput.checks. */\n checks?: CheckDef[];\n /** Index bildirimleri; partial/expression/sıra/covering alanlarıyla (FR-041…043). */\n indexes?: IndexDef[];\n /** Canlıdan düşürülecek constraint adları (FR-008). */\n dropConstraints?: string[];\n /** Tablo düzeyi çok sütunlu FOREIGN KEY bildirimleri (FR-001). */\n foreignKeys?: ForeignKeyDef[];\n /** Koşullu FK (\"donan demet\") bildirimleri (FR-012). */\n freeze?: FreezeDef[];\n /** Guard bildirimleri — bildirimsel kısıtın yetişemediği yazma redleri (FR-015). */\n guards?: GuardDef[];\n /** Bir kez koşacak veri düzeltmeleri, DDL'den ayrı aşamada (FR-033). */\n backfills?: BackfillDef[];\n /** appendOnly (FR-030) — bkz. TableInput. */\n appendOnly?: boolean;\n /** Arama beyanı, doğrulanmış ve taşınmış hali. */\n search?: SearchDecl;\n /** Hafıza beyanı, doğrulanmış ve taşınmış hali (FR-032). */\n memory?: MemoryDecl;\n}\n\n/**\n * A schema definition containing multiple tables, keyed by table name.\n *\n * The `T` type parameter preserves the exact `TableDef<...>` type for each\n * table so that `SchemaDef[\"tables\"][\"rooms\"]` resolves to the precise\n * `TableDef<{ id: ColumnBuilder<'uuid', false, true, never>; ... }>`.\n */\nexport interface SchemaDef<\n T extends Record<string, TableDef> = Record<string, TableDef>,\n> {\n /** The schema's own name — `public`, `billing`, … Declared, never derived. */\n name: string;\n /** Reachable over HTTP? False unless the author opts in. */\n exposed: boolean;\n tables: T;\n /** Postgres extensions to install on deploy. Normalized to `[]` when absent. */\n extensions: PalbaseExtension[];\n}\n\n/** The author-facing input to `defineSchema` — a `tables` map whose keys are\n * the table names and whose values are `{ columns, rls?, policies? }`, plus an\n * optional `extensions` allowlist. */\nexport interface SchemaInput<\n T extends Record<string, TableInput> = Record<string, TableInput>,\n> {\n tables: T;\n /**\n * Postgres extensions to enable for this project, e.g. `[\"vector\"]`.\n * Config-as-code: installed by the deploy (CREATE EXTENSION … SCHEMA\n * extensions) with the privileged deploy connection. The type is an\n * allowlist union, so unsupported names fail typecheck.\n */\n extensions?: PalbaseExtension[];\n}\n\n/** Map the author's `{ tables: { <name>: { columns } } }` input to the\n * `{ tables: { <name>: TableDef<columns> } }` runtime/type shape, threading the\n * per-table column map `T[K][\"columns\"]` so column-level inference survives. */\ntype TablesByName<T extends readonly TableHandle[]> = {\n [K in T[number] as K[typeof TABLE_META][\"name\"]]: K[typeof TABLE_META];\n};\n\n/** Normalize a single `policies` entry into a plain `PolicyDef` (read off a\n * `PolicyBuilder._def`, or passed through when already a `PolicyDef`). */\nfunction toPolicyDef(p: PolicyBuilder | PolicyDef): PolicyDef {\n return p instanceof PolicyBuilder ? p._def : p;\n}\n\n/**\n * How a schema file reads. One file per schema — `db/public.ts`, `db/billing.ts`\n * — and the schema says its own name:\n *\n * const todos = defineTable(\"todos\", {\n * columns: {\n * id: uuid().primaryKey().defaultRandom(),\n * owner: text().notNull(),\n * title: text().notNull(),\n * },\n * rls: true,\n * policies: (p) => [\n * policy(\"owner_all\").for(\"all\").to(\"authenticated\")\n * .using(p.col(\"owner\").eq(p.auth.uid()))\n * .withCheck(p.col(\"owner\").eq(p.auth.uid())),\n * ],\n * });\n *\n * export default defineSchema(\"public\", { tables: [todos] });\n *\n * The dictionary form `defineSchema({ tables: { todos: {…} } })` is RETIRED and\n * refused by name: a table whose name comes from a key does not know what it is\n * called while it is being built, so it cannot resolve `references(() =>\n * other.id)`, and a schema that does not say its own name cannot tell one\n * `invoices` from another schema's `invoices`.\n *\n * The returned value is `{ name, tables: { todos: { name, columns, rls,\n * policies } }, extensions, exposed }` — the exact shape the runtime schema\n * extractor parses. Per-column phantom types are preserved so\n * `Database.public.todos.insert({...})` stays typed.\n *\n * RLS normalization: `rls` defaults to **`true`**, `policies` to `[]`. A table\n * that declares neither is therefore deny-all — nothing reads it until a policy\n * says who may, which is the safe starting point rather than a bug. Declare\n * `rls: false` for a genuinely public table; that is an explicit, greppable\n * statement of intent instead of an omission. When `policies` is non-empty,\n * `rls` is forced on (ENABLE + FORCE) regardless of the declared flag — a table\n * with policies must have RLS enabled or the policies would be inert.\n */\n/**\n * Where a table's metadata lives.\n *\n * The table VALUE is its columns, so `lists.id` is the column — which means a\n * column called `name` would overwrite the table's own name if metadata sat in\n * a plain field. Measured, not imagined: the existing `users` / `rooms` tests\n * (both declare a `name` column) produced an `[object Object]` table key.\n * `columns`, `rls`, `search`, `memory`, `unique` and `indexes` are all plausible\n * column names too. A column cannot collide with a symbol.\n */\nexport const TABLE_META: unique symbol = Symbol.for(\"palbase.table.meta\");\n\n/** A value produced by `defineTable`: the columns, plus metadata behind the symbol. */\nexport type TableHandle<C extends ColumnMap = ColumnMap, N extends string = string> =\n C & { readonly [TABLE_META]: TableDef<C> & { name: N } };\n\n/**\n * Declare one table as a standalone value that KNOWS ITS OWN NAME.\n *\n * The name lives here, not in a dictionary key. A table whose name comes from a\n * key cannot resolve `references(() => other.id)` when it is built — it does not\n * know what to call itself — which forces a two-phase resolution with an\n * empty-name intermediate state. One name source, no empty identity.\n *\n * The returned object spreads its own columns, so a sibling can point at it:\n * `references(() => lists.id)`.\n */\nexport function defineTable<const N extends string, C extends ColumnMap>(\n name: N,\n input: TableInput<C>,\n): TableHandle<C, N> {\n if (name.trim() === \"\") {\n throw new Error(\"defineTable(name, …): name must not be empty\");\n }\n // `can` bir ilişki adı olarak rezerve (W1 h2-r3 N-2): beyan anında reddedilir,\n // motor/env-gen/can() aynı şeyi üç yerde ayrı ayrı kollamak zorunda kalmasın.\n {\n const reserved = reservedCanRelation(name, input.columns);\n if (reserved !== null) throw new Error(`defineTable(${JSON.stringify(name)}): ${reserved}`);\n }\n // İfade bağlamı TABLONUN KENDİ kolon adlarıyla kuruluyor (FR-022). Çalışma\n // zamanında `col()` adı doğrulamıyor — doğrulayan tip; burada yapılacak\n // ikinci bir kontrol, tipin zaten imkânsız kıldığı bir şeyi tekrar ederdi.\n const policies = (input.policies?.(exprCtx(Object.keys(input.columns), 0, name)) ?? []).map(toPolicyDef);\n // Fail closed. RLS is on unless the author explicitly says `rls: false`, and\n // policies force it on regardless — a policy on a table without RLS enabled is\n // inert, so declaring both resolves towards the safe reading.\n //\n // This defaulted to `false` until 2026-08-07, which meant a table nobody\n // thought about had no row-level security while `typed-db.ts` documented the\n // default `Database.*` path as RLS-enforced. The live proof settled it: user B\n // read user A's row in full through the typed client, while the same request\n // against a table declaring `rls: true` returned 0 of 165 rows. With no\n // policies this is deny-all.\n const rls = policies.length > 0 || input.rls !== false;\n // EACH TABLE GETS ITS OWN COLUMN OBJECTS.\n //\n // A ColumnBuilder shares one `_def` with every builder derived from it, so a\n // shared column — `const audit = { created_at: timestamp() }` spread into two\n // tables, the most ordinary pattern this DSL has — would put BOTH tables'\n // stamps on one object and the second declaration would win. A reference\n // thunk written as `() => a.created_at` then resolved to table `b`: a\n // well-formed foreign key onto the WRONG table, with no error anywhere.\n //\n // Copying is what `.ignored()` already does about the same aliasing, and it\n // keeps the spread pattern working rather than banning it. The copies are\n // what the def AND the handle carry, so the identity match that resolves a\n // reference thunk still finds its column.\n const owned = {} as C;\n for (const [colName, b] of Object.entries(input.columns)) {\n const builder = b as { _def: ColumnDefLike };\n // Same class, same phantom type parameters, its own `_def`. Cloning through\n // the prototype rather than the constructor keeps this file free of a value\n // import from columns.ts — the two modules only ever exchanged types.\n const clone = Object.create(Object.getPrototypeOf(builder)) as { _def: ColumnDefLike };\n Object.defineProperty(clone, \"_def\", { value: { ...builder._def }, enumerable: true, writable: true });\n (owned as Record<string, unknown>)[colName] = clone;\n }\n\n const def = {\n name,\n columns: owned,\n rls,\n policies,\n } as TableDef<C> & { name: N };\n if (input.primaryKey !== undefined) def.primaryKey = input.primaryKey;\n if (input.unique !== undefined) def.unique = input.unique;\n if (input.raw !== undefined && input.raw.length > 0) def.raw = input.raw.slice();\n // İki dal da AYNI `CheckDef[]`'e iniyor (FR-009, FR-011): tipli dal ifadeyi\n // `check()` içinde SQL'e derliyor, string dal yazarın SQL'ini taşıyor. Telde\n // yeni bir alan doğmuyor — `TableJSON.checks` bugünkü `{ name, expr }[]`.\n const declaredChecks =\n typeof input.checks === \"function\"\n ? input.checks(exprCtx(Object.keys(input.columns), 0, name))\n : (input.checks?.slice() ?? []);\n if (declaredChecks.length > 0) def.checks = declaredChecks;\n // İfade bağlamı `policies` ile AYNI — index kolonları da tablonun kendi\n // kolonlarından çözülüyor ve yanlış ad derleme hatası (FR-041).\n const declaredIndexes = (input.indexes?.(exprCtx(Object.keys(input.columns), 0, name)) ?? []).map(\n (i) => (i instanceof IndexBuilder ? i._def : i),\n );\n if (declaredIndexes.length > 0) def.indexes = declaredIndexes;\n // Tablo düzeyi çok sütunlu FK'lar (FR-001). `toForeignKeyDef` tutarlılığı\n // BURADA doğruluyor: sütun sayıları eşleşmeyen bir bildirim yazarın\n // editöründe patlıyor ve wire'a hiç çıkmıyor. Push'taki red (FR-002) aynı\n // kuralı deploy tarafında tekrar kuruyor — iki kapı, iki farklı okuyucu için.\n const declaredFKs = (input.foreignKeys?.(exprCtx(Object.keys(input.columns), 0, name)) ?? []).map(\n toForeignKeyDef,\n );\n if (declaredFKs.length > 0) def.foreignKeys = declaredFKs;\n // Koşullu FK'lar (FR-012). `toFreezeDef` tutarlılığı burada doğruluyor;\n // `.references()` zaten aynı fonksiyondan geçtiği için düz bir `FreezeDef`\n // yazan yol da aynı kapıdan geçer.\n const declaredFreezes = (input.freeze?.(exprCtx(Object.keys(input.columns), 0, name)) ?? []).map(\n toFreezeDef,\n );\n if (declaredFreezes.length > 0) def.freeze = declaredFreezes;\n // SÜTUN ADLARI BU TABLONUN OLMALI — ve bu kontrol burada, bildirimin yazıldığı\n // yerde. `.columns(...)` serbest `string` alıyor (aynı builder'ın\n // `.references()`'ı tipli), yani bir typo editörde geçiyordu ve bedeli\n // push'ta ya da — yeni bir tabloda, canlı round-trip'in atlandığı yolda —\n // apply'ın ORTASINDA bir `CREATE`/`ALTER` hatası olarak çıkıyordu.\n for (const fz of declaredFreezes) {\n for (const c of fz.columns) {\n if (!(c in input.columns)) {\n throw new Error(\n `table \"${name}\": freeze(\"${fz.name}\").columns(\"${c}\") — no such column on this table. ` +\n `Declared columns: ${Object.keys(input.columns).join(\", \")}`,\n );\n }\n }\n }\n // Guard'lar (FR-015). `toGuardDef` olay/koşul/mesaj üçlüsünü bildirim anında\n // şart koşuyor — eksik bir guard hiç ateşlemeyen bir guard'dır ve güvenlik\n // yolunda sessiz bir fail-open olurdu.\n const declaredGuards = (input.guards?.(exprCtx(Object.keys(input.columns), 0, name)) ?? []).map(\n toGuardDef,\n );\n if (declaredGuards.length > 0) def.guards = declaredGuards;\n // Aynı gerekçe: `refuse(msg, { column })` serbest `string` ve o sütun hem\n // reddin `COLUMN` alanına hem `UPDATE OF` listesine giriyor.\n for (const g of declaredGuards) {\n if (g.column !== undefined && !(g.column in input.columns)) {\n throw new Error(\n `table \"${name}\": guard(\"${g.name}\").refuse(…, { column: \"${g.column}\" }) — no such column on this table. ` +\n `Declared columns: ${Object.keys(input.columns).join(\", \")}`,\n );\n }\n }\n if (input.backfills !== undefined && input.backfills.length > 0) {\n // AYNI AD İKİ KEZ = ikincisi HİÇ koşmaz. Kayıt ada göre tutuluyor\n // (FR-034), yani ikinci bildirim sessizce atlanır ve hiçbir yerde hata\n // vermez. Beyan anında reddetmek bunun tek görünür hâli.\n const seen = new Set<string>();\n for (const b of input.backfills) {\n if (seen.has(b.name)) {\n throw new Error(\n `table ${name}: backfill adı iki kez bildirildi: ${b.name} — kayıt ADA göre tutuluyor, ikincisi hiç koşmazdı.`,\n );\n }\n seen.add(b.name);\n }\n def.backfills = input.backfills.map((b) => ({ name: b.name, sql: b.sql }));\n }\n if (input.dropConstraints !== undefined && input.dropConstraints.length > 0) {\n def.dropConstraints = [...input.dropConstraints];\n }\n if (input.appendOnly === true) def.appendOnly = true;\n // `omitempty` ile aynı sözleşme: işaretlenmemiş tablo alanı HİÇ taşımaz, yani\n // bugüne kadarki her beyanın telde bayt-aynı kalması garanti.\n if (input.ignored === true) def.ignored = true;\n if (input.search !== undefined) {\n const s = input.search;\n // Erken, beyan-anı doğrulama (apply doğrulamasını İKAME ETMEZ — yazım\n // hatası deploy'a gitmeden yazarın yüzüne söylenir).\n if (s.from !== undefined) {\n // YENİ biçim (D-007). Eski alanlarla karışım tek biçime zorlanır:\n // iki yarım beyanın hangisinin kazandığını okuyucu bilemez.\n if (s.vector !== undefined) {\n throw new Error(\n `table ${name}: search beyanında tek biçim kullanın — 'from' (yeni) ile 'vector' (eski) birlikte olamaz`,\n );\n }\n if (s.from.length === 0) {\n throw new Error(`table ${name}: search.from boş olamaz`);\n }\n if (s.model === undefined) {\n throw new Error(\n `table ${name}: search.from model'siz anlamsız — auto-embed için model verin (BYO için eski 'vector' biçimini kullanın)`,\n );\n }\n if (Array.isArray(s.text) && s.text.length === 0) {\n throw new Error(`table ${name}: search.text boş dizi olamaz — FTS istemiyorsan text: false yazın`);\n }\n } else {\n // ESKİ biçim — davranış ve hata metinleri aynen (NFR-B1'in DX yarısı).\n if (typeof s.text === \"boolean\") {\n throw new Error(`table ${name}: text:${String(s.text)} yalnız yeni biçimde ('from' ile) geçerli`);\n }\n if (s.text === undefined && s.vector === undefined) {\n throw new Error(\n `table ${name}: search beyanı boş — en az bir kol (text ya da vector) verin, yoksa alanı hiç yazmayın`,\n );\n }\n if (s.text !== undefined && s.text.length === 0) {\n throw new Error(`table ${name}: search.text boş olamaz — FTS kolu istemiyorsan alanı hiç yazma`);\n }\n const legs = s.vector === undefined ? [] : Array.isArray(s.vector) ? s.vector : [s.vector];\n for (const leg of legs) {\n if (leg.model !== undefined && (leg.from === undefined || leg.from.length === 0)) {\n throw new Error(`table ${name}: search.vector.model beyan edildi ama 'from' yok — embed kaynağı kolonlar zorunlu (C-2)`);\n }\n if (leg.model === undefined && leg.from !== undefined) {\n throw new Error(`table ${name}: search.vector.from model'siz anlamsız — auto-embed için model verin`);\n }\n }\n }\n def.search = s;\n }\n if (input.memory !== undefined) {\n if (input.memory.from.length === 0) {\n throw new Error(`table ${name}: memory.from boş olamaz`);\n }\n def.memory = input.memory;\n }\n // The stamp goes on the COPIES, after the def exists — that is how a\n // reference thunk names its target when `defineSchema` resolves it.\n for (const b of Object.values(owned as Record<string, unknown>)) {\n (b as { _def: { ownerTable?: unknown } })._def.ownerTable = def;\n }\n // Columns are the enumerable surface; metadata hangs off a non-enumerable\n // symbol so it survives spreads and cannot be shadowed by a column name.\n const handle = { ...(owned as Record<string, unknown>) } as TableHandle<C, N>;\n Object.defineProperty(handle, TABLE_META, { value: def, enumerable: false });\n return handle;\n}\n\n/**\n * Which schema declared a table.\n *\n * A `TableDef` cannot carry it: `defineTable` runs before any schema exists, and\n * `defineSchema` is where the answer arrives. It lives OUTSIDE the def rather\n * than on it because the def is serialized — a field here would either leak into\n * the wire shape or need a second rule saying not to. A WeakMap keyed by the def\n * object is the same fact with no surface.\n *\n * It exists because a foreign key names its target and that name is only half a\n * name without the schema. `resolveReferences` reads it to write the referent\n * the way `qualifiedTableKey` writes every other table name.\n */\nconst declaringSchemaOf = new WeakMap<object, string>();\n\n/**\n * Resolve every pending reference thunk.\n *\n * Runs inside `defineSchema`, where all table bindings exist and every table\n * already carries its name — which is why the name lives on the table and not in\n * a dictionary key: resolving against a table that does not yet know what it is\n * called would need a second pass over an empty-name intermediate state.\n *\n * The written referent follows the ONE naming convention (`qualifiedTableKey`):\n * a `public` table is bare, anything else is schema-qualified. The deciding fact\n * is the REFERENT's schema, not whether the key crosses a schema boundary —\n * exactly the CASE Go's introspection uses when it reads a live FK back\n * (`introspect.go`: `CASE WHEN rn.nspname = 'public' THEN rt.relname ELSE\n * rn.nspname || '.' || rt.relname END`). Writing `invoices` for a table that\n * lives in `billing` made Go read it as `public.invoices`: a FK onto a table\n * that does not exist, or — worse and silently — onto a DIFFERENT table that\n * happened to share the name.\n */\nfunction resolveReferences(tables: Record<string, TableDef>, schemaName: string): void {\n for (const table of Object.values(tables)) {\n // ÇAPRAZ ŞEMA HEDEFLERİ: bileşik FK, freeze ve guard'ın `.exists()`'i.\n //\n // Üçü de builder anında yalnız hedefin ADINI biliyordu ve ÇIPLAK yazıyordu.\n // Kolon başına yolun bu satırların hemen altında kapattığı sessizliğin ta\n // kendisi — ve Go tarafındaki bedeli üç katlı: `REFERENCES orders` ya 42P01\n // ya YANLIŞ tabloya FK; `compositeFKEqual` canlının nitelikli adıyla hiç\n // eşleşmiyor (her push DROP+ADD, kalıcı drift); `validateCompositeFKs`\n // anahtar denetimini sessizce atlıyor. Guard'da daha da kötü: gövde ÇALIŞMA\n // ANINDA ayrıştırılıyor, yani hata KULLANICININ yazması sırasında geliyor.\n qualifyRefTargets(table, `table \"${table.name}\"`);\n }\n for (const table of Object.values(tables)) {\n for (const [colName, builder] of Object.entries(table.columns)) {\n const def = (builder as { _def: ColumnDefLike })._def;\n if (def.selfRefColumn !== undefined) {\n if (!(def.selfRefColumn in table.columns)) {\n throw new Error(\n `table \"${table.name}\" column \"${colName}\": selfReferences(\"${def.selfRefColumn}\") — no such column on this table`,\n );\n }\n // A self-reference is a reference: its referent is this table, in THIS\n // schema, so it is written by the same rule as any other.\n def.references = {\n table: qualifiedTableKey(schemaName, table.name),\n column: def.selfRefColumn,\n };\n continue;\n }\n if (def.referencesThunk === undefined) continue;\n const target = def.referencesThunk();\n const owner = (target as { _def?: ColumnDefLike } | undefined)?._def?.ownerTable;\n if (owner === undefined) {\n throw new Error(\n `table \"${table.name}\" column \"${colName}\": references(() => …) must point at a column of a table declared with defineTable(...)`,\n );\n }\n const targetColumn = Object.entries(owner.columns).find(\n ([, b]) => (b as { _def: unknown })._def === (target as { _def: unknown })._def,\n )?.[0];\n if (targetColumn === undefined) {\n throw new Error(\n `table \"${table.name}\" column \"${colName}\": the referenced column was not found on table \"${owner.name}\"`,\n );\n }\n const targetSchema = declaringSchemaOf.get(owner);\n if (targetSchema === undefined) {\n // Assuming `public` here is the exact silence this resolution closes:\n // it would produce a FK onto a table that does not exist, or onto a\n // same-named one that does. Name the gap instead.\n throw new Error(\n `table \"${table.name}\" column \"${colName}\": references(() => …) points at table ` +\n `\"${owner.name}\", which no defineSchema(...) has claimed yet — a foreign key cannot ` +\n `be written without its target's schema. Declare that table's schema first ` +\n `(one file per schema: db/public.ts, db/billing.ts …, imported by this one).`,\n );\n }\n def.references = {\n table: qualifiedTableKey(targetSchema, owner.name),\n column: targetColumn,\n };\n }\n }\n}\n\ntype ColumnDefLike = {\n references?: { table: string; column: string };\n referencesThunk?: () => unknown;\n selfRefColumn?: string;\n ownerTable?: { name: string; columns: Record<string, unknown> };\n};\n\n/**\n * Collect declared tables into one schema.\n *\n * Takes an ARRAY, not a dictionary: the tables already carry their names, and a\n * second name source is a second thing that can disagree.\n */\nexport function defineSchema<const T extends readonly TableHandle[]>(\n name: string,\n input: { tables: T; exposed?: boolean; extensions?: PalbaseExtension[] },\n): SchemaDef<TablesByName<T>> {\n // The TYPE first, then the value. The retired one-argument form passes an\n // object here, and a guard that only asks whether the name is blank calls\n // `.trim()` on it — which threw `name.trim is not a function` out of the child\n // process that runs `db/*.ts` during push: no file, no form, nothing to act\n // on. `references(\"t\", \"c\")` already answers its own retirement by name.\n if (typeof name !== \"string\") {\n throw new Error(\n `defineSchema(...) takes the schema NAME first: ` +\n `defineSchema(\"public\", { tables: [todos, lists] }). ` +\n `The one-argument form defineSchema({ tables: { … } }) is gone — a schema that does not ` +\n `say its own name cannot be told apart from another schema's table of the same name, ` +\n `which is what a cross-schema foreign key has to do. ` +\n `Migrate db/public.ts (one file per schema: db/public.ts, db/billing.ts …): name the ` +\n `schema, and lift each table key onto the table itself with ` +\n `defineTable(\"todos\", { columns: { … } }), then list the tables in the array.`,\n );\n }\n if (name.trim() === \"\") {\n throw new Error(\"defineSchema(name, …): name must not be empty\");\n }\n const tables = {} as Record<string, TableDef>;\n for (const handle of input.tables) {\n const table = handle[TABLE_META];\n if (tables[table.name] !== undefined) {\n throw new Error(\n `defineSchema(\"${name}\"): two tables declare the name \"${table.name}\" — table names must be unique within a schema`,\n );\n }\n tables[table.name] = table;\n // Stamped BEFORE resolution: a reference from this schema to a sibling in it\n // must find the sibling's schema, and the sibling may be declared later in\n // the array than the table pointing at it.\n declaringSchemaOf.set(table, name);\n }\n // Thunks are invoked HERE: every binding exists and every name is already set.\n resolveReferences(tables, name);\n // memory beyanları TABLOLAR-ARASI doğrulanır (into/subject/fact) — tüm\n // tablolar kurulduktan sonra: beyan sırasına bağımlılık olmasın (FR-032).\n for (const [name, def] of Object.entries(tables)) {\n const m = (def as TableDef).memory;\n if (m === undefined) continue;\n const target = Object.values(tables).find((t) => (t as TableDef).name === m.into) as TableDef | undefined;\n if (target === undefined) {\n throw new Error(`table ${name}: memory.into \"${m.into}\" şemada declared değil`);\n }\n const subject = m.subject ?? \"owner\";\n if (!(subject in (def as TableDef).columns)) {\n throw new Error(`table ${name}: memory.subject \"${subject}\" kolonu kaynak tabloda yok`);\n }\n if (!(subject in target.columns)) {\n throw new Error(`table ${name}: memory.subject \"${subject}\" kolonu hedef \"${m.into}\" tablosunda yok`);\n }\n const factCol = target.columns[\"fact\"];\n const factDef = factCol !== undefined && \"_def\" in (factCol as object)\n ? (factCol as { _def: { type?: string } })._def\n : (factCol as { type?: string } | undefined);\n if (factDef === undefined || factDef.type !== \"text\") {\n throw new Error(`table ${name}: memory.into \"${m.into}\" tablosunda \"fact\" (text) kolonu zorunlu`);\n }\n for (const c of m.from) {\n if (!(c in (def as TableDef).columns)) {\n throw new Error(`table ${name}: memory.from kolonu \"${c}\" kaynak tabloda yok`);\n }\n }\n }\n // Dedupe + normalize extensions (order-independent; deploy resolves deps).\n const extensions = [...new Set(input.extensions ?? [])];\n // Declaring a schema is not the same as putting it on the internet, so\n // `exposed` is false unless the author says otherwise — EXCEPT for `public`,\n // which is reachable today and stays reachable. Making the default uniform\n // would silently 404 every existing project's /v1/db traffic on upgrade.\n return {\n name,\n tables: tables as TablesByName<T>,\n extensions,\n exposed: input.exposed ?? name === \"public\",\n };\n}\n\nexport { backfill, check, foreignKey, freeze, guard, toForeignKeyDef, toFreezeDef, toGuardDef };\nexport type { BackfillDef, CheckDef, ForeignKeyBuilder, ForeignKeyDef, FreezeBuilder, FreezeDef, GuardBuilder, GuardDef };\n\n/**\n * qualifyRefTargets, bir tablonun taşıdığı çapraz şema hedeflerini ŞEMASIYLA\n * niteler — ve şema bilinmiyorsa REDDEDER.\n *\n * `declaringSchemaOf` `defineSchema` tarafından damgalanıyor, yani bir hedefin\n * şeması ancak o tablo bir şemada bildirilmişse biliniyor. Bilinmiyorsa `public`\n * VARSAYMAK, kolon başına yolun adıyla kapattığı sessizliğin aynısı olurdu:\n * var olmayan bir tabloya ya da aynı adlı BAŞKA bir tabloya referans.\n */\nfunction qualifyRefTargets(table: TableDef, where: string): void {\n const qualify = (holder: { refTable?: string; table?: string }, what: string): void => {\n const target = (holder as { [REF_TARGET]?: TableDef })[REF_TARGET];\n if (target === undefined) return;\n const targetSchema = declaringSchemaOf.get(target);\n if (targetSchema === undefined) {\n throw new Error(\n `${where}: ${what} points at table \"${target.name}\", which no defineSchema(...) has claimed yet — ` +\n `a cross-table reference cannot be written without its target's schema. Declare that table's ` +\n `schema first (one file per schema: db/public.ts, db/billing.ts …, imported by this one).`,\n );\n }\n const qualified = qualifiedTableKey(targetSchema, target.name);\n if (holder.refTable !== undefined) holder.refTable = qualified;\n if (holder.table !== undefined) holder.table = qualified;\n };\n\n for (const fk of table.foreignKeys ?? []) qualify(fk, `foreignKey(\"${fk.name}\")`);\n for (const fz of table.freeze ?? []) qualify(fz, `freeze(\"${fz.name}\")`);\n for (const g of table.guards ?? []) {\n if (g.exists !== undefined) {\n qualifyExistsNodes(g.exists as Record<string, unknown>, `guard(\"${g.name}\").exists(...)`, where);\n }\n }\n}\n\n/** İç içe `exists` düğümlerini de niteler — yüklem başka bir tabloya bakabilir. */\nfunction qualifyExistsNodes(node: Record<string, unknown>, what: string, where: string): void {\n if (node === null || typeof node !== \"object\") return;\n if (node.kind === \"exists\") {\n const target = (node as { [REF_TARGET]?: TableDef })[REF_TARGET];\n if (target !== undefined) {\n const targetSchema = declaringSchemaOf.get(target);\n if (targetSchema === undefined) {\n throw new Error(\n `${where}: ${what} points at table \"${target.name}\", which no defineSchema(...) has claimed yet — ` +\n `a guard body is parsed at RUN TIME under a pinned search_path, so an unqualified name never resolves.`,\n );\n }\n node.table = qualifiedTableKey(targetSchema, target.name);\n }\n }\n for (const v of Object.values(node)) {\n if (Array.isArray(v)) {\n for (const e of v) qualifyExistsNodes(e as Record<string, unknown>, what, where);\n } else if (v !== null && typeof v === \"object\") {\n qualifyExistsNodes(v as Record<string, unknown>, what, where);\n }\n }\n}\n","/**\n * Postgres extensions a Palbase project can enable from its schema.\n *\n * Extensions are config-as-code: declare them in `defineSchema({ extensions })`\n * and the deploy installs them (CREATE EXTENSION … SCHEMA extensions) using the\n * deploy path's privileged connection. They are NOT toggled live from Studio —\n * CREATE EXTENSION requires a superuser role that only the deploy path holds.\n *\n * The list is an allowlist (a string-literal union) so editors autocomplete the\n * supported names and a typo fails typecheck. It is intentionally extensible:\n * add a name here (+ confirm the base image ships it) to support more.\n */\nexport const PALBASE_EXTENSIONS = [\n // Search & text\n \"vector\", // pgvector: AI embeddings + vector similarity search (semantic search / RAG).\n // NB: the Postgres extension is named \"vector\", not \"pgvector\" — declare \"vector\".\n \"pg_trgm\", // trigram fuzzy / typo-tolerant text search\n \"unaccent\", // accent-insensitive text search\n \"citext\", // case-insensitive text type\n // Geospatial / location\n \"cube\", // multi-dimensional cubes (dependency of earthdistance)\n \"earthdistance\", // great-circle distance (needs cube)\n // Data types & structures\n \"hstore\", // key/value pairs in a single column\n \"ltree\", // hierarchical tree-structured labels\n // Indexing & constraints\n \"btree_gist\", // GiST operator classes for scalar types — needed for EXCLUDE\n // constraints that mix \"=\" with a range/&& overlap (e.g. no-double-booking).\n // Scheduling\n // Crypto / ids (also installed by default; listable for explicitness)\n \"pgcrypto\", // cryptographic functions (hashing, encryption)\n \"uuid-ossp\", // UUID generation functions\n] as const;\n\n/** A Postgres extension supported by Palbase (allowlist union). */\nexport type PalbaseExtension = (typeof PALBASE_EXTENSIONS)[number];\n\n/**\n * Extensions that depend on another extension. The deploy installs\n * dependencies first; declaring `earthdistance` without `cube` still works\n * because the deploy resolves the order, but listing both is clearer.\n */\nexport const EXTENSION_DEPENDENCIES: Partial<Record<PalbaseExtension, PalbaseExtension[]>> = {\n earthdistance: [\"cube\"],\n};\n\n/** Runtime guard: is `name` a supported Palbase extension? */\nexport function isPalbaseExtension(name: string): name is PalbaseExtension {\n return (PALBASE_EXTENSIONS as readonly string[]).includes(name);\n}\n","/**\n * A named raw-SQL DDL object declared in a schema file (`db/public.ts`,\n * `db/billing.ts`, …) for what the typed DSL cannot express: an index method\n * other than btree (`gin`, `gist`, `brin`, `hash`), an opclass, `CONCURRENTLY`,\n * `EXCLUDE` constraints, views, and PL/pgSQL functions.\n *\n * REACH FOR THE TYPED FIELD FIRST. Most of what this list used to name is\n * declarative today and should not come through here:\n * - a CHECK constraint → `checks: [{ name, expr }]`, or the typed\n * `checks: (c) => [check(name, c.col(\"n\").gt(0))]`\n * - a partial index → `index(n).on(…).where(…)`\n * - an expression index → `index(n).onExpression(\"lower(email)\")`\n * - a covering index → `index(n).on(…).include([…])`\n * - a UNIQUE or PARTIAL UNIQUE index → `index(n).unique().where(…)`\n * - a composite FOREIGN KEY → `foreignKeys: (c) => [foreignKey(n).on(…).references(…)]`\n * - a conditional FK → `freeze: (c) => [freeze(n).when(…).columns(…).references(…)]`\n * - a trigger that refuses a write → `guards: (g) => [guard(n).on(…).refuse(…)]`\n * - a one-off data fix → `backfills: [backfill(name, sql)]`\n * - dropping a constraint → `dropConstraints: [\"name\"]`\n * Those are diffed, validated against the live database before the push, and\n * their mistakes answer you where you write them. A `raw()` is none of that.\n *\n * The deploy emits `up` verbatim on the privileged DDL connection — same trust\n * posture as policy().using(). How a CHANGED body is treated depends on what\n * `name` addresses:\n * - names a constraint or an index → tracked by NAME only; the deploy sees\n * the catalog object and skips, so an edited body does nothing. Use a new\n * name, or drop and re-add explicitly.\n * - names nothing in the catalog (functions, triggers, grants, compound\n * statements) → the last applied body is recorded in\n * `public.palbase_raw_objects` in the same DDL transaction, and an edited\n * body IS re-applied.\n *\n * There is no teardown option — not on the call, and not on this type. One used\n * to be accepted and was carried into a generated `Down` that NOTHING ever ran:\n * the engine's `MigrationFiles.Down` has no consumer and the rollback path names\n * a `runner.go` that does not exist, so an author who wrote one believed they had\n * a teardown they did not have. `raw()` stopped ACCEPTING it first, and the field\n * outlived the parameter — an object literal (`raw: [{ name, up, down }]`) still\n * compiled and still set a field nothing read. Drop what a `raw()` created by\n * declaring the drop as its own `raw()`.\n */\nexport interface RawConstraintDef {\n name: string;\n up: string;\n}\n\nexport function raw(name: string, up: string): RawConstraintDef {\n return { name, up };\n}\n","/** Embedding sağlayıcı DESKRIPTORU — canlı istemci değil, düz veri: şemayla\n * birlikte serileşir, çağrıyı Go worker (yazma) ve engine (sorgu) yapar.\n * Adlandırma Vercel AI SDK'nın aynasıdır (openai.embedding(\"...\")) ama paket\n * bağımlılığı bilinçli olarak YOKTUR (spec C-3, UD-016). v1 sağlayıcı: openai (D-10). */\nexport interface EmbeddingModelRef {\n provider: \"openai\";\n model: string;\n dimensions?: number;\n apiKeyName?: string;\n baseURL?: string;\n}\n/** Chat/damıtma modeli DESKRIPTORU (C-11, D-019) — memory beyanının extract'i.\n * Embedding gibi düz veridir; çağrıyı worker yapar, anahtar vault'taki\n * OPENAI_API_KEY'dir (D-017: aynı sağlayıcı, yeni dış sistem yok). */\nexport interface ChatModelRef {\n provider: \"openai\";\n model: string;\n}\nexport const openai = {\n embedding(\n model: string,\n opts?: { dimensions?: number; apiKeyName?: string; baseURL?: string },\n ): EmbeddingModelRef {\n return { provider: \"openai\", model, apiKeyName: opts?.apiKeyName ?? \"OPENAI_API_KEY\",\n ...(opts?.dimensions !== undefined ? { dimensions: opts.dimensions } : {}),\n ...(opts?.baseURL !== undefined ? { baseURL: opts.baseURL } : {}) };\n },\n chat(model: string): ChatModelRef {\n return { provider: \"openai\", model };\n },\n};\n","/**\n * typed-db.ts — Task 2: TypedDB schema-derived insert/row shapes.\n *\n * Derives INSERT and full-row TypeScript types from a `defineSchema()` result\n * and wraps the untyped runtime `DBClient` with a typed facade.\n *\n * No value-any. No `as unknown as X`. The two narrow `as` casts in\n * `makeTypedTable` are safe because:\n * - `data as Record<string, unknown>`: InsertShape<T> maps string keys to\n * typed values; all value types are subsets of `unknown`, so the cast is\n * structurally sound.\n * - `result as RowShape<T>`: The runtime DBClient returns `Record<string,\n * unknown>` which is the erased form of the typed row; we're narrowing back\n * to the precise shape that the schema declared.\n * Both casts are narrowing only (not widening) and correctness is guaranteed\n * by the schema the caller provides.\n */\n\nimport type { ColValue, ColIsOptionalOnInsert, ColumnBuilder } from \"./columns.js\";\nimport type { TableDef, SchemaDef } from \"./schema.js\";\nimport type { Tables, Schemas, TableTypes } from \"./env.js\";\nimport type { DBClient, DBOps, AtomicClient } from \"../endpoint.js\";\nimport type { RecoOps } from \"../runtime.js\";\nimport type { Materialized, TxPlanHandle, TxTable, TxColumnExpr, TxNow } from \"./tx-plan.js\";\nimport { TxPlanBuilder, runTxPlan } from \"./tx-plan.js\";\nimport { isColRef, brandRef } from \"./input-guards.js\";\nimport { isRetryable } from \"../errors.js\";\nimport { retryBudget, type AtomicOptions } from \"./transaction-options.js\";\nimport { qualifiedTableKey } from \"./schema-json.js\";\n\n// ---------------------------------------------------------------------------\n// Key discriminators — split a column map into required vs optional keys.\n// ---------------------------------------------------------------------------\n\n/** Keys of C whose columns are required on INSERT (not nullable, no default). */\ntype RequiredKeys<C> = {\n [K in keyof C]: ColIsOptionalOnInsert<C[K]> extends true ? never : K;\n}[keyof C];\n\n/** Keys of C whose columns are optional on INSERT (nullable or has a default). */\ntype OptionalKeys<C> = {\n [K in keyof C]: ColIsOptionalOnInsert<C[K]> extends true ? K : never;\n}[keyof C];\n\n// ---------------------------------------------------------------------------\n// Public shape types — exported so callers can reference them directly.\n// ---------------------------------------------------------------------------\n\n/**\n * The TypeScript type for an INSERT payload for table `T`.\n * - Required: columns that are NOT NULL and have no DB-level default.\n * - Optional: columns that are nullable or carry a default.\n *\n * When all columns are optional, `RequiredKeys<C>` resolves to `never` and\n * the first part becomes `{}`, which is a neutral element for `&`.\n */\nexport type InsertShape<T extends TableDef> = {\n [K in RequiredKeys<T[\"columns\"]>]: ColValue<T[\"columns\"][K]>;\n} & {\n [K in OptionalKeys<T[\"columns\"]>]?: ColValue<T[\"columns\"][K]>;\n};\n\n/**\n * The TypeScript type for a full row returned by the DB for table `T`.\n * Every column is present; nullable columns resolve to `T | null`.\n */\nexport type RowShape<T extends TableDef> = {\n [K in keyof T[\"columns\"]]: ColValue<T[\"columns\"][K]>;\n};\n\n// ---------------------------------------------------------------------------\n// TypedTable + TypedDB interfaces.\n// ---------------------------------------------------------------------------\n\n/** A typed table accessor that mirrors the runtime DBClient surface. */\nexport interface TypedTable<T extends TableDef> {\n /** Runtime validates the key against the installed schema. Generated env tables\n * also check the complete unique/composite key at compile time. */\n findUnique<K extends keyof RowShape<T> = keyof RowShape<T>>(q: {\n where: Partial<RowShape<T>>; select?: readonly K[];\n }): Promise<Pick<RowShape<T>, K> | null>;\n page<K extends keyof RowShape<T> = keyof RowShape<T>>(\n q?: PageInput<RowShape<T>, K>,\n ): Promise<import(\"./page.js\").Page<Pick<RowShape<T>, K>>>;\n insert(data: InsertValues<InsertShape<T>>): Promise<RowShape<T>>;\n /** Çok satır, TEK statement. Satırların anahtar kümesi aynı olmalı. */\n insertMany(rows: readonly InsertValues<InsertShape<T>>[], opts: import(\"./bulk.js\").InsertManyOptions & { returning: false }): Promise<number>;\n insertMany(rows: readonly InsertValues<InsertShape<T>>[], opts?: import(\"./bulk.js\").InsertManyOptions & { returning?: true }): Promise<RowShape<T>[]>;\n insertMany(rows: readonly InsertValues<InsertShape<T>>[], opts?: import(\"./bulk.js\").InsertManyOptions): Promise<RowShape<T>[] | number>;\n put(q: { data: InsertShape<T>; onConflict: readonly string[] }): Promise<RowShape<T>>;\n /** Update the row by id; resolves to the updated row, or `null` if no row\n * matched (absent or RLS-hidden) — an idempotent outcome, mirroring\n * `findById`. The runtime returns a null row rather than throwing. */\n update(q: { where: { id: string }; set: SetShape<InsertShape<T>> }): Promise<RowShape<T> | null>;\n delete(id: string): Promise<void>;\n findById(id: string): Promise<RowShape<T> | null>;\n /** Rows matching the filter. Operators, ordering and paging are the ENGINE's\n * surface — this declaration is what makes them callable. */\n findMany<K extends keyof RowShape<T> = keyof RowShape<T>>(\n q?: QueryInput<RowShape<T>, K>,\n ): Promise<Pick<RowShape<T>, K>[]>;\n /**\n * Update every matching row in one statement; an empty filter is refused.\n *\n * **0 satır dönmesi hata DEĞİL, başarı da değil** (FR-014): koşulu `where`'e\n * koyup dönen diziyi kontrol etmek, \"önce oku sonra yaz\"ın yarış koşulu\n * olmayan hâlidir.\n *\n * ```ts\n * const [row] = await Database.public.accounts.updateMany({\n * where: { id, balance: { gte: amount } },\n * set: { balance: decrement(amount) },\n * });\n * if (row === undefined) throw new Conflict(\"yetersiz bakiye\");\n * ```\n */\n updateMany<const Q extends MutateInput<RowShape<T>, InsertShape<T>>>(\n q: Q,\n ): Promise<Q extends { returning: false } ? number : RowShape<T>[]>;\n /** Delete every matching row; resolves to how many. Empty filter refused. */\n deleteMany(q: { where: WhereFilter<RowShape<T>> | SqlFragment }): Promise<number>;\n /**\n * Toplama — `sum` / `avg` / `min` / `max` / `count`, isteğe bağlı `groupBy`.\n *\n * ```ts\n * const r = await Database.public.entries.aggregate({\n * where: { account_id },\n * sum: [\"amount_kurus\"],\n * count: true,\n * });\n * r.sum.amount_kurus; // string | null — KAYIPSIZ\n * r.count; // number\n * ```\n *\n * `sum`/`avg` yalnız sayısal kolonlarda ve HER ZAMAN `string` döner: para JS\n * `number`'ına uğradığı anda kesinliğini kaybeder. `| null` çünkü Postgres\n * boş kümede NULL döndürür — \"hiç satır yoktu\" ile \"toplam sıfırdı\" farklı.\n *\n * `groupBy` verilirse dönüş bir DİZİ ve her satır grup kolonlarını taşır.\n */\n aggregate<const Q extends AggregateInput<RowShape<T>>>(\n q: Q,\n ): Promise<AggregateResult<Q, RowShape<T>>>;\n /** How many rows match. An empty filter is legitimate: counting is a read. */\n count(q?: { where?: WhereFilter<RowShape<T>> | SqlFragment }): Promise<number>;\n}\n\n/** A typed DB facade covering all tables declared in schema `S`. */\nexport interface TypedDB<S extends SchemaDef> {\n diagnostics: DBOps[\"diagnostics\"];\n command<T>(fn: (tx: TypedTx<S>) => T extends Promise<unknown> ? never : T, options?: import(\"./command.js\").CommandOptions): Promise<Materialized<T>>;\n tables: {\n [K in keyof S[\"tables\"]]: TypedTable<S[\"tables\"][K]>;\n };\n /** Run a transaction plan. See {@link EnvTypedDatabase.transaction}. */\n transaction<T>(\n fn: (tx: TypedTx<S>) => T extends Promise<unknown> ? never : T,\n ): Promise<Materialized<T>>;\n}\n\n/** The plan-building handle a `TypedDB<S>` transaction callback receives: the\n * schema's tables, expressed as plan operations rather than awaited calls.\n *\n * YALNIZ `tables`, ve ÇALIŞMA ZAMANI DA yalnız onu veriyor.\n *\n * Bir süre runtime `{ tables, public }` döndürüyordu ama tip yalnız `tables`\n * söylüyordu: `tx.public.x` derlenmiyor, koşsaydı çalışacaktı — tipin çalışma\n * zamanından AZ söylemesi (gözcü M-8). Tipe `public` EKLEMEK yanlış düzeltmeydi\n * ve `check:api` onu adıyla reddetti: `TypedTx` dışa açık, ve zorunlu bir üye\n * eklemek onu İNŞA EDEN müşterinin kodunu kırar — \"the new shape demands more\n * than the recorded one\". Yalan runtime'dan kaldırılarak kapatıldı; ikisi artık\n * aynı şeyi söylüyor. `Database.$transaction`'ın `tx.public`'i ayrı bir yüzey\n * (`TxPlan`) ve orada tip de runtime da onu taşıyor. */\nexport type TypedTx<S extends SchemaDef> = TxPlanHandle<{\n [K in keyof S[\"tables\"]]: TxTable<RowShape<S[\"tables\"][K]>, InsertShape<S[\"tables\"][K]>>;\n}>;\n\n// ---------------------------------------------------------------------------\n// Runtime factory.\n// ---------------------------------------------------------------------------\n\n/**\n * Builds a typed table accessor that delegates every call to `raw` using the\n * runtime table name string. Two narrow `as` casts bridge the mapped-type\n * shapes to/from `Record<string, unknown>` — see module-level doc comment.\n *\n * The `raw` param is typed `DBOps` (the six string-keyed ops) because this only\n * ever calls those — never `txPlan`, which builds its own operations rather than\n * delegating to these.\n */\nfunction makeTypedTable<T extends TableDef<Record<string, ColumnBuilder>>>(\n name: string,\n raw: DBOps,\n): TypedTable<T> {\n return {\n insert: (data: InsertShape<T>) =>\n raw.insert(name, data as Record<string, unknown>) as Promise<RowShape<T>>,\n\n aggregate: ((q: Record<string, unknown>) =>\n raw.aggregate(name, q)) as TypedTable<T>[\"aggregate\"],\n\n insertMany: ((rows: readonly InsertValues<InsertShape<T>>[], opts?: import(\"./bulk.js\").InsertManyOptions) =>\n raw.insertMany(name, rows as readonly Record<string, unknown>[], opts)) as TypedTable<T>[\"insertMany\"],\n\n put: (q: { data: InsertShape<T>; onConflict: readonly string[] }) =>\n raw.put(name, q.data as Record<string, unknown>, { onConflict: q.onConflict }) as Promise<RowShape<T>>,\n\n update: (q: { where: { id: string }; set: Partial<InsertShape<T>> }) =>\n raw.update(name, q.where.id, q.set as Record<string, unknown>) as Promise<RowShape<T> | null>,\n\n delete: (id: string) => raw.delete(name, id),\n\n findUnique: ((q: { where: Record<string, unknown>; select?: readonly string[] }) =>\n raw.findUnique(name, q.where, { select: q.select })) as TypedTable<T>[\"findUnique\"],\n findById: (id: string) =>\n raw.findById(name, id) as Promise<RowShape<T> | null>,\n\n page: (q?: PageInput<RowShape<T>>) => {\n const { where, ...opts } = q ?? {};\n return raw.page(name, where as Record<string, unknown> | undefined, opts as import(\"./page.js\").RawPageOptions) as Promise<import(\"./page.js\").Page<RowShape<T>>>;\n },\n findMany: (q?: QueryInput<RowShape<T>>) => {\n // `where` AYIKLANIR: kalan alanlar (orderBy/limit/offset) opts'a gider.\n // Tümünü opts diye geçirmek `where`'i tel üstünde İKİ KEZ gönderirdi.\n const { where, ...opts } = q ?? {};\n return raw.findMany(\n name,\n where as Record<string, unknown> | undefined,\n opts as Parameters<typeof raw.findMany>[2],\n ) as Promise<RowShape<T>[]>;\n },\n\n updateMany: ((q: MutateInput<RowShape<T>, InsertShape<T>>) =>\n raw.updateMany(\n name,\n q.where as Record<string, unknown>,\n q.set as Record<string, unknown>,\n q.returning === undefined ? undefined : { returning: q.returning },\n )) as TypedTable<T>[\"updateMany\"],\n\n deleteMany: (q: { where: WhereFilter<RowShape<T>> | SqlFragment }) =>\n raw.deleteMany(name, q.where as Record<string, unknown>),\n\n count: (q?: { where?: WhereFilter<RowShape<T>> }) =>\n raw.count(name, q?.where as Record<string, unknown> | undefined),\n };\n}\n\n/**\n * Wraps a raw `DBClient` with the type-safe `TypedDB<S>` facade derived from\n * the provided schema. No behavior change for the direct ops — all calls\n * delegate to `raw` with the table name as a plain string.\n *\n * `transaction` does NOT delegate to a per-op client: the callback describes a\n * plan against a fresh {@link TxPlanBuilder}, and the whole plan travels in one\n * `raw.txPlan` call. The schema is used only for its table NAMES; the values\n * are typed by `S` at compile time and are plain strings at run time.\n *\n * The `as` casts are single structural narrowings from a dynamically-built\n * object to the precise mapped type (TS cannot infer the mapped-type result\n * through `Object.keys` iteration) — see the module-level doc comment.\n */\nexport function makeTypedDB<S extends SchemaDef>(\n schema: S,\n raw: AtomicClient,\n): TypedDB<S> {\n const tables = {} as Record<string, TypedTable<TableDef>>;\n for (const key of Object.keys(schema.tables)) {\n const tableDef = schema.tables[key];\n if (tableDef !== undefined) {\n tables[key] = makeTypedTable(qualifiedTableKey(schema.name, tableDef.name), raw);\n }\n }\n\n const result = {\n tables,\n diagnostics: () => raw.diagnostics(),\n command<T>(fn: (tx: TypedTx<S>) => T extends Promise<unknown> ? never : T, options?: import(\"./command.js\").CommandOptions): Promise<Materialized<T>> {\n const builder = new TxPlanBuilder();\n const planTables = Object.fromEntries(Object.entries(schema.tables).map(([key, table]) => [key, builder.table(qualifiedTableKey(schema.name, table.name))]));\n return runTxPlan({ txPlan: plan => raw.command(plan, options) }, { tables: planTables } as TypedTx<S>, builder, fn) as Promise<Materialized<T>>;\n },\n transaction<T>(\n fn: (tx: TypedTx<S>) => T extends Promise<unknown> ? never : T,\n ): Promise<Materialized<T>> {\n const builder = new TxPlanBuilder();\n const planTables: Record<string, unknown> = {};\n for (const key of Object.keys(schema.tables)) {\n const tableDef = schema.tables[key];\n if (tableDef !== undefined) planTables[key] = builder.table(qualifiedTableKey(schema.name, tableDef.name));\n }\n // Two narrowings at the same seam: the plan tables are built by NAME, so\n // TS cannot see the mapped type through the loop, and the driver erases\n // the callback's return type (see runTxPlan's doc). Both are the erasure\n // this facade exists to undo.\n // `runTxPlan` artık TUTAMAĞIN TAMAMINI alıyor (şema yüzeyi dahil).\n //\n // Burada tutamak YALNIZ `tables` taşıyor, çünkü `TypedTx<S>` de yalnız\n // onu söylüyor. Bir ara `public`'i de veriyordu ve tip onu bilmiyordu —\n // çalışma zamanının tipten FAZLA sunması da bir yalan. `makeTypedDB` tek\n // şemalı bir cephe; çok şemalı yüzey `Database.$transaction`.\n return runTxPlan(\n raw,\n { tables: planTables } as TypedTx<S>,\n builder,\n fn,\n ) as Promise<Materialized<T>>;\n },\n };\n\n // Narrow cast: `result.tables` is structurally identical to\n // TypedDB<S>[\"tables\"] — each key maps to a TypedTable for the matching\n // TableDef. TS cannot infer the mapped-type result through Object.keys\n // iteration, so a single `as` bridges the gap.\n return result as TypedDB<S>;\n}\n\n// ---------------------------------------------------------------------------\n// Env-augmentation-driven typed surface — the typed-by-default `Database`.\n//\n// These types read the globally-augmented `Tables` interface from\n// `@palbase/backend/env` (filled by the generated `palbase-env.d.ts`). They\n// back `Database.public.<name>` so handler code is typed with no import and no\n// generic (C5). They DELIBERATELY do not reference `ColumnBuilder` — the env\n// `Tables` interface carries flat `row`/`insert` object types.\n// ---------------------------------------------------------------------------\n\n/** Bir where değeri: düz eşitlik YA DA operatör nesnesi (FR-016). */\n/**\n * Metin operatörleri YALNIZ metin kolonlarında görünür (FR-005).\n *\n * `contains` bir sayı kolonunda anlamsızdır ve onu tipte sunmak \"ifade edilemez\n * kıl\" ilkesinin tersidir: derleme anında yakalanabilecek bir hata çalışma\n * zamanına ertelenir. Koşullu tip ÖZYİNELEMESİZDİR (N-2).\n */\n/**\n * Bir KOLONA yapılan referans (FR-011) — karşılaştırmanın sağ tarafında değer\n * yerine durabilen tek şey.\n *\n * Şekli okunabilir (`{ $col: \"…\" }`) ama KİMLİĞİ şekli değil: nesne\n * `Symbol.for(\"palbase.db.ref\")` ile markalanır. Şekil tek başına yetseydi\n * güvenilmeyen bir istek gövdesi `{\"$col\":\"tenant_id\"}` gönderip kiracılık\n * predikatını `t.\"tenant_id\" = t.\"tenant_id\"` totolojisine çevirebilirdi —\n * ölçüldü (W2-A/C1). Marka enumerable olmadığı için JSON round-trip'i onu\n * düşürür; süreç içinde (transaction planı dahil) korunur.\n */\nexport type ColRef<N extends string = string> = { readonly $col: N };\n\nexport { isColRef };\n\n/**\n * `total > amount_paid` — bugün bunu yazmanın tek yolu ham SQL'e düşmekti,\n * çünkü sağ taraf bir DEĞER değil.\n *\n * Ad literal olarak yakalanır (`const N`), ve doğruluğu ÇAĞRIDA değil\n * KULLANIM YERİNDE kanıtlanır: filtre `WhereFilter<Row>` beklediği için\n * `ColRef<\"yok_boyle\">` oraya atanamaz. Yani `col()`'a satır tipini elle\n * vermek gerekmiyor, yanlış ad yine de derleme hatası (P5).\n *\n * Dönen nesne MARKALIDIR (`brandRef`): telden gelen `{\"$col\":\"x\"}` bir kolon\n * referansı SAYILMAZ, \"bilinmeyen operatör\" diye reddedilir. Gerekçe\n * `db/input-guards.ts`'te ölçümüyle birlikte yazılı.\n */\nexport function col<const N extends string>(name: N): ColRef<N> {\n return brandRef({ $col: name }, \"col\");\n}\n\n/** Bu satırın kolonlarından birine referans. `Row` bilinmiyorsa hiçbiri. */\n/**\n * Bir kolonun karşılaştırma AİLESİ — ve neden PG tipi değil de bu.\n *\n * ÖLÇÜLDÜ (gözcü, canlı pg16): TS tarafı PG tipini TAŞIMIYOR. `numeric`,\n * `bigint`, `text`, `uuid` ve `timestamp` hepsi `string`'e, `integer` `number`'a\n * düşüyor (`env-gen.ts:30-60`). Bu yüzden TS tipine kurulan HİÇBİR kural doğru\n * olamaz — kural ne olursa olsun bir taraf yanlışa düşer:\n *\n * { qty: { gt: col(\"amount\") } } integer ↔ numeric PG: GEÇERLİ\n * { total: { gt: col(\"note\") } } integer ↔ text PG: GEÇERSİZ\n *\n * İkisi de TS'te \"number ↔ string\". Ayırt edecek bilgi tipte YOK.\n *\n * YANLIŞ RET, YANLIŞ KABULDEN KÖTÜDÜR — ve tercih buna göre yapıldı. Yanlış bir\n * ret meşru bir sorguyu İFADE EDİLEMEZ kılar, yani yazarı `$query`'ye düşürür:\n * bu yüzeyin kapatmak için var olduğu şey. Yanlış bir kabul ise Postgres'in\n * GÜRÜLTÜLÜ hatasına çıkar (`operator does not exist: integer > text`) — kötü\n * ama sessiz değil.\n *\n * O yüzden aile ayrımı yalnız TS'in GERÇEKTEN ayırdığı yerlerde yapılıyor:\n * `boolean`, vektör dizisi ve `Date` kendi başlarına; metin ve sayı ise TEK\n * ailede, çünkü aralarındaki PG ayrımı tipte yok.\n *\n * KALICI ÇÖZÜM tipte değil ÜRETİMDE: `env-gen` kolon başına bir PG-tip markası\n * bassın (`string & { readonly __pg?: \"numeric\" }`). O zaman `numeric ↔ integer`\n * kabul, `numeric ↔ text` ret olur ve ikisi de DOĞRU olur. Defterde teklif.\n */\ntype PgFamily<V> = [NonNullable<V>] extends [boolean]\n ? \"bool\"\n : [NonNullable<V>] extends [readonly (number | string)[]]\n ? \"array\"\n : [NonNullable<V>] extends [Date]\n ? \"date\"\n : [NonNullable<V>] extends [string | number]\n ? \"scalar\"\n : \"opaque\";\n\n/**\n * Kolonun BİLDİRİLMİŞ Postgres tipi — `env-gen`'in bastığı markadan.\n *\n * Marka yoksa `\"?\"`: elle yazılmış bir `Tables` (testler) ya da yeniden\n * üretilmemiş bir `palbase-env.d.ts`. O durumda eski TS-tipi sezgiseline\n * düşülüyor, çünkü marka olmadan söylenebilecek daha doğru bir şey yok.\n */\ntype PgTag<V> = [NonNullable<V>] extends [{ readonly __pg?: infer N }]\n ? [N] extends [string]\n ? N\n : \"?\"\n : \"?\";\n\n/**\n * Postgres'te birbirleriyle karşılaştırılabilen tipler tek \"cins\".\n *\n * `integer`, `bigint` ve `numeric` örtük sayısal dönüşümle karşılaştırılır;\n * geri kalan her tip yalnız kendisiyle. `uuid ↔ text` ve `enum ↔ text`\n * Postgres'te `operator does not exist` verir — D-021'de CANLI ölçülmüştü ve\n * tip bunu göremediği için kabul ediyordu.\n */\ntype PgKind<P> = P extends \"integer\" | \"bigint\" | \"numeric\" ? \"num\" : P;\n\n/** İki tarafın da markası var mı — yoksa sezgisele düşülür. */\ntype BothBranded<A, B> = \"?\" extends PgTag<A> ? false : \"?\" extends PgTag<B> ? false : true;\n\ntype PgSameKind<A, B> = [PgKind<PgTag<A>>] extends [PgKind<PgTag<B>>]\n ? [PgKind<PgTag<B>>] extends [PgKind<PgTag<A>>]\n ? true\n : false\n : false;\n\n/**\n * `A` kolonu `B` ile karşılaştırılabilir mi.\n *\n * Marka varsa CEVAP KESİN: ne yanlış ret ne yanlış kabul. D-021 bu kuralı\n * \"doğru olamaz\" diye kaydetmişti çünkü tipte ayırt edecek bilgi yoktu; bilgi\n * artık tipte.\n */\ntype ColComparable<A, B> = BothBranded<A, B> extends true\n ? PgSameKind<A, B>\n : [PgFamily<A>] extends [PgFamily<B>]\n ? true\n : false;\n\n/** `Row`'un `V` ile karşılaştırılabilir kolonları. */\ntype ColumnsComparableTo<Row, V> = {\n [K in keyof Row]-?: ColComparable<Row[K], V> extends true ? K : never;\n}[keyof Row];\n\n/**\n * Bu satırın kolonlarından birine referans. `Row` bilinmiyorsa hiçbiri.\n *\n * İKİNCİ PARAMETRE kolonun tipi. Verilmezse (`unknown`) KISIT YOKTUR — bu\n * `findMany`'nin `Row`'u bilmediği yolların ve jsonb kolonlarının hâli, ve\n * ikisinde de tipin söyleyebileceği bir şey yok.\n */\n/**\n * \"Kısıt verilmedi\" için AYRI bir işaret — `unknown` DEĞİL.\n *\n * Eskiden varsayılan `unknown`'dı ve dal `[unknown] extends [V]` ile\n * seçiliyordu. Ama `jsonb` kolonlarının DEĞER TİPİ de `unknown`: yani gerçek\n * bir jsonb kolonu \"kısıt verilmedi\" sanılıp TÜM kolonlarla karşılaştırılabilir\n * hâle geliyordu. D-021 bunu \"jsonb ↔ text derleniyor\" diye kaydetmişti ve PG\n * markası tek başına kapatmadı — `unknown & X` kesişimi `X`'e çöktüğü için\n * jsonb markalanamıyor (markalamak kolonu daraltıp meşru yazmaları kırdı,\n * gerçek projede ölçüldü).\n *\n * Ayrı bir işaretle iki durum artık ayrışıyor: kısıtsız yol kısıtsız kalıyor,\n * jsonb ise KENDİ ailesine düşüyor — yani yalnız başka bir jsonb ile\n * karşılaştırılabiliyor.\n */\ndeclare const NO_CONSTRAINT: unique symbol;\nexport type NoColConstraint = { readonly [NO_CONSTRAINT]: true };\n\nexport type ColRefOf<Row, V = NoColConstraint> = [keyof Row] extends [never]\n ? never\n : [V] extends [NoColConstraint]\n ? ColRef<Extract<keyof Row, string>>\n : ColRef<Extract<ColumnsComparableTo<Row, V>, string>>;\n\n/**\n * Doğrulanmış, GÖMÜLEBİLİR bir SQL parçası (FR-018, FR-019).\n *\n * Wire şekli `{ $sql: { text, values } }`: `text` parçalar hâlinde tutulur ve\n * değerler ARADA durur, çünkü birleştirilmiş tek bir string'in içinden hangi\n * kısmın kullanıcı verisi olduğunu bir daha kimse çıkaramaz — enjeksiyonun\n * doğduğu yer tam olarak orasıdır.\n */\nexport type SqlFragment = {\n readonly $sql: { readonly text: readonly string[]; readonly values: readonly unknown[] };\n};\n\n/**\n * Retryable bir hatada işlemi yeniden dener (FR-037).\n *\n * `fn` must open and settle a NEW transaction on each invocation. Repeating\n * a savepoint retains the old snapshot and cannot retry a failed COMMIT.\n * Database.$atomic owns that boundary for ordinary application code.\n *\n * VARSAYILAN SIFIR. Sessiz bir varsayılan retry, idempotent OLMAYAN bir işlemi\n * çağıranın haberi olmadan iki kez çalıştırırdı — bir para transferini iki kez.\n * Tekrar denemek çağıranın kararı.\n *\n * Yalnız `isRetryable(e)` olan hatalar tekrarlanır. Küme dar tutuluyor: `23505`\n * buraya girseydi tekrar denemek aynı cevabı verir ve döngü boşuna dönerdi.\n */\nexport async function withRetry<T>(\n fn: () => Promise<T>,\n opts: { retry?: number } = {},\n): Promise<T> {\n const budget = retryBudget(opts.retry);\n let attempt = 0;\n for (;;) {\n try {\n return await fn();\n } catch (e) {\n // Bütçe bittiğinde SON hata fırlatılıyor, sarmalanmıyor: çağıranın\n // gördüğü şey Postgres'in söylediği şey olsun.\n if (attempt >= budget || !isRetryable(e)) throw e;\n attempt += 1;\n }\n }\n}\n\n/**\n * K3: sorgudan KAÇMAK için değil, sorgunun İÇİNE girmek için kaçış kapağı.\n *\n * ```ts\n * Database.public.notes.findMany({\n * where: sqlFragment`similarity(title, ${q}) > 0.3`,\n * orderBy: { column: \"created_at\", direction: \"desc\" },\n * limit: 20,\n * })\n * ```\n *\n * `select` / `orderBy` / `limit` / RLS aynen çalışmaya devam eder — \"yetmedi,\n * ham SQL'e geçeyim\" anının bugünkü maliyeti tam olarak bunları kaybetmekti.\n *\n * TANIMLAYICI GÖMME YÜZEYİ YOK (`.raw` / `.unsafe` / `.identifier`). Drizzle'ın\n * CVE-2026-39356'sı ve Knex'in CVE-2019-10757'si tam o kapakta doğdu.\n *\n * Ve kapak fonksiyonun ÜSTÜNDE olmakla bitmiyordu: parça MARKALI değilken\n * `{\"$sql\":{\"text\":[\"1=1 -- pwned\"],\"values\":[]}}` düz JSON'dan uydurulup\n * guard'ın tamamını atlıyordu (W2-B/C3, ölçüldü). Marka o kapağı wire ŞEKLİNE\n * de koyuyor — parça yalnız bu template tag'inden çıkabilir.\n */\nexport function sqlFragment(\n strings: TemplateStringsArray,\n ...values: unknown[]\n): SqlFragment {\n return brandRef({ $sql: { text: [...strings], values } }, \"sql\");\n}\n\nexport type TextOps<V> = V extends string\n ? { contains?: string; icontains?: string; startsWith?: string; endsWith?: string }\n : { contains?: never; icontains?: never; startsWith?: never; endsWith?: never };\n\n/** Operatör gövdesi, kolon-referans tipi DIŞARIDAN verilmiş hâliyle.\n *\n * `C` bir parametre, çünkü `ColRefOf<Row, V>` aksi hâlde altı operatör\n * konumunda AYRI AYRI instantiate edilirdi — kolon başına altı mapped type.\n * Böyle kolon başına BİR tane (N-2). */\n/**\n * `now()` HANGİ kolonlarda karşılaştırma değeri olabilir.\n *\n * `timestamp` TypeScript'e `string` olarak geliyor — `text` ile aynı tip. Yani\n * \"yalnız zaman kolonları\" tip düzeyinde İFADE EDİLEMEZ (D-021'in tam olarak\n * kaydettiği sınır: TS numeric/bigint/text/uuid/timestamp'ı `string`'e\n * çöktürüyor). İki seçenekten yanlış KABUL, yanlış RET'e tercih ediliyor:\n * `now()`'ı bir metin kolonunda yazmak Postgres hatası verir, ama zaman\n * kolonunda YASAKLAMAK yazarı bu yüzden `sqlFragment`e düşürürdü — ve bu\n * özelliğin var olma nedeni tam olarak o düşüşü kaldırmak.\n */\ntype NowComparable<V> = \"?\" extends PgTag<V>\n ? [NonNullable<V>] extends [string | Date]\n ? TxNow\n : never\n : PgTag<V> extends \"timestamp\"\n ? TxNow\n : never;\n\ntype WhereOpBody<V, C> = {\n gt?: V | C | NowComparable<V>;\n gte?: V | C | NowComparable<V>;\n lt?: V | C | NowComparable<V>;\n lte?: V | C | NowComparable<V>;\n neq?: V | C | NowComparable<V>;\n in?: V[];\n /** `IS NULL` / `IS NOT NULL` (FR-006) — `= NULL` SQL'de her zaman UNKNOWN'dır. */\n isNull?: boolean;\n} & TextOps<V>;\n\nexport type WhereOp<V, Row = unknown> = WhereOpWith<V, ColRefOf<Row, V>>;\n\n/**\n * Operatör sözlüğü, kolon-referans/plan-tutamağı konumu DIŞARIDAN verilmiş.\n *\n * `export`, çünkü plan yüzeyi (`tx-plan.ts`) aynı sözlüğü `C = ColRefOf<…> |\n * Ref<…>` ile kuruyor: bir plan filtresi ÖNCEKİ bir işlemin sonucuna\n * bakabiliyor, `findMany` bakamıyor. Ref'i `V`'ye eklemek YANLIŞ olurdu —\n * `TextOps<V>` `V extends string` diye soruyor ve `string | Ref<string>` o\n * soruya HAYIR der, yani `contains`/`startsWith` sessizce KAYBOLURDU.\n */\nexport type WhereOpWith<V, C> = V | C | NowComparable<V> | WhereOpBody<V, C>;\n\n/**\n * A filter over a row: every field optional, each one a plain value (equality)\n * or an operator object. THE filter language — `findMany`, `updateMany`,\n * `deleteMany` and `count` all take this one, because two spellings of a filter\n * is how the two come to disagree.\n */\nexport type WhereFilter<Row> = { [K in keyof Row]?: WhereOp<Row[K], Row> } & {\n /**\n * Boolean bileşimi (FR-007). Dallar aynı filtre dilidir — iki yazım olmaz.\n *\n * ÖZYİNELEME BURADA BAŞLIYOR ve N-2'nin izlediği şey tam olarak budur:\n * Kysely'nin TS7'de 9,8M instantiation üreten vakası derin generic\n * özyinelemeydi. Burada derinlik yazarın filtresi kadardır ve pratikte\n * bir-iki seviyedir; tip maliyeti T001'in tavanına karşı ölçülür.\n *\n * Dal bir `sqlFragment` DE olabilir. Motor bunu zaten derliyordu — parantezli\n * ve parametreli (`… AND (((expires_at > now())) AND (t.\"city\" = $2))`) —\n * ama tip yalnız üst düzey `where`'de fragment'e izin veriyordu. Yani\n * \"fragment sorgudan KAÇMAK için değil, sorgunun İÇİNE girmek için\" sözü tam\n * da bileşim anında kırılıyordu: bir koşulu bir fragment'le birleştirmek\n * isteyen yazar SORGUNUN TAMAMINI ham SQL'e taşımak zorunda kalıyordu.\n * Ölçüldü: bir müşteri sorgusunda tam olarak bu oldu.\n */\n OR?: (WhereFilter<Row> | SqlFragment)[];\n AND?: (WhereFilter<Row> | SqlFragment)[];\n NOT?: WhereFilter<Row> | SqlFragment;\n};\n\n/**\n * Ordering and paging for a read.\n *\n * `column` is `keyof Row`, not `string`: a mistyped column name is a compile\n * error here rather than a runtime rejection three layers down. `offset`\n * without `limit` is refused by the engine — a page with no size is not a page.\n */\nexport type OrderBySpec<Row> = {\n column: Extract<keyof Row, string>;\n direction?: \"asc\" | \"desc\";\n /** NULL'ların yeri (FR-008). Verilmezse Postgres varsayılanı geçerlidir ve o\n * varsayılan YÖNE GÖRE DEĞİŞİR: ASC'de NULLS LAST, DESC'te NULLS FIRST. */\n nulls?: \"first\" | \"last\";\n};\n\nexport type FindManyOpts<Row> = {\n /** Tek sıralama ya da SIRALI liste — sıra korunur (FR-008). */\n orderBy?: OrderBySpec<Row> | OrderBySpec<Row>[];\n limit?: number;\n offset?: number;\n};\n\n/**\n * Bir okumanın TEK parametresi (FR-004b).\n *\n * `where` bir ALAN, konumsal bir argüman değil. Kullanıcının kararı: \"deterministik\n * olması lazım, tek düzlem\" — aynı bilginin iki yere dağılması, alanlar çoğaldıkça\n * (select/include/orderBy) \"hangisi nereye\" sorusunu ezberlenecek bir şeye çevirir.\n * Prisma ve Drizzle de tek obje kullanıyor. Bedeli açık ve kabul edildi: en sık\n * kullanım uzuyor — `findMany({ where: { owner: uid } })`.\n *\n * ÖZYİNELEMESİZ kalmak zorunda (N-2): tip maliyeti şekilden değil özyineleme\n * derinliğinden geliyor (Kysely'nin TS7'de 9,8M instantiation vakası).\n */\n/**\n * `has` — İLİŞKİ ÜZERİNDEN SÜZME, JOIN'in ihtiyaç duyulmayan hâli.\n *\n * ```ts\n * Database.public.interests.findMany({\n * where: { has: { user_interests: { user_id: uid } } },\n * orderBy: [{ column: \"sort_order\" }, { column: \"name\" }],\n * })\n * ```\n * → `… WHERE t.\"id\" IN (SELECT r1.\"interest_id\" FROM \"user_interests\" r1\n * WHERE r1.\"user_id\" = $1)`\n *\n * İlişki ADLARI ve gittikleri kolonlar `palbase-env.d.ts`'in ZATEN bastığı\n * `relations` bloğundan geliyor — yabancı anahtarlardan türetiliyorlar, yazar\n * hiçbir kolon adı yazmıyor. O blok üretiliyordu ve HİÇBİR okuma onu\n * kullanmıyordu; `has` onun karşılığı.\n *\n * İç filtre AYNI dil: bir tablo ötesinde de `gt`, `icontains`, `OR`, ve iç içe\n * `has` yazılabiliyor.\n */\n/**\n * İlişkinin HEDEF TABLOSU — anahtar ŞEMA NİTELİKLİ gelir.\n *\n * `buildRelations` `to`'yu `qualifiedTableKey` ile yazıyor: public için düz ad\n * (`\"interests\"`), başka şema için noktalı (`\"billing.invoices\"`). `Tables`\n * yalnız public'i taşır, diğerleri `Schemas`'tadır — noktalı anahtarı doğrudan\n * `Tables`'ta aramak HER ZAMAN ıskalar ve iç filtre sessizce `Record<string,\n * unknown>`'a düşerdi: bilinmeyen kolon da, yanlış tip de derlenirdi (ölçüldü).\n */\ntype RelatedTable<To> = To extends `${infer S}.${infer T}`\n ? S extends keyof Schemas\n ? T extends keyof Schemas[S]\n ? Schemas[S][T]\n : never\n : never\n : To extends keyof Tables\n ? Tables[To]\n : never;\n\ntype RelatedRow<To> = RelatedTable<To> extends { row: infer R } ? R : Record<string, unknown>;\ntype RelatedRels<To> = RelatedTable<To> extends { relations: infer R } ? R : unknown;\n\n/**\n * İç içe `has` ÜÇ seviyeyle sınırlı.\n *\n * Üretilen `relations` bloğu ÇİFT YÖNLÜ: `customers.invoices` ile\n * `invoices.customer` birbirini gösteriyor, yani grafiğin kendisi döngülü.\n * Sınırsız açılım bu döngüyü sonsuz bir tipe çevirirdi — TypeScript'in\n * \"excessively deep\" hatası, yazılan sorgunun karmaşıklığından değil ŞEMANIN\n * şeklinden gelirdi. Üç seviye, ölçtüğümüz tüm gerçek sorguların üstünde.\n */\ntype HasDepth = 0 | 1 | 2 | 3;\ntype HasDec = [0, 0, 1, 2];\ntype HasNest<Rels, D extends HasDepth> = [keyof Rels] extends [never]\n ? unknown\n : D extends 0\n ? unknown\n : { has?: HasFilter<Rels, HasDec[D]> };\n\ntype HasFilter<Rels, D extends HasDepth = 3> = {\n [R in keyof Rels]?: Rels[R] extends { to: infer To }\n ? WhereFilter<RelatedRow<To>> & HasNest<RelatedRels<To>, D>\n : never;\n};\n\n/** İlişki bilgisi taşıyan bir tablo tipinin filtre yüzeyi. */\nexport type WhereWithRelations<Row, Rels> = WhereFilter<Row> & { has?: HasFilter<Rels> };\n\n/**\n * `has` dalı — SADECE `has`, satır filtresi olmadan.\n *\n * Plan yolunun filtre dili (`TxWhere`) düz op'unkiyle aynı değil: orada bir\n * alan ÖNCEKİ bir işlemin satırına referans (`Ref`) taşıyabiliyor. `has`'ı\n * plana taşımak için o dili kopyalamak gerekmiyor — kesişimle EKLENİYOR.\n * İlişki yoksa `unknown` dönüyor, çünkü `X & unknown = X`: dal yok olur ve\n * `has` fazla-alan denetimine takılır.\n */\nexport type HasOnly<Rels> = [unknown] extends [Rels]\n ? unknown\n : [keyof Rels] extends [never]\n ? unknown\n : { has?: HasFilter<Rels> };\n\n/**\n * `has` dalı NE ZAMAN var olur.\n *\n * İlişkisi OLMAYAN bir tabloda `has` hiç yazılamamalı. `HasFilter<{}>` boş bir\n * nesne tipidir ve boş nesne tipi HER nesneyi kabul eder — yani dalı koşulsuz\n * eklemek, ilişkisiz bir tabloda `has: { neyse_ne: {} }`'yi SESSİZCE geçirirdi\n * (ölçüldü: kapı yeşil, çalışma anında \"böyle bir ilişki yok\" hatası).\n */\ntype HasBranch<Row, Rels> = [unknown] extends [Rels]\n ? never\n : [keyof Rels] extends [never]\n ? never\n : WhereWithRelations<Row, Rels>;\n\n/**\n * `with` — İLİŞKİLİ SATIRLARI GETİR (`has` süzer, `with` getirir).\n *\n * `true` bütün kolonları, bir nesne ise `select`/`where`/`orderBy`/`limit` ile\n * daraltılmış hâlini getiriyor. Tek sorgu: LATERAL + `json_agg`.\n */\ntype WithOpts<To, D extends HasDepth> = {\n select?: readonly Extract<keyof RelatedRow<To>, string>[];\n where?: WhereFilter<RelatedRow<To>>;\n orderBy?: OrderBySpec<RelatedRow<To>> | readonly OrderBySpec<RelatedRow<To>>[];\n limit?: number;\n with?: D extends 1 ? never : [keyof RelatedRels<To>] extends [never] ? never : WithInput<RelatedRels<To>, HasDec[D]>;\n};\n\nexport type WithInput<Rels, D extends HasDepth = 3> = {\n [R in keyof Rels]?: Rels[R] extends { to: infer To } ? true | WithOpts<To, D> : never;\n};\n\n/** Bir `with` dalının DÖNÜŞ tipi — `many` dizi, `one` tekil ya da null. */\ntype WithRowOf<Rels, R extends keyof Rels, Q> = Rels[R] extends { to: infer To; kind: infer K }\n ? (Q extends { select: readonly (infer C extends keyof RelatedRow<To>)[] }\n ? Pick<RelatedRow<To>, C>\n : RelatedRow<To>) & (Q extends { with: infer W } ? WithResult<RelatedRels<To>, W> : unknown) extends infer Row\n ? [K] extends [\"many\"]\n ? Row[]\n : Row | null\n : never\n : never;\n\n/**\n * `with` istenmediğinde `unknown` — kesişimde YOK OLSUN diye.\n *\n * Boş bir nesne (`{}`) dönseydi `Pick<Row, K> & {}` satır tipini \"aynı ama\n * özdeş değil\" hâle getirirdi ve tam eşitlik iddiaları kırılırdı. Ölçüldü:\n * `toEqualTypeOf` dört yerde düştü.\n */\n/**\n * Yalnız GERÇEKTEN istenen dallar. `undefined extends W[R]` olan anahtarlar\n * düşüyor — ve bu, `ReturnType<typeof t.findMany>` yazan herkes için kritik:\n * generic bir imzada `ReturnType` tip parametrelerini VARSAYILANLA değil\n * KISITLA örnekliyor, yani `W = WithInput<Rels>` oluyor ve her ilişki\n * (`?:` ile, dolayısıyla `| undefined`) zorunlu bir alana dönüşüyordu.\n * Gerçek projede ölçüldü: `type MemberRow = Awaited<ReturnType<…findMany>>[number]`\n * 32 ilişkiyi birden ister hâle geldi ve 4 yerde kırıldı.\n */\ntype RequestedWith<W> = { [R in keyof W]-?: undefined extends W[R] ? never : R }[keyof W];\n\nexport type WithResult<Rels, W> = [RequestedWith<W>] extends [never]\n ? unknown\n : { [R in RequestedWith<W> & keyof Rels]: WithRowOf<Rels, R, W[R]> };\n\nexport type QueryInput<Row, K extends keyof Row = keyof Row, Rels = unknown> = {\n /**\n * Filtre — ya tipli filtre dili ya da bir `sqlFragment` (FR-018). İkisi de\n * AYNI alandır: kademe atlamak bir parametre değişikliği, ayrı bir çağrı\n * yolu değil (P1).\n */\n where?: WhereFilter<Row> | SqlFragment | HasBranch<Row, Rels>;\n /**\n * İlişkili satırları da getir — TEK sorguda.\n *\n * ```ts\n * const rows = await Database.public.users.findMany({\n * where: { active: true },\n * with: { orders: { select: [\"id\", \"amount\"], limit: 5 } },\n * });\n * rows[0].orders[0].amount; // string — KAYIPSIZ\n * ```\n *\n * `many` ilişki DİZİ döner (boşsa `[]`, `null` değil — `.map()` guard\n * istemesin); `one` ilişki tekil satır ya da `null`.\n *\n * PARA: `numeric`/`bigint` kolonları JSON'a `::text` ile giriyor. Cast\n * olmadan `numeric` bir JSON SAYISI olur ve kesinliğini kaybeder — ölçüldü,\n * `100000000000000000000000000` → `1e+26`.\n */\n // `HasBranch` ile AYNI iki koşul, aynı gerekçe: `unknown` ise kısıt yok\n // demektir, ve `WithInput<{}>` boş bir nesne tipidir — boş nesne HER nesneyi\n // kabul eder, yani ilişkisiz bir tabloda `with` sessizce geçerdi.\n with?: [unknown] extends [Rels] ? never : [keyof Rels] extends [never] ? never : WithInput<Rels>;\n /**\n * Projeksiyon (FR-009): yalnız bu kolonlar çekilir ve DÖNÜŞ TİPİ buna daralır.\n *\n * Tip `Pick<Row, K>` ile TÜRETİLİR, üretilmez: `select` kombinasyonları için\n * tip basmak, üretilen `.d.ts`'i kombinatoryal olarak şişirirdi (N-1: tablo\n * başına ≤ 25 satır).\n */\n select?: readonly K[];\n} & FindManyOpts<Row>;\n\nexport type PageInput<Row, K extends keyof Row = keyof Row, Rels = unknown> =\n Omit<QueryInput<Row, keyof Row, Rels>, \"limit\" | \"offset\" | \"select\"> &\n { select?: readonly K[] } & import(\"./page.js\").PageNavigation;\n\n/** Bir yazmanın TEK parametresi: neyi (`where`) neye çevirdiğin (`set`). */\nexport type MutateInput<Row, Insert, Rels = unknown> = {\n where: WhereFilter<Row> | SqlFragment | HasBranch<Row, Rels>;\n set: SetShape<Insert>;\n /**\n * `false` verilirse SATIRLAR değil SAYI döner — `deleteMany` ile aynı şekil.\n *\n * ÖLÇÜLDÜ (200 bin satır, canlı pg16): `RETURNING *` sunucuda %55 daha\n * pahalı (7,2 sn → 11,1 sn) ve JS'te 45 MB yığın tutuyor — satır başına 236\n * bayt, yani bir milyon satırda 225 MB. Çoğu çağrı için dönen diziyi okumak\n * DOĞRU ve varsayılan odur; toplu bir iş için çıkış yolu olması gerekiyordu.\n */\n returning?: boolean;\n};\n\n/**\n * `set`'e yazılabilen değer (FR-012): kolonun kendi tipi ya da — sayısal\n * kolonlarda — kolonun ŞU ANKİ değerini okuyan bir ifade.\n *\n * `increment()` metin ya da boolean kolonda YOK: \"kolona ekle\"nin orada bir\n * anlamı olmadığı için ifade edilemez kılınıyor (P5 — anlatmak değil, ifade\n * edilemez kılmak). `numeric` kolonlar TypeScript'te `string` taşır, o yüzden\n * string de sayısal sayılır; ayrımı burada yapamayız, ama D-007 zaten miktarın\n * JS `number`'a hiç uğramamasını istiyor.\n */\n/** `increment()`/`decrement()` HANGİ kolonlarda anlamlı — bildirilmiş PG tipine\n * göre. Marka yoksa eski sezgisel (`number | string`), ki o `text` kolonda da\n * izin veriyordu: Postgres `text + 1` demez. */\ntype NumericCol<V> = \"?\" extends PgTag<V>\n ? NonNullable<V> extends number | string\n ? TxColumnExpr\n : never\n : PgKind<PgTag<V>> extends \"num\"\n ? TxColumnExpr\n : never;\n\n/**\n * Bir EKLEME yolunda yazılabilecek değer.\n *\n * Kolonun kendi tipi ya da — zaman kolonlarında — sunucu saati. `increment()`\n * burada YOK ve olamaz: satır henüz yokken \"kolonun şu anki değeri\" diye bir\n * şey yok, motor da bunu adıyla reddediyor.\n *\n * Var olma nedeni ölçülmüş: introspect edilmiş şemalarda zaman kolonlarının\n * çoğu varsayılansız (`timestamp()`), yani \"eklerken sunucu saatini yaz\"ın tek\n * karşılığı istemci saatiydi — 33 tablolu bir projede 12 yerde.\n */\nexport type InsertValues<Insert> = {\n [K in keyof Insert]: Insert[K] | NowComparable<Insert[K]>;\n};\n\nexport type SetValue<V> =\n | V\n | NumericCol<V>\n // `now()` doğrudan yolda da geçerli: motor onu `SET col = now()` diye\n // derliyor (plan yolunun her zaman yaptığı gibi). Tipte yasaklamak, çalışan\n // bir çağrıyı ifade edilemez kılardı — P5'in tersi.\n //\n // VE TAM OLARAK BUNU YAPIYORDU: koşul `Date` idi, oysa `timestamp` kolonlar\n // TypeScript'e `string` geliyor. Yani `set: { updated_at: now() }` —\n // yazılabilecek en sık yazma ifadesi — HİÇBİR üretilmiş şemada derlenmiyordu\n // (ölçüldü). Marka o koşulu doğru yazılabilir kıldı.\n | NowComparable<V>;\n\n/** Bir update'in `set`'i: insert şeklinin herhangi bir alt kümesi, ifadelerle. */\nexport type SetShape<Insert> = { [K in keyof Insert]?: SetValue<Insert[K]> };\n\n/** search() parametreleri, satır tipiyle koşullanmış (FR-013). `offset` BİLEREK yok (UD-013). */\nexport interface SearchParamsTyped<T extends TableTypes> {\n /** Metin sorgusu: FTS kolunu besler; embed beyanlıysa sorgu vektörü de bundan üretilir. */\n query?: string;\n /** Hazır sorgu vektörü — verilirse embed çağrısı olmaz (FR-025). */\n vector?: number[];\n /** `findMany`'nin filtre dili — İKİNCİ tip argümanıyla, yoksa `Row` sessizce\n * `unknown`'a düşer ve `col()` burada ifade edilemez olurdu. Motor `search`\n * için aynı `compileWhereBare`'i kullanıyor; yetenek orada (gözcü I7). */\n where?: { [K in keyof T[\"row\"]]?: WhereOp<T[\"row\"][K], T[\"row\"]> };\n /** default 20, tavan 100 (engine uygular). */\n limit?: number;\n /** Birden çok vektör kolonunda hedef seçimi (model geçişi, FR-013/using). */\n using?: string;\n mode?: \"hybrid\" | \"text\" | \"vector\";\n /** Nihai (RRF-sonrası) skor alt eşiği — süzme LIMIT'ten önce uygulanır (FR-001). */\n minScore?: number;\n /** Chunk-modunda satır başına en iyi blok sayısı (1..10, vars. 3; FR-015). */\n blocksPerRow?: number;\n /** Tazelik çürümesi: nihai skor RRF-sonrası exp(-ln(2)*yaş/halfLife) ile çarpılır;\n * field bir timestamp kolonu, halfLife \"90s\" | \"15m\" | \"12h\" | \"30d\" biçiminde (FR-004). */\n recency?: { field: Extract<keyof T[\"row\"], string>; halfLife: string };\n /** Satır-modunda FTS eşleşme vurgusu: sonuç satırına `_highlight` ekler;\n * chunk-modda no-op — bloklar zaten eşleşen kesittir (FR-025). */\n highlight?: boolean;\n /** Validity'li tabloda zaman penceresi: varsayılan yalnız güncel versiyon;\n * \"all\" tüm versiyonlar; {asOf} o anda geçerli olan (FR-029). */\n validity?: \"all\" | { asOf: string };\n /** Alan-boost (FR-030): skor * (1 + w·x/(1+x)) — sayısal kolonla sınırlı\n * çarpan, dış servissiz; bileşim RRF → boost → recency → minScore. */\n boost?: { field: Extract<keyof T[\"row\"], string>; weight: number };\n}\n\n/**\n * `facets()` dönüşü (FR-027, FR-058): kolon adı → o kolonun top-20 değeri ve\n * sayacı.\n *\n * Bu tip bir zamanlar `search()` dönüş DİZİSİNİN üstünde taşınıyordu; dizi-üstü\n * özellik `JSON.stringify`'da kayboluyor, yani bir kontrolcü onu döndürmeye\n * çalıştığında yanıt gövdesinde hiç görünmüyordu. Sayaçlar artık BAĞIMSIZ\n * dönüşle geliyor ve tip de o dönüşü adlandırıyor.\n */\nexport type SearchFacets = Record<string, { value: string | null; count: number }[]>;\n\n/** similar()/recommend() taşıyıcı opsiyonları (T018, FR-022): search'ün\n * paramlarından query/vector/mode düşer — hedef vektörü metodun kendisi\n * DB'den kurar; facets/highlight de düşer (T020) — engine bu ikisini\n * similar/recommend'e geçirmez, tip vaadi gerçekle aynı kalır. */\nexport type SimilarParamsTyped<T extends TableTypes> = Omit<\n SearchParamsTyped<T>,\n \"query\" | \"vector\" | \"mode\" | \"facets\" | \"highlight\"\n>;\n\n/** recommend() parametreleri (T018, FR-023). */\nexport type RecommendParamsTyped<T extends TableTypes> = SimilarParamsTyped<T> & {\n /** Kaynak beğeniler — hedef vektör bunların DB-içi avg'ı; boş olamaz. */\n positive: string[];\n /** İtilen örnekler — hedef pos.v + (pos.v - neg.v) ile yönlenir. */\n negative?: string[];\n};\n\n/**\n * Tablonun ilişki bloğu — env `Tables` girdisinden.\n *\n * TEK yerde türetiliyor ve HER op'a aynısı veriliyor: `has` yalnız `findMany`'de\n * olsaydı, \"aynı filtre dili her op'ta\" sözü ilk `deleteMany`'de kırılırdı.\n */\ntype RelsOf<T> = T extends { relations: infer R } ? R : unknown;\n\n/**\n * TOPLAMA — dönüş tipi PG markasından TÜRETİLİR, tahmin edilmez.\n *\n * Para bu SDK'dan geçecek, ve toplamada kaybedilecek tek şey kesinliktir:\n * `sum(numeric)` Postgres'te `numeric`, `sum(integer)` `bigint` — İKİSİ DE JS\n * `number`'ında kayıplı. Bu yüzden `sum`/`avg` HER ZAMAN `string` döner ve\n * motor `::text` ile döker. D-007'nin kapattığı hata buydu:\n * 41.00821234567890123 canlıda 41.0082123456789 oluyordu.\n *\n * `| null` bir süs değil: Postgres BOŞ kümede NULL döndürür, 0 değil. \"Hiç\n * satır yoktu\" ile \"toplam sıfırdı\" farklı şeyler, ve tip bunu sormaya\n * ZORLUYOR.\n */\ntype SummableCols<Row> = {\n [K in keyof Row]-?: \"?\" extends PgTag<Row[K]>\n ? NonNullable<Row[K]> extends number | string\n ? K\n : never\n : PgKind<PgTag<Row[K]>> extends \"num\"\n ? K\n : never;\n}[keyof Row];\n\n/** `min`/`max` sıralanabilir her kolonda — jsonb ve vektör hariç. */\ntype OrderableCols<Row> = {\n [K in keyof Row]-?: \"?\" extends PgTag<Row[K]>\n ? NonNullable<Row[K]> extends number | string | Date\n ? K\n : never\n : PgTag<Row[K]> extends \"jsonb\" | \"vector\"\n ? never\n : K;\n}[keyof Row];\n\ntype AggCols<Row> = Extract<SummableCols<Row>, string>;\ntype AggOrderCols<Row> = Extract<OrderableCols<Row>, string>;\n\nexport type AggregateInput<Row, Rels = unknown> = {\n where?: WhereFilter<Row> | SqlFragment | HasBranch<Row, Rels>;\n /** Toplam — yalnız sayısal kolonlarda; sonuç `string | null` (kayıpsız). */\n sum?: readonly AggCols<Row>[];\n /** Ortalama — sonuç `numeric`, yani `string | null`. */\n avg?: readonly AggCols<Row>[];\n min?: readonly AggOrderCols<Row>[];\n max?: readonly AggOrderCols<Row>[];\n /** Kaç satır — `count()` ile aynı sayı, ama AYNI turda. */\n count?: boolean;\n /** Verilirse SATIRLAR döner ve her satır grup kolonlarını taşır. */\n groupBy?: readonly Extract<keyof Row, string>[];\n};\n\ntype AggPart<Q, Row, F extends \"sum\" | \"avg\" | \"min\" | \"max\"> = Q extends {\n [K in F]: readonly (infer C extends keyof Row)[];\n}\n ? { [P in C]: F extends \"sum\" | \"avg\" ? string | null : Row[P] | null }\n : never;\n\ntype AggBody<Q, Row> = ([AggPart<Q, Row, \"sum\">] extends [never] ? unknown : { sum: AggPart<Q, Row, \"sum\"> }) &\n ([AggPart<Q, Row, \"avg\">] extends [never] ? unknown : { avg: AggPart<Q, Row, \"avg\"> }) &\n ([AggPart<Q, Row, \"min\">] extends [never] ? unknown : { min: AggPart<Q, Row, \"min\"> }) &\n ([AggPart<Q, Row, \"max\">] extends [never] ? unknown : { max: AggPart<Q, Row, \"max\"> }) &\n (Q extends { count: true } ? { count: number } : unknown);\n\nexport type AggregateResult<Q, Row> = Q extends {\n groupBy: readonly (infer G extends keyof Row)[];\n}\n ? ({ [P in G]: Row[P] } & AggBody<Q, Row>)[]\n : AggBody<Q, Row>;\n\n/** Temel tablo erişimcisi — search'süz beş op. */\nexport interface EnvTypedTableBase<T extends TableTypes> {\n findUnique<K extends keyof T[\"row\"] = keyof T[\"row\"], W extends WithInput<RelsOf<T>> = Record<never, never>>(q: {\n where: import(\"./unique.js\").UniqueWhere<T[\"row\"], T[\"uniqueKeys\"]>;\n select?: readonly K[]; with?: QueryInput<T[\"row\"], keyof T[\"row\"], RelsOf<T>>[\"with\"] & W;\n }): Promise<(Pick<T[\"row\"], K> & WithResult<RelsOf<T>, W>) | null>;\n /** Index-backed pagination. The engine appends the declared primary key to\n * orderBy, encrypts cursor values and validates the query and caller scope. */\n page<K extends keyof T[\"row\"] = keyof T[\"row\"], W extends WithInput<RelsOf<T>> = Record<never, never>>(\n q?: PageInput<T[\"row\"], K, RelsOf<T>> & { with?: W },\n ): Promise<import(\"./page.js\").Page<Pick<T[\"row\"], K> & WithResult<RelsOf<T>, W>>>;\n insert(data: InsertValues<T[\"insert\"]>): Promise<T[\"row\"]>;\n /**\n * Çok satırı TEK statement'la ekle (tek gidiş-dönüş).\n *\n * ```ts\n * await Database.public.journey_stops.insertMany(\n * stops.map((s, i) => ({ journey_id, name: s.name, sort_order: i })),\n * );\n * ```\n *\n * Satırların anahtar kümesi AYNI olmalı: tek statement kolon listesini\n * paylaşır, yani farklı şekilli bir satırın fazla kolonu sessizce yazılmaz\n * ve eksiği yanlış sütuna kayardı. Eksik alan için `null` yazın.\n *\n * Boş dizi boş sonuç döner — hata değil: \"eklenecek bir şey yoktu\".\n */\n insertMany(rows: readonly InsertValues<T[\"insert\"]>[], opts: import(\"./bulk.js\").InsertManyOptions<Extract<keyof T[\"row\"], string>> & { returning: false }): Promise<number>;\n insertMany(rows: readonly InsertValues<T[\"insert\"]>[], opts?: import(\"./bulk.js\").InsertManyOptions<Extract<keyof T[\"row\"], string>> & { returning?: true }): Promise<T[\"row\"][]>;\n insertMany(rows: readonly InsertValues<T[\"insert\"]>[], opts?: import(\"./bulk.js\").InsertManyOptions<Extract<keyof T[\"row\"], string>>): Promise<T[\"row\"][] | number>;\n /**\n * Bir idempotency anahtarını sahiplen (FR-033).\n *\n * ```ts\n * const { inserted, row } = await Database.public.payments.claim(\n * { idem_key: req.headers[\"idempotency-key\"] },\n * { amount, user_id },\n * );\n * if (!inserted) return row; // aynı istek ikinci kez geldi\n * ```\n *\n * `inserted: false` bir HATA DEĞİL: dönen satır ilk çağrının satırıdır.\n * İlk argüman satırı BULAN alanlar, ikincisi yalnız yazılanlar — ikinci çağrı\n * farklı bir yük gönderse bile satır anahtarla bulunur.\n */\n claim(\n unique: Partial<T[\"insert\"]>,\n extra?: Partial<InsertValues<T[\"insert\"]>>,\n ): Promise<{ inserted: boolean; row: T[\"row\"] }>;\n /**\n * Satırı yaz; `onConflict` kolonlarında çakışırsa ÜZERİNE yaz (FR-034).\n *\n * ```ts\n * await Database.public.settings.put({\n * data: { user_id, theme: \"dark\" },\n * onConflict: [\"user_id\"],\n * });\n * ```\n *\n * `onConflict` kolonları benzersiz bir kısıt ya da index taşımalı — Postgres\n * onlarla eşleştirir — ve güncellemeden dışlanırlar, çünkü eşleşen şey onlar.\n *\n * **`upsert`'ün yerine geldi ve adı bilerek değişti.** `upsert` tek isim\n * altında iki niyet taşıyordu: \"yoksa ekle varsa güncelle\" (bu) ve \"idempotent\n * yaz\" (artık {@link EnvTypedTableBase.claim}). İkincisi için ÖLÇÜLMÜŞ biçimde\n * yanlıştı: `DO UPDATE` ikinci çağrının verisiyle birincininkini EZİYOR\n * (10.00 → 999.00 ölçüldü). İki niyeti tek isimde tutmak, yanlış olanı\n * seçmeyi kolay yapıyordu.\n */\n put(q: {\n data: InsertValues<T[\"insert\"]>;\n onConflict: readonly Extract<keyof T[\"row\"], string>[];\n }): Promise<T[\"row\"]>;\n /** Update the row by id; resolves to the updated row, or `null` if no row\n * matched (absent or RLS-hidden) — an idempotent outcome, mirroring\n * `findById`. The runtime returns a null row rather than throwing. */\n update(q: { where: { id: string }; set: SetShape<T[\"insert\"]> }): Promise<T[\"row\"] | null>;\n delete(id: string): Promise<void>;\n findById(id: string): Promise<T[\"row\"] | null>;\n /** Rows matching the filter. See {@link WhereFilter} / {@link FindManyOpts} —\n * this declaration is what makes the engine's operators callable. */\n findMany<\n K extends keyof T[\"row\"] = keyof T[\"row\"],\n W extends WithInput<RelsOf<T>> = Record<never, never>,\n >(\n // `K` ve `W` AYRI çıkarım noktaları. Tek bir `const Q` generic'i denendi ve\n // ESKİ BİR KAPIYI ÖLDÜRDÜ: `where: { note: { contains: 5 } }` — metin\n // olmayan bir değerle `contains` — derlenmeye başladı, çünkü kısıt denetimi\n // literal çıkarımın altında kayboluyordu. Ölçüldü ve geri alındı.\n q?: QueryInput<T[\"row\"], K, RelsOf<T>> & { with?: W },\n ): Promise<Array<Pick<T[\"row\"], K> & WithResult<RelsOf<T>, W>>>;\n /**\n * Update every matching row in one statement; an empty filter is refused.\n *\n * **0 satır dönmesi hata DEĞİL, başarı da değil** (FR-014): koşulu `where`'e\n * koyup dönen diziyi kontrol etmek, \"önce oku sonra yaz\"ın yarış koşulu\n * olmayan hâlidir.\n *\n * ```ts\n * const [row] = await Database.public.accounts.updateMany({\n * where: { id, balance: { gte: amount } },\n * set: { balance: decrement(amount) },\n * });\n * if (row === undefined) throw new Conflict(\"yetersiz bakiye\");\n * ```\n */\n updateMany<const Q extends MutateInput<T[\"row\"], T[\"insert\"], RelsOf<T>>>(\n q: Q,\n ): Promise<Q extends { returning: false } ? number : T[\"row\"][]>;\n /** Delete every matching row; resolves to how many. Empty filter refused. */\n deleteMany(q: { where: WhereFilter<T[\"row\"]> | SqlFragment | HasBranch<T[\"row\"], RelsOf<T>> }): Promise<number>;\n /**\n * Toplama — `sum` / `avg` / `min` / `max` / `count`, isteğe bağlı `groupBy`.\n *\n * ```ts\n * const r = await Database.public.entries.aggregate({\n * where: { account_id },\n * sum: [\"amount_kurus\"],\n * count: true,\n * });\n * r.sum.amount_kurus; // string | null — KAYIPSIZ\n * r.count; // number\n * ```\n *\n * `sum`/`avg` yalnız sayısal kolonlarda ve HER ZAMAN `string` döner: para JS\n * `number`'ına uğradığı anda kesinliğini kaybeder. `| null` çünkü Postgres\n * boş kümede NULL döndürür — \"hiç satır yoktu\" ile \"toplam sıfırdı\" farklı\n * şeyler ve tip bunu sormaya zorluyor.\n *\n * `groupBy` verilirse dönüş bir DİZİ ve her satır grup kolonlarını taşır.\n */\n aggregate<const Q extends AggregateInput<T[\"row\"], RelsOf<T>>>(\n q: Q,\n ): Promise<AggregateResult<Q, T[\"row\"]>>;\n /** How many rows match. An empty filter is legitimate: counting is a read. */\n count(q?: { where?: WhereFilter<T[\"row\"]> | SqlFragment | HasBranch<T[\"row\"], RelsOf<T>> }): Promise<number>;\n /** Validity'li tabloda satırın yeni versiyonu (FR-029, C-9): eski satır\n * kapanır (valid_to/superseded_by), yenisi TEK savepoint'te eklenir; dönüş\n * yeni satır. Validity beyanı olmayan tabloda adlandırılmış çalışma-zamanı\n * hatası — tip düzeyinde ayrım env `Tables` bayrağı taşımadığından yapılamaz. */\n supersede(id: string, row: InsertValues<T[\"insert\"]>): Promise<T[\"row\"]>;\n}\n\n/** Tablo erişimcisi: env girdisi `searchable: true` taşıyorsa (vector kolonu ya da\n * search beyanı — env-gen üretir) `search()` üyesi VARDIR; yoksa üye hiç yoktur ve\n * çağrı derleme hatasıdır (FR-013). Yapısal koşul TableTypes'ı genişletmeden çalışır. */\n/**\n * `appendOnly` tabloda YAYIMLANMAYAN üyeler (FR-031).\n *\n * Altısı da ayrı ayrı: biri unutulursa append-only sözü o üye üzerinden sessizce\n * delinir. `insert` ve okuma üyeleri kalır — düzeltme SİLMEKLE değil, telafi\n * kaydı EKLEMEKLE yapılır (FR-032).\n */\ntype AppendOnlyForbidden = \"update\" | \"updateMany\" | \"delete\" | \"deleteMany\" | \"put\" | \"supersede\";\n\nexport type EnvTypedTable<T extends TableTypes> = (T extends { appendOnly: true }\n ? Omit<EnvTypedTableBase<T>, AppendOnlyForbidden>\n : EnvTypedTableBase<T>) &\n (T extends { searchable: true }\n ? {\n search(\n params: SearchParamsTyped<T>,\n ): Promise<Array<T[\"row\"] & { _score: number; _highlight?: string }>>;\n /** \"Bu satıra benzeyenler\" (FR-022): hedef vektör DB'den okunur,\n * kaynak satır sonuçta yoktur; id yoksa adlandırılmış hata. */\n similar(id: string, params?: SimilarParamsTyped<T>): Promise<Array<T[\"row\"] & { _score: number }>>;\n /** D-021: sayaçlar bağımsız dönüşle — search'ün dizi-üstü _facets'i\n * JSON.stringify'da kaybolur; ciddi sözleşme budur. */\n facets(params: { facets: Array<keyof T[\"row\"] & string>; where?: Partial<T[\"row\"]>; validity?: \"all\" | { asOf: string } }): Promise<SearchFacets>;\n /** positive/negative beğenilerden öneri (FR-023): hedef vektör DB-içi\n * avg CTE'leriyle; kaynak id'ler sonuçta yoktur. */\n recommend(params: RecommendParamsTyped<T>): Promise<Array<T[\"row\"] & { _score: number }>>;\n }\n : Record<never, never>);\n\n/** The `tables` map exposed on `Database`/`tx`, keyed by the env `Tables`\n * interface. When no schema is declared `Tables` is empty, so `tables` is an\n * empty object — accessing `.tables.foo` is then a compile error (no member). */\nexport type EnvTables = {\n [K in keyof Tables]: EnvTypedTable<Tables[K]>;\n};\n\n/**\n * The project's NON-public schemas, keyed by schema name, each exposing its own\n * `tables` map — the shape `Database.schema(\"billing\")` returns.\n *\n * The intermediate `tables` is there for the reason {@link EnvTables} sits under\n * `.tables`: a schema's table names must not share a namespace with anything the\n * accessor itself might grow.\n *\n * Empty by default. The generated `palbase-env.d.ts` augments `Schemas` with one\n * member per declared schema other than `public`, so a project that declares\n * none has `keyof Schemas = never` and every `schema(...)` call is a compile\n * error rather than a runtime surprise.\n */\n/**\n * @deprecated ARTIK VAR OLMAYAN BİR ŞEKLİ tarif ediyor. Bu tip her şemayı\n * `{ tables: … }` altında gösteriyor; yüzey FR-001 ile `Database.<şema>.<tablo>`\n * oldu ve `.tables` ara katmanı KALKTI. Güncel şekil: {@link EnvSchemaSurface}.\n *\n * Kaldırılmadı çünkü dışa açık bir tip ve kaldırmak SEKİZİNCİ bir kırıcı olurdu;\n * ama bir tip, çalışma zamanının ÜRETMEDİĞİ bir şekli tarif ediyorsa yalan\n * söylüyor demektir — `const x: EnvSchemas[\"billing\"] = Database.billing`\n * açıklanamayan bir derleme hatası verir. Bir sonraki kırıcı sürümde silinmeli\n * (defter D-18).\n *\n * Bu tipi ÜRETEN iki fonksiyon (`makeTablesAccessor`, `makeSchemaAccessor`)\n * ölçüldü: hiçbir yerden çağrılmıyorlardı ve silindiler. Canlı yol\n * `makeTypedSurface`'ın proxy'si.\n */\nexport type EnvSchemas = {\n [S in keyof Schemas]: {\n tables: {\n [T in keyof Schemas[S]]: EnvTypedTable<Extract<Schemas[S][T], TableTypes>>;\n };\n };\n};\n\n/** The project's tables as PLAN operations, keyed by the env `Tables`\n * interface. The transaction twin of {@link EnvTables}. */\n/** `appendOnly` bir tabloda transaction planının da kaybettiği üyeler. Doğrudan\n * yüzeyin `AppendOnlyForbidden`'ının plan-yolu ikizi; adlar farklı çünkü plan\n * yüzeyinin üye adları farklı. */\ntype TxAppendOnlyForbidden = \"put\" | \"updateWhere\" | \"deleteWhere\";\n\n/**\n * Plan yüzeyi de `appendOnly`'yi UYGULUYOR — ve uygulamıyor olması bir kusurdu.\n *\n * `EnvTypedTable` altı üyeyi Omit ediyordu, ama `TxTables` hiçbirini: yani\n * `tx.tables.entries.updateWhere(…)` ve `.put(…)` DERLENİYORDU. Tip bir şeyi\n * \"ifade edilemez\" ilan edip ikinci bir kapıda ifade edilebilir bırakırsa,\n * ilan yalandır (doğrulayıcı gözcü, FR-031).\n *\n * Motor da aynı üçünü adıyla reddediyor — tip atlanınca susmaması için.\n */\nexport type TxTables = {\n [K in keyof Tables]: Tables[K] extends { appendOnly: true }\n ? Omit<TxTable<Tables[K][\"row\"], Tables[K][\"insert\"], RelsOf<Tables[K]>>, TxAppendOnlyForbidden>\n : TxTable<Tables[K][\"row\"], Tables[K][\"insert\"], RelsOf<Tables[K]>>;\n};\n\n/** Bir şemanın tabloları PLAN operasyonları olarak — `TxTables`'ın public\n * DIŞI şemalar için ikizi. */\ntype TxTablesOf<S> = {\n [T in keyof S]: Extract<S[T], TableTypes> extends { appendOnly: true }\n ? Omit<\n TxTable<\n Extract<S[T], TableTypes>[\"row\"],\n Extract<S[T], TableTypes>[\"insert\"],\n RelsOf<Extract<S[T], TableTypes>>\n >,\n TxAppendOnlyForbidden\n >\n : TxTable<\n Extract<S[T], TableTypes>[\"row\"],\n Extract<S[T], TableTypes>[\"insert\"],\n RelsOf<Extract<S[T], TableTypes>>\n >;\n};\n\n/**\n * Plan tutamağının şema yüzeyi — `EnvSchemaSurface`'ın BİREBİR ikizi.\n *\n * NEDEN AYNI ŞEKİL: `Database.billing.invoices` yazılabiliyorken\n * `tx.billing.invoices` yazılamıyordu, yani `billing` şemasındaki iki tabloyu\n * TEK ATOMİK PLANDA yazmak imkânsızdı — yazar `$query`'ye düşüyor, tipi ve RLS\n * yardımını kaybediyordu. Bu yüzeyin kapatmak için var olduğu düşüşün ta\n * kendisi, ve GOAL'ün \"ciddi ölçekli fintech\" yarısının tam ortasında\n * (nihai inceleme I-6).\n */\nexport type TxSchemaSurface = { public: TxTables } & {\n [S in keyof Schemas]: TxTablesOf<Schemas[S]>;\n};\n\n/**\n * The handle a `Database.$transaction(…)` callback receives.\n *\n * Tables only — no `query`, no `findById`, no `asService`. A read whose value\n * the plan does not write belongs outside the transaction, where it costs one\n * round trip and is an ordinary value you can branch on.\n *\n * `tx.public.x` ve `tx.<şema>.x`, `Database` ile aynı şekil. `tx.tables.x`\n * public'in TAKMA ADI olarak duruyor: bu run'ın göç notu onu öğretiyor ve her\n * mevcut çağrı onu kullanıyor — kaldırmak sekizinci bir kırıcı olurdu ve\n * hiçbir şey kazandırmazdı.\n */\nexport type TxPlan = TxPlanHandle<TxTables> & TxSchemaSurface;\n\n/**\n * The RLS-bypass sibling returned by `Database.$asService()`. Same typed surface\n * as {@link EnvTypedDatabase} — `tables`, the raw string ops, and a typed\n * `transaction` — but it does NOT re-expose `asService` (no double-bypass).\n * Every op it performs runs as the `service_role` (BYPASSRLS).\n */\nexport type EnvServiceDatabase = EnvSchemaSurface & {\n /** Commits independently of the request. All decision reads and writes belong\n * inside this callback; each retry includes a new BEGIN and COMMIT. */\n $atomic<T>(fn: (tx: AtomicDatabase) => Promise<T>, options?: AtomicOptions): Promise<T>;\n /** Ham SQL. Generic verilmezse `unknown[]` döner (FR-021). */\n $query: DBClient[\"query\"];\n $insert: DBClient[\"insert\"];\n $update: DBClient[\"update\"];\n $delete: DBClient[\"delete\"];\n $findById: DBClient[\"findById\"];\n $findUnique: DBClient[\"findUnique\"];\n $diagnostics: DBClient[\"diagnostics\"];\n $findMany: DBClient[\"findMany\"];\n $page: DBClient[\"page\"];\n $put: DBClient[\"put\"];\n $updateMany: DBClient[\"updateMany\"];\n $deleteMany: DBClient[\"deleteMany\"];\n $count: DBClient[\"count\"];\n $search: DBClient[\"search\"];\n $similar: RecoOps[\"similar\"];\n $recommend: RecoOps[\"recommend\"];\n $facets: DBClient[\"facets\"];\n $supersede: DBClient[\"supersede\"];\n $claim: DBClient[\"claim\"];\n $lockRows: DBClient[\"lockRows\"];\n $lockRowsWhere: DBClient[\"lockRowsWhere\"];\n $advisoryXactLock: DBClient[\"advisoryXactLock\"];\n $attempt: DBClient[\"attempt\"];\n $command<T>(fn: (tx: TxPlan) => T extends Promise<unknown> ? never : T, options?: import(\"./command.js\").CommandOptions): Promise<Materialized<T>>;\n /** Bkz. {@link EnvTypedDatabase.$transaction}. */\n /**\n * A plan is a savepoint in the current transaction. Nonzero `retry` is\n * refused; use $atomic for whole-transaction retry, including decision reads\n * and COMMIT. The default plan keeps request-scoped commit/rollback behavior.\n */\n $transaction<T>(\n fn: (tx: TxPlan) => T extends Promise<unknown> ? never : T,\n opts?: { retry?: number },\n ): Promise<Materialized<T>>;\n }\n\n/**\n * The typed-by-default Database surface: the `$`-prefixed string-keyed\n * `DBClient` ops PLUS one property per schema — `public` and every schema the\n * project declares — typed against the generated `palbase-env.d.ts`, a\n * `$transaction` that runs a whole plan in one request, and `$asService()` for\n * the explicit RLS-bypass sibling.\n *\n * NOT `tables`: that intermediate layer was removed (FR-001) and this sentence\n * outlived it by two majors, teaching a spelling that is TS2339. Pinned in\n * `src/database-ambient.test-d.ts`.\n *\n * The low-level `txPlan` op is deliberately NOT re-exposed here: `$transaction`\n * is the surface, and a hand-built plan would bypass the ref/guard machinery\n * that makes one safe to write.\n */\nexport type EnvSchemaSurface = { public: EnvTables } & {\n [S in keyof Schemas]: {\n [T in keyof Schemas[S]]: EnvTypedTable<Extract<Schemas[S][T], TableTypes>>;\n };\n};\n\n/**\n * `$` öneki, sistem üyelerini kullanıcı adlarından AYIRAN şeydir (FR-002/003).\n *\n * `Database` altında on beşten fazla string-anahtarlı op var ve çoğu son derece\n * makul bir tablo adı — `transaction` bir fintech şemasında neredeyse kaçınılmaz.\n * Şema doğrulayıcısı bir tablo/şema adının `$` ile başlamasına izin vermediği\n * için (`^[a-zA-Z_][a-zA-Z0-9_]*`), önek çakışmayı MATEMATİKSEL olarak imkânsız\n * kılar: bir isim ya `$`'la başlar (sistem) ya başlamaz (kullanıcı).\n */\nexport type DollarOps<T> = { [K in keyof T as `$${string & K}`]: T[K] };\n\n// NOT: `EnvTypedDatabase` bu yardımcıyı KULLANMIYOR, üyelerini AÇIKÇA yazıyor.\n// Sebep ölçüldü: `database.test.ts`'in sayımı TypeScript checker'ıyla yürüyor ve\n// her property'nin declaration'ını arıyor; mapped type ile yeniden adlandırılan\n// property'ler SYNTHETIC'tir, declaration taşımaz, dolayısıyla sayımda GÖRÜNMEZ.\n// Görünmeyen bir yüzey denetlenemez — o testin varlık sebebi de bu. Yardımcı,\n// runtime tarafındaki `satisfies` kontrolü için duruyor.\n\n/**\n * Projenin veri yüzeyi: `Database.<şema>.<tablo>` + `$` önekli sistem üyeleri.\n *\n * Bugünkü `tables` ve `schema(\"x\")` ikilisinin yerine geçer (FR-001). İki yol\n * tek yola iner: `public` de diğer şemalar gibi adıyla anılır, ara katman yoktur.\n *\n * @example\n * await Database.public.notes.findMany({ where: { owner: uid } });\n * await Database.billing.invoices.findMany({ where: { paid: false } });\n * await Database.$transaction((tx) => { … });\n */\nexport type EnvTypedDatabase = EnvSchemaSurface & {\n /** Commits independently of the request. A later handler failure does not\n * undo this scope. The callback cannot switch RLS identity or nest a root. */\n $atomic<T>(fn: (tx: AtomicDatabase) => Promise<T>, options?: AtomicOptions): Promise<T>;\n /** Ham SQL. Generic verilmezse `unknown[]` döner (FR-021). */\n $query: DBClient[\"query\"];\n $insert: DBClient[\"insert\"];\n $update: DBClient[\"update\"];\n $delete: DBClient[\"delete\"];\n $findById: DBClient[\"findById\"];\n $findUnique: DBClient[\"findUnique\"];\n $diagnostics: DBClient[\"diagnostics\"];\n $findMany: DBClient[\"findMany\"];\n $page: DBClient[\"page\"];\n $put: DBClient[\"put\"];\n $updateMany: DBClient[\"updateMany\"];\n $deleteMany: DBClient[\"deleteMany\"];\n $count: DBClient[\"count\"];\n $search: DBClient[\"search\"];\n $similar: RecoOps[\"similar\"];\n $recommend: RecoOps[\"recommend\"];\n $facets: DBClient[\"facets\"];\n $supersede: DBClient[\"supersede\"];\n $claim: DBClient[\"claim\"];\n $lockRows: DBClient[\"lockRows\"];\n $lockRowsWhere: DBClient[\"lockRowsWhere\"];\n $advisoryXactLock: DBClient[\"advisoryXactLock\"];\n $attempt: DBClient[\"attempt\"];\n $command<T>(fn: (tx: TxPlan) => T extends Promise<unknown> ? never : T, options?: import(\"./command.js\").CommandOptions): Promise<Materialized<T>>;\n /** RLS'i bypass eden kardeş yüzey. Kendisi `$asService` TAŞIMAZ — çift bypass yok. */\n $asService(): EnvServiceDatabase;\n /**\n * Bir transaction çalıştırır. Callback işlemleri TARİF eder; tarifin tamamı\n * tek istekte gider ve broker onu tek bir transaction içinde koşturur.\n * Callback SENKRONDUR: döndüğünde hiçbir şey çalışmamıştır.\n */\n /**\n * A plan is a savepoint in the current transaction. Nonzero `retry` is\n * refused; use $atomic for whole-transaction retry, including decision reads\n * and COMMIT. The default plan keeps request-scoped commit/rollback behavior.\n */\n $transaction<T>(\n fn: (tx: TxPlan) => T extends Promise<unknown> ? never : T,\n opts?: { retry?: number },\n ): Promise<Materialized<T>>;\n }\n\n/** The same typed table/query surface on one active physical transaction. */\nexport type AtomicDatabase = Omit<EnvServiceDatabase, \"$atomic\">;\n"],"mappings":"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","names":["TABLE_META","Symbol","for","REF_TARGET","ForeignKeyBuilder","_def","name","trim","Error","columns","refTable","refColumns","on","cols","map","c","e","expr","kind","references","table","length","Object","defineProperty","value","enumerable","configurable","onUpdate","action","onDelete","match","m","foreignKey","toForeignKeyDef","b","def","join","FreezeBuilder","when","pred","toFreezeDef","freeze","undefined","out","target","z","GuardBuilder","_def","name","trim","Error","on","event","when","pred","expr","exists","table","predicate","exprCtx","existsIn","refuse","message","opts","detail","undefined","hint","column","toGuardDef","guard","b","def","backfill","name","sql","trim","Error","IndexBuilder","_def","name","trim","Error","unique","on","cols","columns","map","c","e","expr","kind","onExpression","expression","where","desc","sort","asc","nulls","include","index","toPolicyDef","p","PolicyBuilder","TABLE_META","Symbol","for","defineTable","input","reserved","reservedCanRelation","JSON","stringify","policies","exprCtx","Object","keys","rls","length","owned","colName","b","entries","builder","clone","create","getPrototypeOf","defineProperty","value","enumerable","writable","def","primaryKey","undefined","raw","slice","declaredChecks","checks","declaredIndexes","indexes","i","declaredFKs","foreignKeys","toForeignKeyDef","declaredFreezes","freeze","toFreezeDef","fz","join","declaredGuards","guards","toGuardDef","g","column","backfills","seen","Set","has","add","sql","dropConstraints","appendOnly","ignored","search","s","from","vector","model","Array","isArray","text","String","legs","leg","memory","values","ownerTable","handle","declaringSchemaOf","WeakMap","resolveReferences","tables","schemaName","table","qualifyRefTargets","selfRefColumn","references","qualifiedTableKey","referencesThunk","target","owner","targetColumn","find","targetSchema","get","defineSchema","set","m","t","into","subject","factCol","factDef","type","extensions","exposed","qualifyRefTargets","table","where","qualify","holder","what","target","REF_TARGET","undefined","targetSchema","declaringSchemaOf","get","Error","name","qualified","qualifiedTableKey","refTable","fk","foreignKeys","fz","freeze","g","guards","exists","qualifyExistsNodes","node","kind","v","Object","values","Array","isArray","e","PolicyExprRef","expr","bin","op","other","kind","left","right","toExpr","eq","neq","gt","gte","lt","lte","isNull","negated","and","others","parts","map","o","or","not","v","value","exprCtx","_columns","depth","ownTable","alias","col","name","auth","uid","lit","p","part","existsIn","table","predicate","meta","TABLE_META","inner","Object","keys","columns","node","outer","defineProperty","REF_TARGET","enumerable","configurable","quote","replace","PolicyBuilder","_def","command","roles","using","withCheck","permissive","for","to","memberOf","membershipTable","foreignKey","options","Error","column","userColumn","as","mode","policy","assertCheckNode","CHECK_BIN_OPS","literalSQL","Number","isFinite","String","checkNodeSQL","undefined","length","joiner","join","check","trim","can","def","Array","isArray","policies","prototype","hasOwnProperty","call","rel","reservedCanRelation","names","filter","Buffer","byteLength","all","hint","n","z","array","enum","tableName","b","entries","referencesThunk","selfRefColumn","reverseAs","forward","owns","refAs","endsWith","slice","PALBASE_EXTENSIONS","EXTENSION_DEPENDENCIES","earthdistance","isPalbaseExtension","name","includes","raw","name","up","openai","embedding","model","opts","provider","apiKeyName","dimensions","undefined","baseURL","chat","makeTypedTable","name","raw","insert","data","aggregate","q","insertMany","rows","opts","put","onConflict","update","where","id","set","delete","findUnique","select","findById","page","findMany","updateMany","returning","undefined","deleteMany","count","makeTypedDB","schema","tables","key","Object","keys","tableDef","qualifiedTableKey","result","diagnostics","command","fn","options","builder","TxPlanBuilder","planTables","fromEntries","entries","map","table","runTxPlan","txPlan","plan","transaction","col","name","brandRef","$col","withRetry","fn","opts","budget","retryBudget","retry","attempt","e","isRetryable","sqlFragment","strings","values","$sql","text"]}
|
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
} from "./chunk-FFO36MQQ.js";
|
|
4
4
|
import {
|
|
5
5
|
qualifiedTableKey
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-4J6I4KVQ.js";
|
|
7
7
|
import {
|
|
8
8
|
__name
|
|
9
9
|
} from "./chunk-VXPNPVAG.js";
|
|
@@ -754,4 +754,4 @@ export {
|
|
|
754
754
|
buildContainer,
|
|
755
755
|
assertNoOrphanEntryPoints
|
|
756
756
|
};
|
|
757
|
-
//# sourceMappingURL=chunk-
|
|
757
|
+
//# sourceMappingURL=chunk-H7EKL6HC.js.map
|