@palbase/backend 38.0.16 → 39.0.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.
Files changed (58) hide show
  1. package/dist/bin/palbase-backend.cjs +46 -1
  2. package/dist/bin/palbase-backend.cjs.map +1 -1
  3. package/dist/bin/palbase-backend.js +5 -5
  4. package/dist/{chunk-LFUNRWUE.js → chunk-4J6I4KVQ.js} +67 -3
  5. package/dist/{chunk-LFUNRWUE.js.map → chunk-4J6I4KVQ.js.map} +1 -1
  6. package/dist/{chunk-7WAGQ3VR.js → chunk-AR2I4M7I.js} +497 -17
  7. package/dist/chunk-AR2I4M7I.js.map +1 -0
  8. package/dist/{chunk-YANGWAIM.js → chunk-H7EKL6HC.js} +2 -2
  9. package/dist/{chunk-EHKEMHB4.js → chunk-JJSR4BUX.js} +49 -5
  10. package/dist/chunk-JJSR4BUX.js.map +1 -0
  11. package/dist/{chunk-CS6NQ6PO.js → chunk-JPTFYHP3.js} +2 -2
  12. package/dist/{chunk-CS6NQ6PO.js.map → chunk-JPTFYHP3.js.map} +1 -1
  13. package/dist/{chunk-X7UR3VXA.js → chunk-XZWOMPD3.js} +3 -2
  14. package/dist/chunk-XZWOMPD3.js.map +1 -0
  15. package/dist/{chunk-PDD55QWN.js → chunk-ZNQDL466.js} +2 -2
  16. package/dist/db/index.cjs +378 -14
  17. package/dist/db/index.cjs.map +1 -1
  18. package/dist/db/index.d.cts +1 -1
  19. package/dist/db/index.d.ts +1 -1
  20. package/dist/db/index.js +3 -3
  21. package/dist/engine/index.cjs +46 -1
  22. package/dist/engine/index.cjs.map +1 -1
  23. package/dist/engine/index.d.cts +3 -3
  24. package/dist/engine/index.d.ts +3 -3
  25. package/dist/engine/index.js +5 -5
  26. package/dist/{index-CI7S0Wqv.d.cts → index-B0mjUnxy.d.cts} +25 -2
  27. package/dist/{index-CUy50OLU.d.ts → index-eN4KzGa5.d.ts} +555 -29
  28. package/dist/{index-DRx880KY.d.cts → index-pK2At5Yc.d.cts} +555 -29
  29. package/dist/{index-Ogi30dbt.d.ts → index-yDno9Ju9.d.ts} +25 -2
  30. package/dist/index.cjs +628 -17
  31. package/dist/index.cjs.map +1 -1
  32. package/dist/index.d.cts +183 -8
  33. package/dist/index.d.ts +183 -8
  34. package/dist/index.js +74 -6
  35. package/dist/index.js.map +1 -1
  36. package/dist/openapi/index.cjs.map +1 -1
  37. package/dist/openapi/index.d.cts +2 -2
  38. package/dist/openapi/index.d.ts +2 -2
  39. package/dist/openapi/index.js +2 -2
  40. package/dist/{registry-C7UCkQf0.d.cts → registry-9dNeVN5d.d.cts} +1 -1
  41. package/dist/{registry-DJcvbomD.d.ts → registry-B8ddZiMY.d.ts} +1 -1
  42. package/dist/test/index.cjs +19 -0
  43. package/dist/test/index.cjs.map +1 -1
  44. package/dist/test/index.d.cts +1 -1
  45. package/dist/test/index.d.ts +1 -1
  46. package/dist/test/index.js +20 -2
  47. package/dist/test/index.js.map +1 -1
  48. package/docs/README.md +1 -1
  49. package/docs/database.md +79 -0
  50. package/docs/llms-full.txt +462 -33
  51. package/docs/schema.md +382 -32
  52. package/package.json +1 -1
  53. package/template/package.json +1 -1
  54. package/dist/chunk-7WAGQ3VR.js.map +0 -1
  55. package/dist/chunk-EHKEMHB4.js.map +0 -1
  56. package/dist/chunk-X7UR3VXA.js.map +0 -1
  57. /package/dist/{chunk-YANGWAIM.js.map → chunk-H7EKL6HC.js.map} +0 -0
  58. /package/dist/{chunk-PDD55QWN.js.map → chunk-ZNQDL466.js.map} +0 -0
@@ -824,6 +824,33 @@ declare class PolicyExprRef {
824
824
  or(...others: PolicyExprRef[]): PolicyExprRef;
825
825
  not(): PolicyExprRef;
826
826
  }
827
+ /**
828
+ * Bir tablonun `existsIn` için ANNOTATION hâli — iki bildirim birbirini
829
+ * başlatırken çıkarım döngüsünü kıran şey.
830
+ *
831
+ * ÖLÇÜLDÜ: `memberships.household_id` `households.id`'ye referans verirken
832
+ * `households`'ın politikası `existsIn(memberships, …)` yazarsa TypeScript
833
+ * ikisini de TS7022 ile `any`'ye düşürüyor. Kesinti sadece hata mesajı değil:
834
+ * `m.col(…)` de `any` olduğu için politika gövdesindeki YANLIŞ YAZILMIŞ bir
835
+ * kolon adı sessizce derleniyor — RLS yolunda fail-open. Aynı ölçümde
836
+ * `existsIn`'in jeneriğini kaldırmak (tamamen jeneriksiz imza dahil) döngüyü
837
+ * KIRMADI: döngü çıkarımdan değil, iki `const`'un birbirini başlatmasından
838
+ * geliyor ve TypeScript'te tek çaresi bir tip annotation'ı.
839
+ *
840
+ * Bu, `references((): AnyColumn => y.id)`'nin tablo düzeyindeki karşılığı — ama
841
+ * `AnyColumn`'dan farklı olarak KOLON ADLARINI SİLMEZ:
842
+ *
843
+ * ```ts
844
+ * const memberships: TableRef<"id" | "household_id" | "user_id", "memberships"> =
845
+ * defineTable("memberships", { columns: { … } });
846
+ * ```
847
+ *
848
+ * Adlar `Cols`'ta durduğu için `m.col("user")` hâlâ DERLENMEZ, ve `N` verildiği
849
+ * için tablo `defineSchema` içinde anahtarını kaybetmez. Kolon adlarını silen
850
+ * gevşek bir `AnyTable` KASITLI OLARAK YOK: onu yazan kişi döngüyü susturur ve
851
+ * politikasının kolon denetimini kapattığını fark etmez.
852
+ */
853
+ type TableRef<Cols extends string, N extends string = string> = TableHandle<Record<Cols, ColumnMap[string]>, N>;
827
854
  /** `.eq()` gibi metotların sağ tarafı: başka bir ifade ya da düz bir değer. */
828
855
  type PolicyOperand = PolicyExprRef | string | number | boolean | null;
829
856
  /**
@@ -855,6 +882,11 @@ interface PolicyExprCtx<Cols extends string = string> {
855
882
  * tipli ve SQL'de farklı nitelenirler. Karışsalardı `team_id = team_id`
856
883
  * üretilir ve politika hiçbir şeyi süzmezdi.
857
884
  *
885
+ * ÇIKARIM DÖNGÜSÜ: `table` iki bildirim birbirini başlatıyorsa (üyelik tablosu
886
+ * bu tabloya `references` veriyor, bu tablo da ona `existsIn` atıyor) o
887
+ * bildirime {@link TableRef} annotation'ı gerekir — yoksa TypeScript ikisini
888
+ * de TS7022 ile `any`'ye düşürür ve `m.col(…)` sessizce her adı kabul eder.
889
+ *
858
890
  * ÖZYİNELEME TUZAĞI: üyelik tablosunun KENDİ politikası `existsIn`
859
891
  * KULLANMAZ — `user_id = auth.uid()` yazar. İki tablo birbirini
860
892
  * sorgularsa Postgres sorgu anında
@@ -1004,6 +1036,44 @@ declare class PolicyBuilder {
1004
1036
  * `(table, name)`, so names must be unique per table.
1005
1037
  */
1006
1038
  declare function policy(name: string): PolicyBuilder;
1039
+ /**
1040
+ * Adlandırılmış bir CHECK kısıtı — telin bugünkü şekli, HARFİYEN.
1041
+ *
1042
+ * `expr` STRING kalıyor: `TableJSON.checks` bugün de `{ name, expr }[]` ve Go
1043
+ * tarafındaki `CheckJSON.Expr` bir string. Tipli `check()` ifadeyi bildirim
1044
+ * anında SQL'e derleyip aynı yere koyuyor, yani string dalıyla tipli dal telde
1045
+ * AYNI şeye iniyor: `NormalizeDeclaredChecks` ikisini de canlı Postgres'e
1046
+ * sorarak kanonikleştiriyor (böylece değişmemiş bir CHECK churn olarak
1047
+ * yeniden diff'lenmiyor) ve `schema-json.ts` yeni bir alan taşımıyor.
1048
+ */
1049
+ interface CheckDef {
1050
+ name: string;
1051
+ /** Derlenmiş SQL. Tipli dalda `check()` üretir, string dalda yazar verir. */
1052
+ expr: string;
1053
+ }
1054
+ /**
1055
+ * `check("<ad>", <ifade>)` — TİPLİ CHECK kısıtı (FR-009).
1056
+ *
1057
+ * İfade POLİTİKA ifade cebirinin ta kendisiyle yazılıyor; bu DSL'de iki ayrı
1058
+ * ifade dili olmaması kurulu ilke. Kolon adları `checks` callback'inin verdiği
1059
+ * bağlamdan geliyor, yani yanlış yazılmış bir ad DERLENMİYOR — bugün string
1060
+ * biçiminde o hata ancak `ALTER TABLE ... ADD CONSTRAINT` anında Postgres'ten
1061
+ * geliyor.
1062
+ *
1063
+ * ```ts
1064
+ * defineTable("payments", {
1065
+ * columns: { amount: integer().notNull(), currency: text().notNull() },
1066
+ * checks: (c) => [
1067
+ * check("payments_amount_pos", c.col("amount").gt(0)),
1068
+ * check("payments_currency_set", c.col("currency").isNull(true)),
1069
+ * ],
1070
+ * })
1071
+ * ```
1072
+ *
1073
+ * @param name Kısıtın adı. CHECK'ler ADA göre uzlaştırılıyor (gövde farkı
1074
+ * DROP + ADD demek), o yüzden ad tablo başına tekil olmalı.
1075
+ */
1076
+ declare function check(name: string, expr: PolicyExprRef): CheckDef;
1007
1077
  /**
1008
1078
  * `can` alanının YANIT şeması (FR-004, D-14).
1009
1079
  *
@@ -1057,22 +1127,336 @@ declare const EXTENSION_DEPENDENCIES: Partial<Record<PalbaseExtension, PalbaseEx
1057
1127
  /** Runtime guard: is `name` a supported Palbase extension? */
1058
1128
  declare function isPalbaseExtension(name: string): name is PalbaseExtension;
1059
1129
 
1130
+ /** `ON UPDATE` / `ON DELETE` eylemleri — Postgres'in kabul ettiği kapalı küme. */
1131
+ type FkAction = "cascade" | "restrict" | "set null" | "set default" | "no action";
1132
+ /** `MATCH` türü. `partial` Postgres'te HENÜZ uygulanmadı, o yüzden yok. */
1133
+ type FkMatch = "simple" | "full";
1134
+ /** Bir tablo düzeyi FOREIGN KEY bildirimi — C-1/C-2 (FR-001). */
1135
+ interface ForeignKeyDef {
1136
+ name: string;
1137
+ columns: string[];
1138
+ refTable: string;
1139
+ refColumns: string[];
1140
+ onUpdate?: FkAction;
1141
+ onDelete?: FkAction;
1142
+ match?: FkMatch;
1143
+ }
1144
+ /**
1145
+ * `foreignKey("<ad>")` — tablo düzeyinde, ÇOK SÜTUNLU FOREIGN KEY (C-1, FR-001).
1146
+ *
1147
+ * ```ts
1148
+ * foreignKeys: (c) => [
1149
+ * foreignKey("settlement_entry_household")
1150
+ * .on(c.col("household_id"), c.col("entry_id"))
1151
+ * .references(entries, "household_id", "id")
1152
+ * .onDelete("cascade"),
1153
+ * ]
1154
+ * ```
1155
+ *
1156
+ * NEDEN KOLON ÜZERİNDEKİ `.references()` YETMİYOR. O tek sütunlu ve tek
1157
+ * hedeflidir. Çok kiracılı bütünlüğün istediği şey
1158
+ * `FOREIGN KEY (household_id, entry_id) REFERENCES entries (household_id, id)`:
1159
+ * çocuğun ebeveyni yalnız var olmakla kalmaz, AYNI KİRACIYA ait olmak
1160
+ * zorundadır. Kolon başına model bunu ifade edemez.
1161
+ *
1162
+ * İki yol BİRBİRİNİ DÜŞÜRMEZ: bu bildirim kendi adıyla izlenir, kolon
1163
+ * üzerindekiler `<tablo>_<kolon>_fkey` ile. Aynı tabloda ikisi birden olabilir.
1164
+ */
1165
+ declare class ForeignKeyBuilder {
1166
+ readonly _def: ForeignKeyDef;
1167
+ constructor(name: string);
1168
+ /** Yerel sütunlar. SIRA KORUNUR — hedef sütunlarla birebir eşleşir. */
1169
+ on(...cols: PolicyExprRef[]): this;
1170
+ /**
1171
+ * Hedef tablo ve sütunları. Sütun sayısı `.on()`'unkiyle eşit OLMALI ve bu
1172
+ * burada, bildirim yazılırken kontrol edilir — bozuk bir FK wire'a hiç çıkmaz.
1173
+ */
1174
+ references<C extends ColumnMap, N extends string>(table: TableHandle<C, N>, ...cols: (Extract<keyof C, string>)[]): this;
1175
+ onUpdate(action: FkAction): this;
1176
+ onDelete(action: FkAction): this;
1177
+ /**
1178
+ * `MATCH FULL`: referans veren sütunların HEPSİ NULL olmadıkça kısıt
1179
+ * değerlendirilir. Varsayılan `MATCH SIMPLE`'da tek bir NULL kısıtı atlatır —
1180
+ * `freeze` bunu bilerek kullanır, sıradan bir FK'da genelde istenmez.
1181
+ */
1182
+ match(m: FkMatch): this;
1183
+ }
1184
+ declare function foreignKey(name: string): ForeignKeyBuilder;
1185
+ /**
1186
+ * Bir KOŞULLU ("donan") FOREIGN KEY bildirimi — C-5 (FR-012).
1187
+ *
1188
+ * `columns` çocuğun donan sütunları, `refColumns` ebeveynin onlara karşılık
1189
+ * gelen anahtar sütunları; ikisi SIRAYLA eşleşir. `when` doğruyken FK
1190
+ * değerlendirilir, yanlışken hiç değerlendirilmez.
1191
+ */
1192
+ interface FreezeDef {
1193
+ name: string;
1194
+ when: PolicyExpr;
1195
+ columns: string[];
1196
+ refTable: string;
1197
+ refColumns: string[];
1198
+ }
1199
+ /** Builder'ın YAZILMAKTA olan hâli: `when` henüz atanmamış olabilir. */
1200
+ type FreezeDraft = Omit<FreezeDef, "when"> & {
1201
+ when?: PolicyExpr;
1202
+ };
1203
+ /**
1204
+ * `freeze("<ad>")` — KOŞULLU FK: bir koşul sağlandığı sürece bir demeti dondurur
1205
+ * (C-5, FR-012).
1206
+ *
1207
+ * ```ts
1208
+ * freeze: (c) => [
1209
+ * freeze("pay_settled_inv")
1210
+ * .when(c.col("status").eq("settled"))
1211
+ * .columns("inv_id", "amount", "currency")
1212
+ * .references(invoices, "id", "amount", "currency"),
1213
+ * ]
1214
+ * ```
1215
+ *
1216
+ * NEDEN TRIGGER DEĞİL. Üretilen şey bir CONSTRAINT: ebeveyndeki demet üzerinde
1217
+ * bir UNIQUE, çocukta `when` sağlanmıyorken NULL veren `STORED` generated
1218
+ * sütunlar, ve bunlardan `ON UPDATE RESTRICT ON DELETE RESTRICT` bir FK.
1219
+ * `MATCH SIMPLE`'ın NULL kaçışı — "referans veren sütunlardan biri NULL ise satır
1220
+ * kısıtı sağlamak zorunda değildir" — "koşullu FK"yı `WHERE` olmadan veriyor.
1221
+ *
1222
+ * Trigger'a göre üç bedava üstünlük (canlı pg'de ölçüldü, spec Research
1223
+ * Appendix): TERS YÖN de kapanır (uyuşmayan bir çocuk `settled` yapılamaz —
1224
+ * trigger yalnız ebeveyni korurdu); koşul kalkınca donma KENDİLİĞİNDEN çözülür;
1225
+ * `pg_dump`/restore'da FK gibi davranır.
1226
+ *
1227
+ * Donan sütunlar `NOT NULL` OLMALI: nullable bir sütun `MATCH SIMPLE`'ın aynı
1228
+ * kaçışını koşuldan BAĞIMSIZ olarak açar ve donma sessizce hiç kurulmaz. Push o
1229
+ * bildirimi reddeder (FR-014).
1230
+ */
1231
+ declare class FreezeBuilder {
1232
+ readonly _def: FreezeDraft;
1233
+ constructor(name: string);
1234
+ /**
1235
+ * DONMA KOŞULU — çocuk satırının kendi kolonları üzerinde bir yüklem.
1236
+ *
1237
+ * Generated sütunlara `CASE WHEN <koşul> THEN <sütun> END` olarak iner; yani
1238
+ * koşul yanlışken sütunlar NULL olur ve FK o satır için hiç değerlendirilmez.
1239
+ */
1240
+ when(pred: PolicyExprRef): this;
1241
+ /** Çocuğun DONAN sütunları. SIRA KORUNUR — hedef sütunlarla birebir eşleşir. */
1242
+ columns(...cols: string[]): this;
1243
+ /**
1244
+ * Ebeveyn tablo ve donan demetin ORADAKİ karşılığı. Zincirin SON halkası:
1245
+ * bildirim burada tamamlanır ve tutarlılığı burada doğrulanır, yani
1246
+ * `.references()`'ı unutmuş bir freeze `FreezeDef` üretmediği için tabloya
1247
+ * hiç giremez.
1248
+ */
1249
+ references<C extends ColumnMap, N extends string>(table: TableHandle<C, N>, ...cols: (Extract<keyof C, string>)[]): FreezeDef;
1250
+ }
1251
+ declare function freeze(name: string): FreezeBuilder;
1252
+
1253
+ /**
1254
+ * guard.ts — DAR REDDEDİCİ YÜZEY (C-3, FR-015…FR-021).
1255
+ *
1256
+ * Bildirimsel kısıtların yetişemediği beş madde kaldı: write-once alanlar,
1257
+ * durum makinesi geçişleri, sabit olmayan yüklemle çapraz satır kontrolü, işlem
1258
+ * düzeyinde toplam, ve alan diline ait teşhis. RLS yolu bunlara KAPALI: `OLD` ve
1259
+ * `NEW` bir politika ifadesinde ad olarak YOKTUR (ölçüldü — red, ad çözümleme
1260
+ * düzeyinde `CREATE POLICY` anında gelir: `missing FROM-clause entry for table
1261
+ * "new"`), ve `USING`/`WITH CHECK` iki ayrı satıra karşı ayrı ayrı
1262
+ * değerlendirilir; tek ifadede iki satırı yan yana getiren bir kapsam yok.
1263
+ *
1264
+ * YAZAR ÜÇ ŞEY YAZAR: hangi olay · hangi koşul · ne diyerek reddet. Kalan sekiz
1265
+ * knob'un güvenli varsayılanı var ve bu yüzeyde HİÇ görünmüyor: `BEFORE` ·
1266
+ * `FOR EACH ROW` (Postgres'in varsayılanı `STATEMENT` ve bir guard için yanlış) ·
1267
+ * `UPDATE OF` listesi `WHEN`'den türetilir · `SET search_path = pg_catalog,
1268
+ * pg_temp` HER ZAMAN · `SECURITY INVOKER` (asla `DEFINER`) · `NOT DEFERRABLE` ·
1269
+ * `REFERENCING`/`FROM` üretilmez · `DROP IF EXISTS` + `CREATE`. Bir yeteneği
1270
+ * yüzeye çıkarmak onu politika hâline getirir; bunlar politika DEĞİL, güvenli
1271
+ * varsayılan (FR-017).
1272
+ *
1273
+ * Global bir kaçış kapısı KASITLI OLARAK YOK: django-pgtrigger'ın
1274
+ * `SET pgtrigger.ignore`'u herhangi bir oturumun guard'ı atlamasına izin veriyor
1275
+ * ve bir BaaS'ta bu kabul edilemez.
1276
+ */
1277
+ /** Guard'ın tetiklendiği yazma fiili. */
1278
+ type GuardEvent = "insert" | "update" | "delete";
1279
+ /**
1280
+ * Bir guard bildirimi — C-3/C-4 (FR-015).
1281
+ *
1282
+ * `when` satırın KENDİ kolonları üzerinde bir yüklem (trigger'ın `WHEN` yan
1283
+ * tümcesine iner), `exists` ise çapraz satır yüklemi (gövdedeki `EXISTS`
1284
+ * bloğuna). İkisi ayrı alan çünkü Postgres bir trigger'ın `WHEN` yan tümcesinde
1285
+ * ALT SORGUYA İZİN VERMİYOR (`ERROR: cannot use subquery in trigger WHEN
1286
+ * condition` — ölçüldü); ayrımı wire'da yapmak, emitter'ın yükleme bakıp
1287
+ * tahmin etmesinden daha dürüst (FR-019).
1288
+ */
1289
+ interface GuardDef {
1290
+ name: string;
1291
+ event: GuardEvent;
1292
+ when?: PolicyExpr;
1293
+ exists?: PolicyExpr;
1294
+ message: string;
1295
+ detail?: string;
1296
+ hint?: string;
1297
+ column?: string;
1298
+ }
1299
+ /** Builder'ın YAZILMAKTA olan hâli: olay ve mesaj henüz atanmamış olabilir. */
1300
+ type GuardDraft = Omit<GuardDef, "event" | "message"> & {
1301
+ event?: GuardEvent;
1302
+ message?: string;
1303
+ };
1304
+ /**
1305
+ * `guard("<ad>")` — bir yazmayı ALAN DİLİYLE reddeden trigger (C-3, FR-015).
1306
+ *
1307
+ * ```ts
1308
+ * guards: (g) => [
1309
+ * guard("documents_frozen_body")
1310
+ * .on("update")
1311
+ * .when(g.col("status").eq("archived"))
1312
+ * .refuse("Arşivlenmiş belgenin gövdesi değiştirilemez", { column: "body" }),
1313
+ * ]
1314
+ * ```
1315
+ *
1316
+ * ADI ZORUNLU (FR-016). Postgres aynı olaya bağlı trigger'ları ADA GÖRE
1317
+ * alfabetik sırayla koşar ve başka bir sıra tutamacı YOKTUR: adsız üretilmiş bir
1318
+ * guard, sırası kendi kontrolünde olmayan bir guard demektir.
1319
+ *
1320
+ * Teşhis: red `PB001` SQLSTATE'i ile gelir — `23514` KULLANILMAZ, o gerçek bir
1321
+ * CHECK ihlalinin kodu ve istemci ikisini ayırt edemezdi. Guard'ın adı
1322
+ * `CONSTRAINT` alanına gider, yani istemci mesajı PARSE ETMEDEN hangi guard'ın
1323
+ * reddettiğini okur (FR-021).
1324
+ */
1325
+ declare class GuardBuilder {
1326
+ readonly _def: GuardDraft;
1327
+ constructor(name: string);
1328
+ /** Hangi yazma fiilinde bakılacak. */
1329
+ on(event: GuardEvent): this;
1330
+ /**
1331
+ * Satırın KENDİ kolonları üzerinde koşul — trigger'ın `WHEN` yan tümcesi.
1332
+ *
1333
+ * Emitter karşılaştırmaları `IS DISTINCT FROM` ile yazar (`<>` NULL'da yanlış
1334
+ * cevap verir) ve geçen sütunlardan bir `UPDATE OF (…)` listesi türetir
1335
+ * (FR-018).
1336
+ */
1337
+ when(pred: PolicyExprRef): this;
1338
+ /**
1339
+ * ÇAPRAZ SATIR koşulu — gövdedeki `EXISTS` bloğuna iner, `WHEN`'e DEĞİL:
1340
+ * Postgres trigger `WHEN`'inde alt sorgu kabul etmiyor (FR-019).
1341
+ *
1342
+ * Yüklem içinde takma adsız kalan kolon guard'ın KENDİ satırıdır (`NEW`/`OLD`);
1343
+ * `r.col(...)` hedef tablonun kolonlarını verir ve ayrı nitelenir. Bu yüzden
1344
+ * düğümün `outer` alanı BOŞ kalır: bir guard'ın "dış satır"ı bir tablo takma
1345
+ * adı değildir.
1346
+ */
1347
+ exists<C extends ColumnMap, N extends string>(table: TableHandle<C, N>, predicate: (row: PolicyExprCtx<Extract<keyof C, string>>) => PolicyExprRef): this;
1348
+ /**
1349
+ * REDDİN KENDİSİ ve zincirin son halkası: mesaj olmadan bir guard tamamlanmaz.
1350
+ *
1351
+ * `detail`/`hint` Postgres'in aynı adlı alanlarına, `column` ise `COLUMN`
1352
+ * alanına gider — istemci hangi alanın reddedildiğini mesajı parse etmeden
1353
+ * okur.
1354
+ */
1355
+ refuse(message: string, opts?: {
1356
+ detail?: string;
1357
+ hint?: string;
1358
+ column?: string;
1359
+ }): GuardDef;
1360
+ }
1361
+ declare function guard(name: string): GuardBuilder;
1362
+
1363
+ /**
1364
+ * backfill.ts — DDL'DEN AYRI, İZLENEN, BİR KEZ KOŞAN fiil (C-6, FR-033/FR-034).
1365
+ *
1366
+ * Bir sütun eklemek bildirimseldir; o sütunu DOLDURMAK değildir. Doldurma
1367
+ * bugüne kadar `raw()` içinde yaşıyordu ve `raw()` her deploy'da yeniden
1368
+ * koşulan bir DDL bloğu — yani veri düzeltmesi ya elle bir kez çalıştırılıyor
1369
+ * (kayıt yok, tekrarı belirsiz) ya da idempotent yazılmak zorunda kalıyordu.
1370
+ *
1371
+ * `backfills:` o işi kendi aşamasına alır: DDL'den SONRA, kendi işleminde ve
1372
+ * ADI BAŞINA BİR KEZ. Kayıt `public.palbase_backfills` tablosunda tutulur, yani
1373
+ * "koştu mu" sorusunun cevabı veritabanının kendisinde durur.
1374
+ */
1375
+ /** Bir backfill bildirimi — C-6 (FR-033). */
1376
+ interface BackfillDef {
1377
+ name: string;
1378
+ sql: string;
1379
+ }
1380
+ /**
1381
+ * `backfill("<ad>", "<sql>")` — bir kez koşacak veri düzeltmesi.
1382
+ *
1383
+ * ```ts
1384
+ * backfills: [
1385
+ * backfill("ledger_currency_try", "UPDATE ledger SET currency = 'TRY' WHERE currency IS NULL"),
1386
+ * ]
1387
+ * ```
1388
+ *
1389
+ * AD, KAYDIN TA KENDİSİ. "Bu koştu mu?" sorusu ada göre cevaplanıyor, gövdeye
1390
+ * göre değil: adı sabit tutup SQL'i değiştirmek İKİNCİ bir koşu ÜRETMEZ. Bir
1391
+ * düzeltmeyi düzeltmek istiyorsan yeni bir ad verirsin — aynı adın altında
1392
+ * değişen bir gövde, canlıda hangi sürümün koştuğunu belirsiz bırakırdı.
1393
+ *
1394
+ * Bu yüzden BOŞ SQL de reddediliyor: boş bir gövde adı kayda geçirir ve o adı
1395
+ * KALICI olarak yakar — sonradan yazılan gerçek SQL "zaten koştu" diye hiç
1396
+ * çalışmaz, hiçbir yerde hata da vermez.
1397
+ *
1398
+ * SQL verbatim emit edilir (`raw()` ve `policy().using("…")` ile aynı güven
1399
+ * duruşu) ve `raw()` ile AYNI ayrıcalıklı DDL bağlantısında koşar — yalnızca
1400
+ * KENDİ AŞAMASINDA, yani DDL'den ayrı bir `Exec`'te. Ayrım budur ve tek başına
1401
+ * bir güvenlik iddiası DEĞİLDİR.
1402
+ *
1403
+ * Bu yorum daha önce "ayrıcalıklı DDL bağlantısında değil" diyordu ve YANLIŞTI.
1404
+ * Yanlış olduğu ölçüldü, ve niçin kayda geçtiği önemli: tam olarak bir
1405
+ * inceleyicinin "backfill güvenli" diye geçmesine sebep olacak cümleydi.
1406
+ *
1407
+ * Bu yüzden gövde `raw()` ile AYNI AST yetki kapısından geçiyor: rol yaratan,
1408
+ * sahiplik devreden, yetki dağıtan ya da `search_path` kaydıran bir ifade
1409
+ * taşıyan bir backfill push'u reddeder. Veri düzeltmesi veri düzeltmesidir.
1410
+ */
1411
+ declare function backfill(name: string, sql: string): BackfillDef;
1412
+
1060
1413
  /**
1061
1414
  * A named raw-SQL DDL object declared in a schema file (`db/public.ts`,
1062
- * `db/billing.ts`, …) for anything the typed DSL
1063
- * cannot express (EXCLUDE, CHECK, partial/expression indexes, triggers, views).
1415
+ * `db/billing.ts`, …) for what the typed DSL cannot express: an index method
1416
+ * other than btree (`gin`, `gist`, `brin`, `hash`), an opclass, `CONCURRENTLY`,
1417
+ * `EXCLUDE` constraints, views, and PL/pgSQL functions.
1418
+ *
1419
+ * REACH FOR THE TYPED FIELD FIRST. Most of what this list used to name is
1420
+ * declarative today and should not come through here:
1421
+ * - a CHECK constraint → `checks: [{ name, expr }]`, or the typed
1422
+ * `checks: (c) => [check(name, c.col("n").gt(0))]`
1423
+ * - a partial index → `index(n).on(…).where(…)`
1424
+ * - an expression index → `index(n).onExpression("lower(email)")`
1425
+ * - a covering index → `index(n).on(…).include([…])`
1426
+ * - a UNIQUE or PARTIAL UNIQUE index → `index(n).unique().where(…)`
1427
+ * - a composite FOREIGN KEY → `foreignKeys: (c) => [foreignKey(n).on(…).references(…)]`
1428
+ * - a conditional FK → `freeze: (c) => [freeze(n).when(…).columns(…).references(…)]`
1429
+ * - a trigger that refuses a write → `guards: (g) => [guard(n).on(…).refuse(…)]`
1430
+ * - a one-off data fix → `backfills: [backfill(name, sql)]`
1431
+ * - dropping a constraint → `dropConstraints: ["name"]`
1432
+ * Those are diffed, validated against the live database before the push, and
1433
+ * their mistakes answer you where you write them. A `raw()` is none of that.
1434
+ *
1064
1435
  * The deploy emits `up` verbatim on the privileged DDL connection — same trust
1065
- * posture as policy().using(). Tracked by NAME (not by diffing the body), so a
1066
- * changed body needs a new name or an explicit drop+add.
1436
+ * posture as policy().using(). How a CHANGED body is treated depends on what
1437
+ * `name` addresses:
1438
+ * - names a constraint or an index → tracked by NAME only; the deploy sees
1439
+ * the catalog object and skips, so an edited body does nothing. Use a new
1440
+ * name, or drop and re-add explicitly.
1441
+ * - names nothing in the catalog (functions, triggers, grants, compound
1442
+ * statements) → the last applied body is recorded in
1443
+ * `public.palbase_raw_objects` in the same DDL transaction, and an edited
1444
+ * body IS re-applied.
1445
+ *
1446
+ * There is no teardown option — not on the call, and not on this type. One used
1447
+ * to be accepted and was carried into a generated `Down` that NOTHING ever ran:
1448
+ * the engine's `MigrationFiles.Down` has no consumer and the rollback path names
1449
+ * a `runner.go` that does not exist, so an author who wrote one believed they had
1450
+ * a teardown they did not have. `raw()` stopped ACCEPTING it first, and the field
1451
+ * outlived the parameter — an object literal (`raw: [{ name, up, down }]`) still
1452
+ * compiled and still set a field nothing read. Drop what a `raw()` created by
1453
+ * declaring the drop as its own `raw()`.
1067
1454
  */
1068
1455
  interface RawConstraintDef {
1069
1456
  name: string;
1070
1457
  up: string;
1071
- down?: string;
1072
1458
  }
1073
- declare function raw(name: string, up: string, opts?: {
1074
- down?: string;
1075
- }): RawConstraintDef;
1459
+ declare function raw(name: string, up: string): RawConstraintDef;
1076
1460
 
1077
1461
  /** Embedding sağlayıcı DESKRIPTORU — canlı istemci değil, düz veri: şemayla
1078
1462
  * birlikte serileşir, çağrıyı Go worker (yazma) ve engine (sorgu) yapar.
@@ -1201,6 +1585,12 @@ interface MemoryDecl {
1201
1585
  */
1202
1586
  interface IndexDef {
1203
1587
  name: string;
1588
+ /**
1589
+ * `CREATE UNIQUE INDEX` (FR-007). `unique: [{name, columns}]` bir UNIQUE
1590
+ * CONSTRAINT üretir ve constraint'in `WHERE`'i olamaz; `index()` partial
1591
+ * olabilir ama unique olamıyordu. İki yarım vardı, birleşmiyorlardı.
1592
+ */
1593
+ unique?: boolean;
1204
1594
  columns?: string[];
1205
1595
  expression?: string;
1206
1596
  where?: PolicyExpr;
@@ -1230,6 +1620,12 @@ interface IndexDef {
1230
1620
  declare class IndexBuilder {
1231
1621
  readonly _def: IndexDef;
1232
1622
  constructor(name: string);
1623
+ /**
1624
+ * `CREATE UNIQUE INDEX` (FR-007). `.where()` ile birlikte PARTIAL UNIQUE
1625
+ * index verir (FR-007b) — "NULL'lar serbest, non-NULL'lar tekil" kalıbının
1626
+ * tek bildirimsel yolu.
1627
+ */
1628
+ unique(): this;
1233
1629
  /** Index'in kolonları. SIRA KORUNUR — çok kolonlu bir index'in anlamı sırasıdır. */
1234
1630
  on(...cols: PolicyExprRef[]): this;
1235
1631
  /**
@@ -1305,13 +1701,25 @@ interface TableInput<C extends ColumnMap = ColumnMap> {
1305
1701
  /**
1306
1702
  * Named first-class CHECK constraints. Diffed by NAME with a BODY compare:
1307
1703
  * a changed `expr` (after pg normalization) recreates the constraint
1308
- * (DROP + ADD). `expr` is trusted SQL emitted verbatim (like policy USING),
1309
- * `name` is identifier-validated.
1704
+ * (DROP + ADD). `name` is identifier-validated.
1705
+ *
1706
+ * İKİ BİÇİM, TEK TEL (FR-009, FR-011):
1707
+ *
1708
+ * - DİZİ — `expr` verbatim yayılan güvenilen SQL (policy `using` gibi).
1709
+ * Bugünkü biçim, olduğu gibi kabul edilmeye devam ediyor.
1710
+ * - CALLBACK — `(c) => [check(name, c.col("amount").gt(0))]`: ifade POLİTİKA
1711
+ * ifade cebiriyle yazılıyor ve kolon adları DERLEME anında doğrulanıyor.
1712
+ * Callback olması bunun şartı: `checks` düz bir dizi olsaydı TypeScript
1713
+ * `columns`'tan kolon adlarını çıkarıp ifadeyi onlarla bağlamlandıramazdı.
1714
+ *
1715
+ * Yanlış yazılmış bir kolon adı string biçiminde ancak
1716
+ * `ALTER TABLE … ADD CONSTRAINT` anında — deploy'un ORTASINDA — Postgres'ten
1717
+ * dönüyor. Tipli biçim aynı cevabı yazma anına taşıyor.
1718
+ *
1719
+ * Tipli ifade CHECK bağlamının DAR kümesine tabi: `existsIn` ve `auth.uid()`
1720
+ * alt sorgu oldukları için `check()` tarafından reddediliyor (FR-010).
1310
1721
  */
1311
- checks?: {
1312
- name: string;
1313
- expr: string;
1314
- }[];
1722
+ checks?: CheckDef[] | ((c: PolicyExprCtx<Extract<keyof C, string>>) => CheckDef[]);
1315
1723
  /**
1316
1724
  * Plain (non-unique) btree indexes over an ordered column list, emitted as
1317
1725
  * standalone `CREATE INDEX [IF NOT EXISTS] name ON table (col1, col2)`
@@ -1319,12 +1727,85 @@ interface TableInput<C extends ColumnMap = ColumnMap> {
1319
1727
  * Structural compare by NAME (no expression normalization). `name` and each
1320
1728
  * column are identifier-validated by the Go differ.
1321
1729
  *
1322
- * Scope: columns-only plain btree. Partial (`where`) and expression indexes
1323
- * are a deliberate follow-up modelling them needs the same raw-SQL
1324
- * normalization round-trip CHECK uses (Task 10), so they are NOT in this
1325
- * type yet to avoid a half-working partial-index path.
1730
+ * NAME is the WHOLE diff key. Editing `.where()`, `.onExpression()`,
1731
+ * `.include()` or the sort under a name that is already live does NOTHING
1732
+ * the deploy matches the name, sees the index, and skips. Give a changed
1733
+ * definition a new name.
1734
+ *
1735
+ * Scope, via `index(name)`: `.on(...cols)` · `.onExpression(sql)` (expression
1736
+ * index) · `.where(pred)` (partial index, typed predicate) · `.unique()`
1737
+ * (UNIQUE, and WITH `.where()` a PARTIAL UNIQUE index) · `.include(cols)`
1738
+ * (covering) · `.asc()`/`.desc()`/`.nulls()`. Predicates and expressions are
1739
+ * probed against the live database before the push — as a prepared statement
1740
+ * AND as a real CREATE INDEX on an empty `LIKE` clone, which is what catches
1741
+ * a subquery predicate or a non-IMMUTABLE function before the apply.
1742
+ *
1743
+ * `index(n).unique().where(p)` is the ONE declarative way to say "NULLs are
1744
+ * free, non-NULLs are unique" — the table-level `unique:` cannot carry a
1745
+ * predicate, because it renders a CONSTRAINT and PostgreSQL has no partial
1746
+ * unique CONSTRAINT (only a partial unique INDEX).
1747
+ *
1748
+ * NOT expressible here: another index method (gin/gist/brin/hash), an
1749
+ * opclass, or CONCURRENTLY.
1326
1750
  */
1327
1751
  indexes?: (p: PolicyExprCtx<Extract<keyof C, string>>) => (IndexBuilder | IndexDef)[];
1752
+ /**
1753
+ * Canlıdan DÜŞÜRÜLECEK constraint adları (FR-008).
1754
+ *
1755
+ * Differ additive: canlıda olup bildirimde olmayan bir constraint asla
1756
+ * düşürülmez — beyan dosyası veritabanının nesnelerine sahip değildir. Bu
1757
+ * alan o kuralın TEK istisnası ve açıkça yazılmış olması gerekiyor.
1758
+ *
1759
+ * Ad bilinçli olarak `retired` DEĞİL: bu DSL'de `retired` zaten "emekliye
1760
+ * ayrılmış ÇAĞRI biçimi" demek (`schema-retired-call.test.ts`).
1761
+ */
1762
+ dropConstraints?: string[];
1763
+ /**
1764
+ * Tablo düzeyinde, ÇOK SÜTUNLU FOREIGN KEY'ler (FR-001).
1765
+ *
1766
+ * Kolon üzerindeki `.references()` tek sütunlu ve tek hedeflidir; çok kiracılı
1767
+ * bütünlüğün istediği `FOREIGN KEY (tenant_id, child_id) REFERENCES parent
1768
+ * (tenant_id, id)`'yi ifade edemez. İki yol birbirini DÜŞÜRMEZ: bu bildirim
1769
+ * kendi adıyla, kolon üzerindekiler `<tablo>_<kolon>_fkey` ile izlenir.
1770
+ */
1771
+ foreignKeys?: (p: PolicyExprCtx<Extract<keyof C, string>>) => (ForeignKeyBuilder | ForeignKeyDef)[];
1772
+ /**
1773
+ * KOŞULLU FK'lar — bir koşul sağlandığı sürece donan demetler (FR-012).
1774
+ *
1775
+ * "Ödeme `settled` olduğu sürece faturanın tutarı değişemez" bir trigger
1776
+ * istemiyor: koşul sağlanmıyorken NULL veren `STORED` generated sütunlar ve
1777
+ * onlardan `ON UPDATE RESTRICT` bir FK, `MATCH SIMPLE`'ın NULL kaçışı
1778
+ * üzerinden aynı şeyi CONSTRAINT olarak veriyor.
1779
+ *
1780
+ * `foreignKeys` ile aynı sebeple callback: `when` yüklemi TABLONUN KENDİ
1781
+ * kolonlarından çözülüyor ve yanlış ad derleme hatası oluyor.
1782
+ */
1783
+ freeze?: (p: PolicyExprCtx<Extract<keyof C, string>>) => (FreezeBuilder | FreezeDef)[];
1784
+ /**
1785
+ * Bu tablonun GUARD'ları — bildirimsel kısıtın yetişemediği yazma redleri
1786
+ * (FR-015).
1787
+ *
1788
+ * Yazar üç şey yazar: hangi olay · hangi koşul · ne diyerek reddet. `BEFORE`,
1789
+ * `FOR EACH ROW`, `SECURITY INVOKER`, pinlenmiş `search_path` ve `UPDATE OF`
1790
+ * türetimi güvenli VARSAYILAN — bu yüzeyde görünmezler (FR-017).
1791
+ *
1792
+ * `policies` ile aynı sebeple callback: koşul TABLONUN KENDİ kolonlarından
1793
+ * çözülüyor ve yanlış bir ad derleme hatası oluyor. Bir guard'da yanlış kolon
1794
+ * adı, hiç ateşlemeyen bir guard demektir — güvenlik yolunda fail-open.
1795
+ */
1796
+ guards?: (p: PolicyExprCtx<Extract<keyof C, string>>) => (GuardBuilder | GuardDef)[];
1797
+ /**
1798
+ * BİR KEZ koşacak veri düzeltmeleri — DDL'den AYRI bir aşamada (FR-033).
1799
+ *
1800
+ * Sütun eklemek bildirimseldir, o sütunu DOLDURMAK değildir: doldurma bugüne
1801
+ * kadar her deploy'da yeniden koşan bir `raw()` bloğunun içindeydi. Burası o
1802
+ * işin kendi aşaması; kayıt ada göre tutuluyor ve aynı ad ikinci kez koşmuyor
1803
+ * (FR-034).
1804
+ *
1805
+ * `policies`/`guards`'ın aksine düz bir dizi: bir backfill'in yüklemi yok,
1806
+ * gövdesi verbatim SQL — bağlamlandıracak bir kolon adı da yok.
1807
+ */
1808
+ backfills?: BackfillDef[];
1328
1809
  /**
1329
1810
  * appendOnly (FR-030): tablo yalnız INSERT kabul eder — UPDATE/DELETE hem
1330
1811
  * veritabanı yetkisiyle hem üretilen tipte reddedilir (T017/T018).
@@ -1363,13 +1844,21 @@ interface TableDef<C extends ColumnMap = ColumnMap> {
1363
1844
  }[];
1364
1845
  /** Named raw-SQL DDL objects emitted verbatim on deploy. Tracked by name. */
1365
1846
  raw?: RawConstraintDef[];
1366
- /** Named first-class CHECK constraints. Diffed by name + (normalized) body. */
1367
- checks?: {
1368
- name: string;
1369
- expr: string;
1370
- }[];
1847
+ /** Named first-class CHECK constraints. Diffed by name + (normalized) body.
1848
+ * İki yazım biçimi de (dizi / callback) BURAYA iner — bkz. TableInput.checks. */
1849
+ checks?: CheckDef[];
1371
1850
  /** Index bildirimleri; partial/expression/sıra/covering alanlarıyla (FR-041…043). */
1372
1851
  indexes?: IndexDef[];
1852
+ /** Canlıdan düşürülecek constraint adları (FR-008). */
1853
+ dropConstraints?: string[];
1854
+ /** Tablo düzeyi çok sütunlu FOREIGN KEY bildirimleri (FR-001). */
1855
+ foreignKeys?: ForeignKeyDef[];
1856
+ /** Koşullu FK ("donan demet") bildirimleri (FR-012). */
1857
+ freeze?: FreezeDef[];
1858
+ /** Guard bildirimleri — bildirimsel kısıtın yetişemediği yazma redleri (FR-015). */
1859
+ guards?: GuardDef[];
1860
+ /** Bir kez koşacak veri düzeltmeleri, DDL'den ayrı aşamada (FR-033). */
1861
+ backfills?: BackfillDef[];
1373
1862
  /** appendOnly (FR-030) — bkz. TableInput. */
1374
1863
  appendOnly?: boolean;
1375
1864
  /** Arama beyanı, doğrulanmış ve taşınmış hali. */
@@ -1410,10 +1899,10 @@ type TablesByName<T extends readonly TableHandle[]> = {
1410
1899
  * title: text().notNull(),
1411
1900
  * },
1412
1901
  * rls: true,
1413
- * policies: [
1902
+ * policies: (p) => [
1414
1903
  * policy("owner_all").for("all").to("authenticated")
1415
- * .using("owner = (select auth.uid())")
1416
- * .withCheck("owner = (select auth.uid())"),
1904
+ * .using(p.col("owner").eq(p.auth.uid()))
1905
+ * .withCheck(p.col("owner").eq(p.auth.uid())),
1417
1906
  * ],
1418
1907
  * });
1419
1908
  *
@@ -4288,6 +4777,7 @@ type EnvServiceDatabase = EnvSchemaSurface & {
4288
4777
  $supersede: DBClient["supersede"];
4289
4778
  $claim: DBClient["claim"];
4290
4779
  $lockRows: DBClient["lockRows"];
4780
+ $lockRowsWhere: DBClient["lockRowsWhere"];
4291
4781
  $advisoryXactLock: DBClient["advisoryXactLock"];
4292
4782
  $attempt: DBClient["attempt"];
4293
4783
  $command<T>(fn: (tx: TxPlan) => T extends Promise<unknown> ? never : T, options?: CommandOptions): Promise<Materialized<T>>;
@@ -4359,6 +4849,7 @@ type EnvTypedDatabase = EnvSchemaSurface & {
4359
4849
  $supersede: DBClient["supersede"];
4360
4850
  $claim: DBClient["claim"];
4361
4851
  $lockRows: DBClient["lockRows"];
4852
+ $lockRowsWhere: DBClient["lockRowsWhere"];
4362
4853
  $advisoryXactLock: DBClient["advisoryXactLock"];
4363
4854
  $attempt: DBClient["attempt"];
4364
4855
  $command<T>(fn: (tx: TxPlan) => T extends Promise<unknown> ? never : T, options?: CommandOptions): Promise<Materialized<T>>;
@@ -4984,8 +5475,12 @@ declare class SerializationFailure extends Conflict implements RetryableError {
4984
5475
  * Postgres birini seçip iptal etti.
4985
5476
  *
4986
5477
  * Bu hatayı GÖRMEK bir tasarım sinyali: kilit sırası deterministik değilse
4987
- * tekrar denemek yalnız maliyeti öteler. `Database.$lockRows(...)` (FR-035)
4988
- * ya da çok satırlı yazmanın CTE'si (FR-015) sırayı sabitler.
5478
+ * tekrar denemek yalnız maliyeti öteler. Sırayı sabitleyen üç şey var ve
5479
+ * hangisinin geçerli olduğunu ELİNDEKİ belirler: satırların id'leri elindeyse
5480
+ * `Database.$lockRows(tablo, id'ler)`, elinde bir FİLTRE varsa
5481
+ * `Database.$lockRowsWhere(tablo, filtre)` (FR-037 — birincil anahtara göre
5482
+ * sıralayarak kilitler, yani `updateMany` ile aynı sırayı paylaşır), ya da çok
5483
+ * satırlı yazmanın CTE'si (FR-015).
4989
5484
  */
4990
5485
  declare class DeadlockDetected extends Conflict implements RetryableError {
4991
5486
  readonly retryable: true;
@@ -5203,6 +5698,37 @@ interface DBOps {
5203
5698
  * `FOR NO KEY UPDATE` — `updateMany`'nin CTE'siyle aynı mod.
5204
5699
  */
5205
5700
  lockRows(table: string, ids: readonly string[]): Promise<void>;
5701
+ /**
5702
+ * Bir FİLTRENİN eşleştiği satırları kilitle — sırayı yine KATMAN koyar
5703
+ * (FR-037).
5704
+ *
5705
+ * `lockRows` kilitlenecek kümeyi çağıranın SAYMASINI istiyor. "Bu hesabın
5706
+ * bekleyen bütün hareketlerini kilitle" bunu yapamaz: id listesi ancak bir
5707
+ * sorguyla çıkar, ve o sorgu ile kilit arasındaki boşluk tam olarak kilidin
5708
+ * kapatması gereken yarıştır. Bu biçim kümeyi TEK statement'ta hem seçer hem
5709
+ * kilitler.
5710
+ *
5711
+ * ```ts
5712
+ * await db.lockRowsWhere("entries", { account_id: id, status: "pending" });
5713
+ * const rows = await db.findMany("entries", { account_id: id, status: "pending" });
5714
+ * ```
5715
+ *
5716
+ * `ORDER BY <pk>` — `updateMany`'nin kilit CTE'siyle AYNI sıra, yani aynı
5717
+ * satır kümesine giren iki yol birbirini deadlock'a sokmaz (FR-037b, canlı
5718
+ * kanıt: `v2/internal/schema/lock_order_test.go`).
5719
+ *
5720
+ * MOD ÇAĞIRANIN SEÇİMİ ve eşitlenmez: `"update"` (varsayılan, `FOR UPDATE`),
5721
+ * `"share"` (`FOR SHARE` — "ben okurken kimse değiştirmesin"), `"noKeyUpdate"`
5722
+ * (`FOR NO KEY UPDATE` — `updateMany`'nin modu, anahtar dışı alanları
5723
+ * değiştirecek yazmalar için). Herkesi tek moda zorlamak, okuma kilidi
5724
+ * isteyeni ihtiyacından fazlasını almaya zorlardı.
5725
+ *
5726
+ * BOŞ FİLTRE REDDEDİLİR: bütün tabloyu kilitlemek kazayla ulaşılacak bir yer
5727
+ * değil.
5728
+ */
5729
+ lockRowsWhere(table: string, where: Record<string, unknown>, opts?: {
5730
+ mode?: "update" | "share" | "noKeyUpdate";
5731
+ }): Promise<void>;
5206
5732
  /**
5207
5733
  * Bir ADI kilitle — satırı değil (FR-054). Kilitlenecek satırı olmayan
5208
5734
  * işler için ("aynı anda tek bir fatura kapanışı koşsun").
@@ -5614,4 +6140,4 @@ type Middleware = (ctx: MiddlewareContext, next: () => Promise<void>) => Promise
5614
6140
  */
5615
6141
  type AuthSpec = boolean | Partial<AuthConfig>;
5616
6142
 
5617
- export { Flags as $, type AuthSpec as A, BadRequest as B, type CommandOptions as C, type DatabaseBudget as D, type EnvServiceDatabase as E, Conflict as F, Database as G, HttpError as H, type DatabaseQueryEvent as I, DeadlockDetected as J, Documents as K, EXTENSION_DEPENDENCIES as L, type EmbeddingModelRef as M, type EnvSchemas as N, type EnvTables as O, type Page as P, type EnvTypedDatabase as Q, type RateLimitConfig as R, type SchemaDef as S, type TransactionIsolation as T, type EnvTypedTable as U, type ErrorDef as V, type ErrorMap as W, type ErrorThrowers as X, type FileContext as Y, type FindManyOpts as Z, __runWithRuntime as _, type DBClient as a, type PalbaseFlagValue as a$, Forbidden as a0, type HttpMethod as a1, IndexBuilder as a2, type IndexDef as a3, type InsertManyOptions as a4, type InsertShape as a5, type InsertValues as a6, type LifecycleHook as a7, Log as a8, type Logger as a9, type PalbaseBatchSetOverridesResult as aA, type PalbaseBindDeviceParams as aB, type PalbaseBucketClient as aC, type PalbaseClearAllOverridesResult as aD, type PalbaseClearOverrideResult as aE, type PalbaseCohortQueryInput as aF, type PalbaseCohortResult as aG, type PalbaseCollectionRef as aH, type PalbaseCountQueryInput as aI, type PalbaseCountResult as aJ, type PalbaseCreateLinkParams as aK, type PalbaseDeviceInfo as aL, type PalbaseDeviceTokenView as aM, type PalbaseDocsClient as aN, type PalbaseDocumentRef as aO, type PalbaseDocumentSnapshot as aP, type PalbaseEmailClient as aQ, type PalbaseEmailSendParams as aR, type PalbaseEmailSendResponse as aS, type PalbaseEventNamesResult as aT, type PalbaseEventsQueryInput as aU, type PalbaseEventsResult as aV, type PalbaseExtension as aW, type PalbaseFileObject as aX, type PalbaseFlag as aY, type PalbaseFlagContext as aZ, type PalbaseFlagSource as a_, type Materialized as aa, type Middleware as ab, type MiddlewareContext as ac, type MiddlewareHandler as ad, type MutateInput as ae, NotFound as af, Notifications as ag, type OnDeleteAction as ah, type OrderBySpec as ai, PALBASE_EXTENSIONS as aj, type PBRequest as ak, type PageInfo as al, type PageInput as am, type PageNavigation as an, PalError as ao, type PalbaseAnalyticsClient as ap, type PalbaseAnalyticsManagementNamespace as aq, type PalbaseAnalyticsProperties as ar, type PalbaseAnalyticsQueryNamespace as as, type PalbaseAttestAndroidParams as at, type PalbaseAttestAndroidResult as au, type PalbaseAttestiOSParams as av, type PalbaseAttestiOSResult as aw, type PalbaseAuthAdminClient as ax, type PalbaseAuthClient as ay, type PalbaseBatchOverrideOperation as az, type RuntimeServices as b, type PolicyDef as b$, type PalbaseFlagVariant as b0, type PalbaseFlagsClient as b1, type PalbaseFlagsServiceClient as b2, type PalbaseFunctionsClient as b3, type PalbaseFunnelQueryInput as b4, type PalbaseFunnelResult as b5, type PalbaseIdentifyTraits as b6, type PalbaseInboxClient as b7, type PalbaseInboxListOptions as b8, type PalbaseInboxListResult as b9, type PalbaseRetentionQueryInput as bA, type PalbaseRetentionResult as bB, type PalbaseSession as bC, type PalbaseSetOverrideResult as bD, type PalbaseSetOverridesResult as bE, type PalbaseSignedUrlResponse as bF, type PalbaseSmsClient as bG, type PalbaseSmsSendParams as bH, type PalbaseSmsSendResponse as bI, type PalbaseStorageClient as bJ, type PalbaseTransformOptions as bK, type PalbaseUpdateLinkParams as bL, type PalbaseUploadOptions as bM, type PalbaseUser as bN, type PalbaseUserDetailResult as bO, type PalbaseUsersQueryInput as bP, type PalbaseUsersResult as bQ, type PalbaseVerifyRequestSignatureParams as bR, type PalbaseWhatsAppClient as bS, type PalbaseWhatsAppEvent as bT, type PalbaseWhatsAppSendParams as bU, type PalbaseWhatsAppSendResponse as bV, type PalbaseWhatsAppTemplate as bW, type PalbaseWhereOperator as bX, type PolicyBinOp as bY, PolicyBuilder as bZ, type PolicyCommand as b_, type PalbaseInboxMessage as ba, type PalbaseInboxSendParams as bb, type PalbaseInboxSendResponse as bc, type PalbaseInitialLink as bd, type PalbaseInvokeOptions as be, type PalbaseLink as bf, type PalbaseLinkAnalytics as bg, type PalbaseLinkDetails as bh, type PalbaseLinksClient as bi, type PalbaseListLinksOptions as bj, type PalbaseListLinksResult as bk, type PalbaseListOptions as bl, type PalbaseMatchParams as bm, type PalbaseMultiChannelResponse as bn, type PalbaseNotificationChannel as bo, type PalbaseNotificationsClient as bp, type PalbaseOverviewResult as bq, type PalbasePreferences as br, type PalbasePreferencesClient as bs, type PalbasePushClient as bt, type PalbasePushSendParams as bu, type PalbasePushSendResponse as bv, type PalbaseQrCodeOptions as bw, type PalbaseQuerySnapshot as bx, type PalbaseRealtimeClient as by, type PalbaseRegisterDeviceParams as bz, type DatabaseDiagnosticsOptions as c, col as c$, type PolicyExprCtx as c0, PolicyExprRef as c1, type PolicyMode as c2, type PolicyOperand as c3, type QueryInput as c4, type RawConstraintDef as c5, Realtime as c6, type Ref as c7, type RequestStore as c8, type RowShape as c9, type TxSetShape as cA, type TxSetValue as cB, type TxTable as cC, type TxTables as cD, type TxWhere as cE, type TxWireExpr as cF, type TxWireGuard as cG, type TxWireOp as cH, type TxWireRef as cI, type TxWireValue as cJ, type TypedDB as cK, type TypedTable as cL, type TypedTx as cM, Unauthorized as cN, UniqueViolation as cO, type UniqueWhere as cP, type User as cQ, type VerifiedDevice as cR, type WhereFilter as cS, type WhereOp as cT, __getRuntime as cU, __resetLifecycleHooks as cV, __runStartHooks as cW, __setRuntime as cX, bigint as cY, boolean as cZ, can as c_, Secrets as ca, type SecretsService as cb, SerializationFailure as cc, type SetShape as cd, type SetValue as ce, type ShutdownRunner as cf, type SqlFragment as cg, Storage as ch, TABLE_META as ci, type TableDef as cj, type TableHandle as ck, type TableInput as cl, TooManyRequests as cm, type TxColumnExpr as cn, type TxInsertShape as co, type TxInsertValue as cp, type TxNow as cq, type TxPlan as cr, TxPlanError as cs, type TxPlanHandle as ct, type TxPlanOpResult as cu, type TxPlanRejection as cv, TxRefError as cw, type TxRow as cx, type TxRows as cy, type TxSelectOptions as cz, type DatabaseDiagnostics as d, dec as d0, decrement as d1, defineMiddleware as d2, defineSchema as d3, defineTable as d4, enumType as d5, exprCtx as d6, inc as d7, increment as d8, index as d9, installationRef as da, integer as db, isPalbaseExtension as dc, isRetryable as dd, jsonb as de, makeTypedDB as df, now as dg, numeric as dh, onShutdown as di, onStart as dj, openai as dk, ownedByUser as dl, policy as dm, raw as dn, sqlFragment as dp, text as dq, timestamp as dr, userRef as ds, uuid as dt, vector as du, withRetry as dv, type DBOps as e, type RawPageOptions as f, type TxPlanBody as g, type TxPlanResponse as h, type CacheClient as i, __requestALS as j, type PalbaseResult as k, type PolicyExpr as l, type AggregateInput as m, type AggregateResult as n, type AnyColumn as o, type AtomicDatabase as p, type AtomicOptions as q, Auth as r, type AuthConfig as s, Cache as t, type ClientInfo as u, type ColRef as v, ColumnBuilder as w, type ColumnDef as x, type ColumnMap as y, type ColumnType as z };
6143
+ export { type FileContext as $, type AuthSpec as A, type BackfillDef as B, type CommandOptions as C, type DatabaseBudget as D, type EnvServiceDatabase as E, type ColumnMap as F, type ColumnType as G, HttpError as H, Conflict as I, Database as J, type DatabaseQueryEvent as K, DeadlockDetected as L, Documents as M, EXTENSION_DEPENDENCIES as N, type EmbeddingModelRef as O, type Page as P, type EnvSchemas as Q, type RateLimitConfig as R, type SchemaDef as S, type TransactionIsolation as T, type EnvTables as U, type EnvTypedDatabase as V, type EnvTypedTable as W, type ErrorDef as X, type ErrorMap as Y, type ErrorThrowers as Z, __runWithRuntime as _, type DBClient as a, type PalbaseEmailClient as a$, type FindManyOpts as a0, type FkAction as a1, type FkMatch as a2, Flags as a3, Forbidden as a4, ForeignKeyBuilder as a5, type ForeignKeyDef as a6, FreezeBuilder as a7, type FreezeDef as a8, GuardBuilder as a9, type PalbaseAnalyticsClient as aA, type PalbaseAnalyticsManagementNamespace as aB, type PalbaseAnalyticsProperties as aC, type PalbaseAnalyticsQueryNamespace as aD, type PalbaseAttestAndroidParams as aE, type PalbaseAttestAndroidResult as aF, type PalbaseAttestiOSParams as aG, type PalbaseAttestiOSResult as aH, type PalbaseAuthAdminClient as aI, type PalbaseAuthClient as aJ, type PalbaseBatchOverrideOperation as aK, type PalbaseBatchSetOverridesResult as aL, type PalbaseBindDeviceParams as aM, type PalbaseBucketClient as aN, type PalbaseClearAllOverridesResult as aO, type PalbaseClearOverrideResult as aP, type PalbaseCohortQueryInput as aQ, type PalbaseCohortResult as aR, type PalbaseCollectionRef as aS, type PalbaseCountQueryInput as aT, type PalbaseCountResult as aU, type PalbaseCreateLinkParams as aV, type PalbaseDeviceInfo as aW, type PalbaseDeviceTokenView as aX, type PalbaseDocsClient as aY, type PalbaseDocumentRef as aZ, type PalbaseDocumentSnapshot as a_, type GuardDef as aa, type GuardEvent as ab, type HttpMethod as ac, IndexBuilder as ad, type IndexDef as ae, type InsertManyOptions as af, type InsertShape as ag, type InsertValues as ah, type LifecycleHook as ai, Log as aj, type Logger as ak, type Materialized as al, type Middleware as am, type MiddlewareContext as an, type MiddlewareHandler as ao, type MutateInput as ap, NotFound as aq, Notifications as ar, type OnDeleteAction as as, type OrderBySpec as at, PALBASE_EXTENSIONS as au, type PBRequest as av, type PageInfo as aw, type PageInput as ax, type PageNavigation as ay, PalError as az, type RuntimeServices as b, type PalbaseUsersResult as b$, type PalbaseEmailSendParams as b0, type PalbaseEmailSendResponse as b1, type PalbaseEventNamesResult as b2, type PalbaseEventsQueryInput as b3, type PalbaseEventsResult as b4, type PalbaseExtension as b5, type PalbaseFileObject as b6, type PalbaseFlag as b7, type PalbaseFlagContext as b8, type PalbaseFlagSource as b9, type PalbaseNotificationsClient as bA, type PalbaseOverviewResult as bB, type PalbasePreferences as bC, type PalbasePreferencesClient as bD, type PalbasePushClient as bE, type PalbasePushSendParams as bF, type PalbasePushSendResponse as bG, type PalbaseQrCodeOptions as bH, type PalbaseQuerySnapshot as bI, type PalbaseRealtimeClient as bJ, type PalbaseRegisterDeviceParams as bK, type PalbaseRetentionQueryInput as bL, type PalbaseRetentionResult as bM, type PalbaseSession as bN, type PalbaseSetOverrideResult as bO, type PalbaseSetOverridesResult as bP, type PalbaseSignedUrlResponse as bQ, type PalbaseSmsClient as bR, type PalbaseSmsSendParams as bS, type PalbaseSmsSendResponse as bT, type PalbaseStorageClient as bU, type PalbaseTransformOptions as bV, type PalbaseUpdateLinkParams as bW, type PalbaseUploadOptions as bX, type PalbaseUser as bY, type PalbaseUserDetailResult as bZ, type PalbaseUsersQueryInput as b_, type PalbaseFlagValue as ba, type PalbaseFlagVariant as bb, type PalbaseFlagsClient as bc, type PalbaseFlagsServiceClient as bd, type PalbaseFunctionsClient as be, type PalbaseFunnelQueryInput as bf, type PalbaseFunnelResult as bg, type PalbaseIdentifyTraits as bh, type PalbaseInboxClient as bi, type PalbaseInboxListOptions as bj, type PalbaseInboxListResult as bk, type PalbaseInboxMessage as bl, type PalbaseInboxSendParams as bm, type PalbaseInboxSendResponse as bn, type PalbaseInitialLink as bo, type PalbaseInvokeOptions as bp, type PalbaseLink as bq, type PalbaseLinkAnalytics as br, type PalbaseLinkDetails as bs, type PalbaseLinksClient as bt, type PalbaseListLinksOptions as bu, type PalbaseListLinksResult as bv, type PalbaseListOptions as bw, type PalbaseMatchParams as bx, type PalbaseMultiChannelResponse as by, type PalbaseNotificationChannel as bz, type DatabaseDiagnosticsOptions as c, type UniqueWhere as c$, type PalbaseVerifyRequestSignatureParams as c0, type PalbaseWhatsAppClient as c1, type PalbaseWhatsAppEvent as c2, type PalbaseWhatsAppSendParams as c3, type PalbaseWhatsAppSendResponse as c4, type PalbaseWhatsAppTemplate as c5, type PalbaseWhereOperator as c6, type PolicyBinOp as c7, PolicyBuilder as c8, type PolicyCommand as c9, type TxInsertShape as cA, type TxInsertValue as cB, type TxNow as cC, type TxPlan as cD, TxPlanError as cE, type TxPlanHandle as cF, type TxPlanOpResult as cG, type TxPlanRejection as cH, TxRefError as cI, type TxRow as cJ, type TxRows as cK, type TxSelectOptions as cL, type TxSetShape as cM, type TxSetValue as cN, type TxTable as cO, type TxTables as cP, type TxWhere as cQ, type TxWireExpr as cR, type TxWireGuard as cS, type TxWireOp as cT, type TxWireRef as cU, type TxWireValue as cV, type TypedDB as cW, type TypedTable as cX, type TypedTx as cY, Unauthorized as cZ, UniqueViolation as c_, type PolicyDef as ca, type PolicyExprCtx as cb, PolicyExprRef as cc, type PolicyMode as cd, type PolicyOperand as ce, type QueryInput as cf, type RawConstraintDef as cg, Realtime as ch, type Ref as ci, type RequestStore as cj, type RowShape as ck, Secrets as cl, type SecretsService as cm, SerializationFailure as cn, type SetShape as co, type SetValue as cp, type ShutdownRunner as cq, type SqlFragment as cr, Storage as cs, TABLE_META as ct, type TableDef as cu, type TableHandle as cv, type TableInput as cw, type TableRef as cx, TooManyRequests as cy, type TxColumnExpr as cz, type DatabaseDiagnostics as d, type User as d0, type VerifiedDevice as d1, type WhereFilter as d2, type WhereOp as d3, __getRuntime as d4, __resetLifecycleHooks as d5, __runStartHooks as d6, __setRuntime as d7, backfill as d8, bigint as d9, onShutdown as dA, onStart as dB, openai as dC, ownedByUser as dD, policy as dE, raw as dF, sqlFragment as dG, text as dH, timestamp as dI, userRef as dJ, uuid as dK, vector as dL, withRetry as dM, boolean as da, can as db, check as dc, col as dd, dec as de, decrement as df, defineMiddleware as dg, defineSchema as dh, defineTable as di, enumType as dj, exprCtx as dk, foreignKey as dl, freeze as dm, guard as dn, inc as dp, increment as dq, index as dr, installationRef as ds, integer as dt, isPalbaseExtension as du, isRetryable as dv, jsonb as dw, makeTypedDB as dx, now as dy, numeric as dz, type DBOps as e, type RawPageOptions as f, type TxPlanBody as g, type TxPlanResponse as h, type CacheClient as i, __requestALS as j, type PalbaseResult as k, type PolicyExpr as l, type AggregateInput as m, type AggregateResult as n, type AnyColumn as o, type AtomicDatabase as p, type AtomicOptions as q, Auth as r, type AuthConfig as s, BadRequest as t, Cache as u, type CheckDef as v, type ClientInfo as w, type ColRef as x, ColumnBuilder as y, type ColumnDef as z };