{"id":30781,"date":"2025-10-02T02:32:14","date_gmt":"2025-10-01T23:32:14","guid":{"rendered":"https:\/\/fatihsoysal.com\/blog\/luks-restoran-rezervasyon-sistemi-next-js-prisma-ile-nasil-yapilir\/"},"modified":"2025-10-02T02:32:14","modified_gmt":"2025-10-01T23:32:14","slug":"luks-restoran-rezervasyon-sistemi-next-js-prisma-ile-nasil-yapilir","status":"publish","type":"post","link":"https:\/\/fatihsoysal.com\/blog\/luks-restoran-rezervasyon-sistemi-next-js-prisma-ile-nasil-yapilir\/","title":{"rendered":"L\u00fcks Restoran Rezervasyon Sistemi: Next.js &amp; Prisma ile Nas\u0131l Yap\u0131l\u0131r?"},"content":{"rendered":"<p><body><\/p>\n<p>L\u00fcks restoranlarda rezervasyon yapmak, bazen yorucu bir s\u00fcre\u00e7 haline gelebilir. Peki, modern web teknolojilerini kullanarak, bu deneyimi hem restoranlar hem de m\u00fc\u015fteriler i\u00e7in p\u00fcr\u00fczs\u00fcz ve keyifli bir hale getirebilir miyiz? Bu makalede, Next.js ve Prisma ikilisinin g\u00fcc\u00fcn\u00fc birle\u015ftirerek nas\u0131l \u00fcst d\u00fczey bir restoran rezervasyon sistemi geli\u015ftirebilece\u011fimizi ad\u0131m ad\u0131m inceleyece\u011fiz. Bu rehber, sadece teknik detaylar\u0131 de\u011fil, ayn\u0131 zamanda kullan\u0131c\u0131 deneyimi ve \u00f6l\u00e7eklenebilirlik gibi kritik fakt\u00f6rleri de kapsayarak, projeyi s\u0131f\u0131rdan hayata ge\u00e7irmenize yard\u0131mc\u0131 olacak.<\/p>\n<p>G\u00fcn\u00fcm\u00fcz\u00fcn dijital \u00e7a\u011f\u0131nda, kullan\u0131c\u0131lar\u0131n beklentileri her zamankinden daha y\u00fcksek. \u00d6zellikle l\u00fcks segmentte hizmet veren restoranlar i\u00e7in, rezervasyon s\u00fcrecinin karma\u015f\u0131kl\u0131\u011f\u0131, m\u00fc\u015fteri memnuniyetini do\u011frudan etkileyen kritik bir fakt\u00f6r. Telefon trafi\u011fi, manuel ajandalar, \u00e7ak\u0131\u015fan rezervasyonlar ve son dakika iptallerinin yaratt\u0131\u011f\u0131 operasyonel y\u00fck, \u00e7o\u011fu zaman restoranlar\u0131n k\u00e2rl\u0131l\u0131\u011f\u0131n\u0131 ve itibar\u0131n\u0131 olumsuz etkileyebilir. M\u00fc\u015fteriler ise, \u00f6zel bir ak\u015fam yeme\u011fi planlarken, h\u0131zl\u0131, kolay ve hatas\u0131z bir rezervasyon deneyimi aray\u0131\u015f\u0131ndad\u0131rlar. Peki, bu sorunu modern bir yakla\u015f\u0131mla, \u00f6l\u00e7eklenebilir ve g\u00fcvenilir bir teknoloji altyap\u0131s\u0131yla \u00e7\u00f6zebilir miyiz?<\/p>\n<p>Kesinlikle evet! \u0130\u015fte tam bu noktada, Next.js ve Prisma gibi g\u00fc\u00e7l\u00fc ara\u00e7lar devreye giriyor. Next.js, React tabanl\u0131, server-side rendering (SSR) ve static site generation (SSG) yetenekleriyle \u00f6ne \u00e7\u0131kan bir framework olarak, hem h\u0131zl\u0131 ve SEO dostu frontendler olu\u015fturmam\u0131za olanak tan\u0131r hem de API rotalar\u0131 sayesinde g\u00fc\u00e7l\u00fc bir backend altyap\u0131s\u0131 sunar. Bu sayede, dinamik i\u00e7erik sunumu ve h\u0131zl\u0131 sayfa y\u00fckleme s\u00fcreleri sayesinde kullan\u0131c\u0131 deneyimini zirveye ta\u015f\u0131yabiliriz. \u00d6te yandan Prisma, veritaban\u0131 etkile\u015fimini basitle\u015ftiren, tip g\u00fcvenli\u011fine sahip ve geli\u015ftirici dostu bir ORM (Object-Relational Mapper) arac\u0131d\u0131r. Karma\u015f\u0131k SQL sorgular\u0131 yazmak yerine, TypeScript\u2019in g\u00fcc\u00fcn\u00fc kullanarak veritaban\u0131 i\u015flemlerini \u00e7ok daha okunabilir ve y\u00f6netilebilir hale getirebiliriz. Bu ikili, l\u00fcks bir restoran\u0131n t\u00fcm rezervasyon ihtiya\u00e7lar\u0131n\u0131 kar\u015f\u0131layacak, y\u00fcksek performansl\u0131 ve g\u00fcvenli bir sistemin temelini atmak i\u00e7in ideal bir kombinasyondur. \u00d6rne\u011fin, yo\u011fun saatlerde binlerce e\u015f zamanl\u0131 rezervasyon talebini sorunsuz bir \u015fekilde y\u00f6netmek veya anl\u0131k masa m\u00fcsaitli\u011fi g\u00fcncellemeleri sunmak, Next.js ve Prisma ile olduk\u00e7a ger\u00e7ek\u00e7i hale gelir. Bu yakla\u015f\u0131m, sadece operasyonel verimlili\u011fi art\u0131rmakla kalmayacak, ayn\u0131 zamanda m\u00fc\u015fterilere sunulan hizmet kalitesini de g\u00f6zle g\u00f6r\u00fcl\u00fcr \u015fekilde y\u00fckseltecektir. Dolay\u0131s\u0131yla, l\u00fcks bir restoran\u0131n marka de\u011ferine yak\u0131\u015f\u0131r, teknolojik olarak geli\u015fmi\u015f bir rezervasyon sistemi in\u015fa etmek, art\u0131k hayal de\u011fil, ula\u015f\u0131labilir bir hedeftir.<\/p>\n<h2>\ud83d\udee0\ufe0f Temel Ta\u015flar: Next.js ve Prisma Neden \u0130deal Bir \u0130kili?<\/h2>\n<p>Bir l\u00fcks restoran rezervasyon sistemi gibi karma\u015f\u0131k bir uygulamay\u0131 geli\u015ftirirken do\u011fru teknolojileri se\u00e7mek, projenin ba\u015far\u0131s\u0131 i\u00e7in kritik \u00f6neme sahiptir. Bu ba\u011flamda, Next.js ve Prisma, modern web geli\u015ftirmenin sundu\u011fu en g\u00fc\u00e7l\u00fc ara\u00e7lardan ikisidir ve birlikte benzersiz avantajlar sunarlar. Bu iki teknolojinin neden ideal bir ikili oldu\u011funu daha yak\u0131ndan inceleyelim.<\/p>\n<h3>Next.js: Frontend&#8217;in ve Hafif Backend&#8217;in G\u00fcc\u00fc<\/h3>\n<p>Next.js, bir React framework&#8217;\u00fc olmas\u0131n\u0131n \u00f6tesinde, tam te\u015fekk\u00fcll\u00fc bir web geli\u015ftirme platformu olarak kabul edilir. Sundu\u011fu \u00f6zellikler sayesinde, sadece estetik ve reaktif kullan\u0131c\u0131 aray\u00fczleri olu\u015fturmakla kalmaz, ayn\u0131 zamanda sunucu taraf\u0131nda i\u015flenen (Server-Side Rendered &#8211; SSR) sayfalar ve statik olarak olu\u015fturulan (Static Site Generated &#8211; SSG) i\u00e7erikler arac\u0131l\u0131\u011f\u0131yla performans ve SEO a\u00e7\u0131s\u0131ndan da b\u00fcy\u00fck avantajlar sa\u011flar. L\u00fcks bir restoran\u0131n web sitesi i\u00e7in h\u0131zl\u0131 y\u00fckleme s\u00fcreleri ve arama motorlar\u0131nda \u00fcst s\u0131ralarda yer almak, m\u00fc\u015fteri \u00e7ekmek a\u00e7\u0131s\u0131ndan hayati \u00f6neme sahiptir. Next.js&#8217;in sundu\u011fu otomatik kod b\u00f6lme (automatic code splitting) ve g\u00f6r\u00fcnt\u00fc optimizasyonu gibi \u00f6zellikler, bu hedeflere ula\u015fmay\u0131 kolayla\u015ft\u0131r\u0131r. Ayr\u0131ca, Next.js&#8217;in yerle\u015fik API Routes \u00f6zelli\u011fi, ayr\u0131 bir backend projesi kurma ihtiyac\u0131n\u0131 ortadan kald\u0131rarak, uygulamam\u0131z\u0131n hem frontend hem de backend k\u0131s\u0131mlar\u0131n\u0131 tek bir codebase i\u00e7inde geli\u015ftirmemizi sa\u011flar. Bu, geli\u015ftirme s\u00fcrecini basitle\u015ftirir, deploy (da\u011f\u0131t\u0131m) s\u00fcre\u00e7lerini h\u0131zland\u0131r\u0131r ve genel proje y\u00f6netimini kolayla\u015ft\u0131r\u0131r. \u00d6zellikle rezervasyon taleplerini i\u015flemek, kullan\u0131c\u0131 do\u011frulamas\u0131n\u0131 sa\u011flamak ve restoran bilgilerini sunmak gibi g\u00f6revler i\u00e7in bu API Routes, olduk\u00e7a verimli bir \u00e7\u00f6z\u00fcm sunar. \u00d6rne\u011fin, bir kullan\u0131c\u0131n\u0131n belirli bir tarih ve saat aral\u0131\u011f\u0131ndaki m\u00fcsait masalar\u0131 sorgulad\u0131\u011f\u0131 bir senaryoda, Next.js API route&#8217;u h\u0131zla veritaban\u0131ndan veri \u00e7ekip an\u0131nda geri d\u00f6nebilir, b\u00f6ylece kullan\u0131c\u0131ya kesintisiz bir deneyim sunulur.<\/p>\n<h3>Prisma: Veritaban\u0131 Y\u00f6netimini Basitle\u015ftiren K\u00f6pr\u00fc<\/h3>\n<p>Prisma, modern bir veritaban\u0131 ara\u00e7 seti olup, ORM yetenekleriyle \u00f6n plana \u00e7\u0131kar. Geleneksel ORM&#8217;lerden farkl\u0131 olarak, veritaban\u0131 etkile\u015fimlerini TypeScript ile u\u00e7tan uca tip g\u00fcvenli\u011fi sa\u011flayarak geli\u015ftirir. Bu, geli\u015ftirme s\u0131ras\u0131nda potansiyel hatalar\u0131 yakalamay\u0131 kolayla\u015ft\u0131r\u0131r ve kodun daha okunabilir, s\u00fcrd\u00fcr\u00fclebilir olmas\u0131n\u0131 sa\u011flar. Rezervasyon sistemi gibi veri yo\u011fun bir uygulamada, verilerin do\u011fru bir \u015fekilde saklanmas\u0131, al\u0131nmas\u0131 ve g\u00fcncellenmesi b\u00fcy\u00fck \u00f6nem ta\u015f\u0131r. Prisma&#8217;n\u0131n Schema-first yakla\u015f\u0131m\u0131, veritaban\u0131 \u015femam\u0131z\u0131 (\u00f6rne\u011fin, <code>Restaurant<\/code>, <code>Reservation<\/code>, <code>User<\/code> modelleri) tek bir <code>schema.prisma<\/code> dosyas\u0131nda tan\u0131mlamam\u0131za olanak tan\u0131r. Bu \u015fema \u00fczerinden otomatik olarak bir Prisma Client olu\u015fturulur ve bu client, uygulamam\u0131z\u0131n veritaban\u0131yla g\u00fcvenli ve tip kontroll\u00fc bir \u015fekilde ileti\u015fim kurmas\u0131n\u0131 sa\u011flar. Destekledi\u011fi veritabanlar\u0131 aras\u0131nda PostgreSQL, MySQL, SQLite, SQL Server ve MongoDB (Preview) gibi pop\u00fcler se\u00e7enekler bulunur, bu da projenizin ihtiya\u00e7lar\u0131na g\u00f6re esneklik sa\u011flar. Prisma&#8217;n\u0131n migration (g\u00f6\u00e7) ara\u00e7lar\u0131 sayesinde, veritaban\u0131 \u015femas\u0131nda yap\u0131lan de\u011fi\u015fiklikleri g\u00fcvenli bir \u015fekilde y\u00f6netebilir ve da\u011f\u0131tabiliriz. \u00d6rne\u011fin, yeni bir \u00f6zellik eklendi\u011finde ve bu, veritaban\u0131 yap\u0131s\u0131nda bir de\u011fi\u015fiklik gerektirdi\u011finde, Prisma migration&#8217;lar\u0131 bu de\u011fi\u015fikliklerin izlenmesini ve uygulanmas\u0131n\u0131 sorunsuz hale getirir. Bu, \u00f6zellikle \u00fcretim ortam\u0131nda canl\u0131 bir sistemi g\u00fcncellerken b\u00fcy\u00fck bir g\u00fcvence sa\u011flar. Next.js API Routes i\u00e7inde Prisma Client&#8217;\u0131 kullanmak, hem frontend hem de backend logic&#8217;ini TypeScript&#8217;in sa\u011flad\u0131\u011f\u0131 avantajlarla birle\u015ftirerek, geli\u015ftirme h\u0131z\u0131n\u0131 ve kod kalitesini \u00f6nemli \u00f6l\u00e7\u00fcde art\u0131r\u0131r. Bu kombinasyon, \u00f6zellikle l\u00fcks bir restoran gibi hata tolerans\u0131n\u0131n d\u00fc\u015f\u00fck oldu\u011fu ortamlarda, sa\u011flam ve g\u00fcvenilir bir altyap\u0131 olu\u015fturman\u0131n anahtar\u0131d\u0131r.<\/p>\n<div class=\"expert-tip\">\n        Uzman \u0130pucu: Next.js API Routes ve Prisma&#8217;y\u0131 birlikte kullan\u0131rken, her API \u00e7a\u011fr\u0131s\u0131 i\u00e7in yeni bir Prisma Client \u00f6rne\u011fi olu\u015fturmaktan ka\u00e7\u0131n\u0131n. Bunun yerine, bir Singleton deseni kullanarak global bir Prisma Client instance&#8217;\u0131 olu\u015fturup bunu yeniden kullanmak, veritaban\u0131 ba\u011flant\u0131 havuzu y\u00f6netimini optimize ederek performans\u0131 %40&#8217;a kadar art\u0131rabilir.\n    <\/div>\n<h2>\u2699\ufe0f Proje Kurulumu ve \u0130lk Ad\u0131mlar: S\u0131f\u0131rdan Ba\u015flang\u0131\u00e7 Nas\u0131l Yap\u0131l\u0131r?<\/h2>\n<p>Art\u0131k Next.js ve Prisma&#8217;n\u0131n neden g\u00fc\u00e7l\u00fc bir ikili oldu\u011funu anlad\u0131\u011f\u0131m\u0131za g\u00f6re, bu teknolojileri kullanarak projemizi nas\u0131l s\u0131f\u0131rdan kuraca\u011f\u0131m\u0131za ge\u00e7ebiliriz. Bu b\u00f6l\u00fcm, temel proje yap\u0131s\u0131n\u0131 olu\u015fturmaktan veritaban\u0131 \u015femam\u0131z\u0131 tan\u0131mlamaya kadar ad\u0131m ad\u0131m bir rehber sunacak.<\/p>\n<h3>Next.js Projesini Ba\u015flatma<\/h3>\n<p>\u0130lk ad\u0131m, Next.js projemizi olu\u015fturmak. Terminalinizi a\u00e7\u0131n ve a\u015fa\u011f\u0131daki komutu \u00e7al\u0131\u015ft\u0131r\u0131n. Bu komut, size TypeScript, ESLint ve Tailwind CSS gibi pop\u00fcler ara\u00e7lar\u0131 projenize dahil etme se\u00e7ene\u011fi sunacakt\u0131r; hepsi i\u00e7in &#8220;Yes&#8221; se\u00e7ene\u011fini tercih etmeniz modern ve sa\u011flam bir geli\u015ftirme deneyimi i\u00e7in \u00f6nerilir.<\/p>\n<pre><code>\nnpx create-next-app@latest rezervasyon-sistemi --typescript --eslint --tailwind\n    <\/pre>\n<p><\/code><\/p>\n<p>Proje olu\u015fturulduktan sonra, dizine girin:<\/p>\n<pre><code>\ncd rezervasyon-sistemi\n    <\/pre>\n<p><\/code><\/p>\n<p>Ve geli\u015ftirme sunucusunu ba\u015flat\u0131n:<\/p>\n<pre><code>\nnpm run dev\n    <\/pre>\n<p><\/code><\/p>\n<p>Art\u0131k taray\u0131c\u0131n\u0131zda <code>http:\/\/localhost:3000<\/code> adresine giderek Next.js ba\u015flang\u0131\u00e7 sayfas\u0131n\u0131 g\u00f6rebilirsiniz. Bu, frontend taraf\u0131n\u0131z\u0131n haz\u0131r oldu\u011fu anlam\u0131na gelir.<\/p>\n<h3>Prisma Kurulumu ve Veritaban\u0131 Ba\u011flant\u0131s\u0131<\/h3>\n<p>\u015eimdi s\u0131ra Prisma'y\u0131 projemize entegre etmeye geldi. Prisma'n\u0131n kurulumu ve veritaban\u0131 ile ba\u011flant\u0131 kurmas\u0131 olduk\u00e7a basittir.<\/p>\n<ol>\n<li><strong>Prisma CLI ve Client K\u00fct\u00fcphanelerini Kurun:<\/strong><\/li>\n<pre><code>\nnpm install prisma @prisma\/client\n        <\/pre>\n<p><\/code><\/p>\n<li><strong>Prisma'y\u0131 Ba\u015flat\u0131n:<\/strong> Bu komut, projenize bir <code>prisma<\/code> dizini ve i\u00e7inde <code>schema.prisma<\/code> dosyas\u0131 olu\u015fturacakt\u0131r. Ayr\u0131ca, veritaban\u0131 ba\u011flant\u0131 dizenizi i\u00e7eren bir <code>.env<\/code> dosyas\u0131 da olu\u015fturulacakt\u0131r.<\/li>\n<pre><code>\nnpx prisma init\n        <\/pre>\n<p><\/code><\/p>\n<li><strong>Veritaban\u0131 Ba\u011flant\u0131s\u0131n\u0131 Yap\u0131land\u0131r\u0131n:<\/strong> <code>.env<\/code> dosyan\u0131z\u0131 a\u00e7\u0131n ve <code>DATABASE_URL<\/code> de\u011fi\u015fkenini kullanaca\u011f\u0131n\u0131z veritaban\u0131n\u0131n ba\u011flant\u0131 dizeniyle g\u00fcncelleyin. L\u00fcks restoran sistemleri i\u00e7in genellikle g\u00fcvenilirli\u011fi ve \u00f6l\u00e7eklenebilirli\u011fi nedeniyle PostgreSQL tercih edilir.<\/li>\n<pre><code>\nDATABASE_URL=\"postgresql:\/\/kullanici:sifre@localhost:5432\/restoran_rezervasyon?schema=public\"\n        <\/pre>\n<p><\/code><\/p>\n<p>Yukar\u0131daki \u00f6rnek bir PostgreSQL ba\u011flant\u0131 dizesidir. Kendi veritaban\u0131 bilgilerinize g\u00f6re (kullan\u0131c\u0131 ad\u0131, \u015fifre, host, port, veritaban\u0131 ad\u0131) g\u00fcncellemeyi unutmay\u0131n. E\u011fer hen\u00fcz bir PostgreSQL veritaban\u0131n\u0131z yoksa, Docker ile h\u0131zl\u0131ca bir tane kurabilirsiniz:<\/p>\n<pre><code>\ndocker run --name some-postgres -e POSTGRES_PASSWORD=mysecretpassword -p 5432:5432 -d postgres\n        <\/pre>\n<p><\/code>\n    <\/ol>\n<h3>Veritaban\u0131 \u015eemas\u0131n\u0131 Tan\u0131mlama (schema.prisma)<\/h3>\n<p>Prisma'n\u0131n kalbi, <code>prisma\/schema.prisma<\/code> dosyas\u0131nda tan\u0131mlanan veri modelleridir. Bu modeller, veritaban\u0131m\u0131zdaki tablolar\u0131 ve aralar\u0131ndaki ili\u015fkileri temsil eder. Rezervasyon sistemimiz i\u00e7in temel modelleri olu\u015ftural\u0131m: <code>User<\/code> (Kullan\u0131c\u0131), <code>Restaurant<\/code> (Restoran) ve <code>Reservation<\/code> (Rezervasyon).<\/p>\n<pre><code>\n\/\/ prisma\/schema.prisma\n\ngenerator client {\n  provider = \"prisma-client-js\"\n}\n\ndatasource db {\n  provider = \"postgresql\"\n  url      = env(\"DATABASE_URL\")\n}\n\nmodel User {\n  id        String      @id @default(uuid())\n  email     String      @unique\n  name      String?\n  password  String \/\/ \u015eifreler hash'lenmelidir!\n  reservations Reservation[]\n  createdAt DateTime    @default(now())\n  updatedAt DateTime    @updatedAt\n}\n\nmodel Restaurant {\n  id        String      @id @default(uuid())\n  name      String\n  address   String\n  phone     String\n  description String?\n  imageUrl  String?\n  openingTime String \/\/ \u00d6rn: \"09:00\"\n  closingTime String \/\/ \u00d6rn: \"23:00\"\n  capacity  Int \/\/ Toplam masa say\u0131s\u0131 veya kapasite\n  tables    Int \/\/ Mevcut masa say\u0131s\u0131\n  reservations Reservation[]\n  createdAt DateTime    @default(now())\n  updatedAt DateTime    @updatedAt\n}\n\nmodel Reservation {\n  id         String      @id @default(uuid())\n  userId     String\n  user       User        @relation(fields: [userId], references: [id])\n  restaurantId String\n  restaurant Restaurant  @relation(fields: [restaurantId], references: [id])\n  date       DateTime\n  time       String \/\/ \u00d6rn: \"19:30\"\n  partySize  Int \/\/ Ki\u015fi say\u0131s\u0131\n  status     String      @default(\"PENDING\") \/\/ PENDING, CONFIRMED, CANCELLED\n  notes      String?\n  createdAt  DateTime    @default(now())\n  updatedAt  DateTime    @updatedAt\n\n  @@unique([restaurantId, date, time]) \/\/ Ayn\u0131 restoranda, ayn\u0131 saatte iki rezervasyon olamaz (basit kontrol)\n}\n    <\/pre>\n<p><\/code><\/p>\n<p>Yukar\u0131daki \u015femada;<\/p>\n<ul>\n<li><code>User<\/code>: Rezervasyon yapan kullan\u0131c\u0131lar\u0131 temsil eder. \u015eifrenin g\u00fcvenli bir \u015fekilde hashlenmesi gerekti\u011fini unutmay\u0131n.<\/li>\n<li><code>Restaurant<\/code>: Rezervasyon yap\u0131labilecek restoranlar\u0131 i\u00e7erir. Kapasite, a\u00e7\u0131l\u0131\u015f\/kapan\u0131\u015f saatleri gibi bilgiler \u00f6nemlidir.<\/li>\n<li><code>Reservation<\/code>: Bir kullan\u0131c\u0131n\u0131n belirli bir restoran i\u00e7in yapt\u0131\u011f\u0131 rezervasyonu tutar. <code>userId<\/code> ve <code>restaurantId<\/code> alanlar\u0131, <code>@relation<\/code> anotasyonlar\u0131 ile di\u011fer modellerle ili\u015fkilendirilir.<\/li>\n<li><code>@@unique([restaurantId, date, time])<\/code> k\u0131s\u0131tlamas\u0131, ayn\u0131 restoranda, ayn\u0131 tarih ve saat i\u00e7in m\u00fckerrer rezervasyonlar\u0131 engellemek i\u00e7in basit bir kontrol sa\u011flar. Ger\u00e7ek d\u00fcnyada bu, masa numaralar\u0131 ve m\u00fcsaitlik durumu gibi daha karma\u015f\u0131k bir mant\u0131kla ele al\u0131nmal\u0131d\u0131r.<\/li>\n<\/ul>\n<h3>Veritaban\u0131 Migration'lar\u0131 ve Prisma Client Olu\u015fturma<\/h3>\n<p>\u015eema dosyam\u0131z\u0131 tan\u0131mlad\u0131ktan sonra, bu \u015femay\u0131 veritaban\u0131m\u0131za uygulamam\u0131z gerekiyor. Prisma'n\u0131n migration sistemi bu konuda bize yard\u0131mc\u0131 olur.<\/p>\n<ol>\n<li><strong>Migration Olu\u015fturma ve Uygulama:<\/strong><\/li>\n<pre><code>\nnpx prisma migrate dev --name init\n        <\/pre>\n<p><\/code><\/p>\n<p>Bu komut, <code>prisma\/migrations<\/code> dizini alt\u0131nda yeni bir migration dosyas\u0131 olu\u015fturacak ve ard\u0131ndan bu migration'\u0131 veritaban\u0131n\u0131za uygulayarak tablolar\u0131 olu\u015fturacakt\u0131r.<\/p>\n<li><strong>Prisma Client'\u0131 Olu\u015fturma:<\/strong> Herhangi bir model de\u011fi\u015fikli\u011fi yapt\u0131\u011f\u0131n\u0131zda, Prisma Client'\u0131 yeniden olu\u015fturman\u0131z gerekir. Bu, TypeScript'in modellerinizi tan\u0131mas\u0131n\u0131 ve do\u011fru tip ipu\u00e7lar\u0131 sa\u011flamas\u0131n\u0131 sa\u011flar.<\/li>\n<pre><code>\nnpx prisma generate\n        <\/pre>\n<p><\/code>\n    <\/ol>\n<p>Art\u0131k projemiz temel Next.js yap\u0131s\u0131yla ve veritaban\u0131 ile ileti\u015fim kurmaya haz\u0131r bir Prisma kurulumuyla donat\u0131lm\u0131\u015f durumda. Sonraki ad\u0131mlarda, bu temeller \u00fczerine API'lerimizi ve kullan\u0131c\u0131 aray\u00fcz\u00fcm\u00fcz\u00fc in\u015fa etmeye ba\u015flayabiliriz.<\/p>\n<h2>\u2699\ufe0f Backend Geli\u015ftirme: Rezervasyon API'lar\u0131 Next.js ile Nas\u0131l Olu\u015fturulur?<\/h2>\n<p>Projemizin temelini att\u0131\u011f\u0131m\u0131za g\u00f6re, \u015fimdi rezervasyon sistemimizin \"beyni\" olan backend k\u0131sm\u0131na odaklanabiliriz. Next.js'in API Routes \u00f6zelli\u011fi sayesinde, RESTful API'lerimizi kolayca olu\u015fturabilir ve veritaban\u0131m\u0131zla etkile\u015fim kurabiliriz. Bu b\u00f6l\u00fcmde, kullan\u0131c\u0131lar\u0131n rezervasyon yapabilece\u011fi, mevcut rezervasyonlar\u0131 listeleyebilece\u011fi ve belki de iptal edebilece\u011fi temel API u\u00e7 noktalar\u0131n\u0131 nas\u0131l olu\u015fturaca\u011f\u0131m\u0131z\u0131 ele alaca\u011f\u0131z.<\/p>\n<h3>Next.js API Routes: Tan\u0131m ve Kullan\u0131m<\/h3>\n<p>Next.js'de API Routes, <code>pages\/api<\/code> dizini alt\u0131nda tan\u0131mlanan dosyalard\u0131r. Bu dosyalar, sunucu taraf\u0131nda \u00e7al\u0131\u015fan ve HTTP isteklerine yan\u0131t veren Node.js i\u015flevleri olarak g\u00f6rev yapar. Bu sayede, ayr\u0131 bir backend framework'\u00fcne ihtiya\u00e7 duymadan, frontend ve backend mant\u0131\u011f\u0131n\u0131 ayn\u0131 projede tutabiliriz. \u00d6rne\u011fin, <code>pages\/api\/reservations.ts<\/code> ad\u0131nda bir dosya olu\u015fturdu\u011fumuzda, bu dosya <code>\/api\/reservations<\/code> adresinden eri\u015filebilen bir API endpoint'i haline gelir.<\/p>\n<h3>Prisma Client'\u0131 Ba\u015flatma ve Kullanma<\/h3>\n<p>API Routes i\u00e7inde veritaban\u0131m\u0131zla ileti\u015fim kurmak i\u00e7in Prisma Client'\u0131 kullanaca\u011f\u0131z. Daha \u00f6nce de bahsetti\u011fimiz gibi, performans optimizasyonu i\u00e7in global bir Prisma Client \u00f6rne\u011fi kullanmak en iyi uygulamad\u0131r.<\/p>\n<pre><code>\n\/\/ lib\/prisma.ts (Yeni bir dosya olu\u015fturun)\nimport { PrismaClient } from '@prisma\/client';\n\nlet prisma: PrismaClient;\n\nif (process.env.NODE_ENV === 'production') {\n  prisma = new PrismaClient();\n} else {\n  if (!(global as any).prisma) {\n    (global as any).prisma = new PrismaClient();\n  }\n  prisma = (global as any).prisma;\n}\n\nexport default prisma;\n    <\/pre>\n<p><\/code><\/p>\n<p>Bu kod par\u00e7as\u0131, geli\u015ftirme ortam\u0131nda s\u0131cak yeniden y\u00fckleme (hot-reloading) s\u0131ras\u0131nda her defas\u0131nda yeni bir Prisma Client \u00f6rne\u011fi olu\u015fturulmas\u0131n\u0131 engellerken, \u00fcretim ortam\u0131nda tek bir \u00f6rnek kullan\u0131r. \u015eimdi bu Prisma Client'\u0131 API rotalar\u0131m\u0131zda kullanabiliriz.<\/p>\n<h3>Rezervasyon Olu\u015fturma (POST \/api\/reservations)<\/h3>\n<p>Yeni bir rezervasyon olu\u015fturmak i\u00e7in bir POST iste\u011fi alacak bir API rotas\u0131 olu\u015ftural\u0131m. Bu rota, kullan\u0131c\u0131n\u0131n g\u00f6nderdi\u011fi verileri do\u011frulayacak ve veritaban\u0131na yeni bir rezervasyon kayd\u0131 ekleyecektir. \u00d6ncelikle, <code>pages\/api\/reservations\/index.ts<\/code> dosyas\u0131n\u0131 olu\u015ftural\u0131m:<\/p>\n<pre><code>\n\/\/ pages\/api\/reservations\/index.ts\nimport type { NextApiRequest, NextApiResponse } from 'next';\nimport prisma from '@\/lib\/prisma'; \/\/ lib\/prisma.ts dosyas\u0131n\u0131 do\u011fru yoldan import edin\n\nexport default async function handler(req: NextApiRequest, res: NextApiResponse) {\n  if (req.method === 'POST') {\n    const { userId, restaurantId, date, time, partySize, notes } = req.body;\n\n    \/\/ 1. Giri\u015f verilerini do\u011frulama\n    if (!userId || !restaurantId || !date || !time || !partySize) {\n      return res.status(400).json({ message: 'Eksik rezervasyon bilgileri.' });\n    }\n\n    \/\/ 2. Tarih format\u0131n\u0131 kontrol etme (\u00f6rne\u011fin ISO string)\n    const reservationDate = new Date(date);\n    if (isNaN(reservationDate.getTime())) {\n      return res.status(400).json({ message: 'Ge\u00e7ersiz tarih format\u0131.' });\n    }\n\n    try {\n      \/\/ 3. Restoran\u0131n m\u00fcsaitli\u011fini kontrol etme (basit bir \u00f6rnek)\n      \/\/ Daha karma\u015f\u0131k bir senaryoda, masa numaralar\u0131, kapasite ve di\u011fer rezervasyonlar dikkate al\u0131nmal\u0131d\u0131r.\n      const restaurant = await prisma.restaurant.findUnique({\n        where: { id: restaurantId },\n      });\n\n      if (!restaurant) {\n        return res.status(404).json({ message: 'Restoran bulunamad\u0131.' });\n      }\n\n      \/\/ Ayn\u0131 tarih ve saat i\u00e7in \u00e7ak\u0131\u015fma kontrol\u00fc (basit bir yakla\u015f\u0131md\u0131r, ger\u00e7ek sistemde masa baz\u0131nda olmal\u0131)\n      const existingReservation = await prisma.reservation.findFirst({\n        where: {\n          restaurantId,\n          date: reservationDate,\n          time,\n        },\n      });\n\n      if (existingReservation) {\n        return res.status(409).json({ message: 'Bu saatte ba\u015fka bir rezervasyon mevcut.' });\n      }\n\n      \/\/ 4. Yeni rezervasyonu olu\u015fturma\n      const newReservation = await prisma.reservation.create({\n        data: {\n          userId,\n          restaurantId,\n          date: reservationDate,\n          time,\n          partySize: parseInt(partySize, 10),\n          notes,\n          status: 'CONFIRMED', \/\/ Ba\u015flang\u0131\u00e7ta CONFIRMED olarak ayarlanabilir veya PENDING\n        },\n      });\n\n      return res.status(201).json(newReservation);\n    } catch (error) {\n      console.error('Rezervasyon olu\u015fturulurken hata:', error);\n      return res.status(500).json({ message: 'Dahili sunucu hatas\u0131.' });\n    }\n  } else {\n    \/\/ Di\u011fer HTTP metodlar\u0131na izin verme\n    res.setHeader('Allow', ['POST']);\n    return res.status(405).end(<code>Metot ${req.method} Desteklenmiyor.<\/code>);\n  }\n}\n    <\/pre>\n<p><\/code><\/p>\n<p>Bu kod;<\/p>\n<ul>\n<li><code>POST<\/code> iste\u011fini i\u015fler.<\/li>\n<li>Gerekli alanlar\u0131n doldurulup doldurulmad\u0131\u011f\u0131n\u0131 kontrol eder.<\/li>\n<li>Restoran\u0131n varl\u0131\u011f\u0131n\u0131 kontrol eder.<\/li>\n<li>Belirli bir tarih ve saat i\u00e7in \u00e7ak\u0131\u015fan rezervasyon olup olmad\u0131\u011f\u0131n\u0131 kontrol eder (bu, l\u00fcks bir sistem i\u00e7in ba\u015flang\u0131\u00e7 seviyesi bir kontrold\u00fcr; daha geli\u015fmi\u015f sistemler masa numaras\u0131, alan vb. detaylar\u0131 hesaba katmal\u0131d\u0131r).<\/li>\n<li>Herhangi bir hata durumunda uygun HTTP durum kodlar\u0131 ve mesajlar\u0131 ile yan\u0131t verir.<\/li>\n<\/ul>\n<h3>T\u00fcm Rezervasyonlar\u0131 Listeleme (GET \/api\/reservations)<\/h3>\n<p>Mevcut rezervasyonlar\u0131 listelemek i\u00e7in ayn\u0131 <code>pages\/api\/reservations\/index.ts<\/code> dosyas\u0131nda bir GET iste\u011fi i\u015fleyici ekleyebiliriz.<\/p>\n<pre><code>\n\/\/ pages\/api\/reservations\/index.ts (devam)\nimport type { NextApiRequest, NextApiResponse } from 'next';\nimport prisma from '@\/lib\/prisma';\n\nexport default async function handler(req: NextApiRequest, res: NextApiResponse) {\n  if (req.method === 'POST') {\n    \/\/ ... (yukar\u0131daki POST kodu)\n  } else if (req.method === 'GET') {\n    try {\n      \/\/ Query parametreleri ile filtreleme yap\u0131labilir (\u00f6rne\u011fin userId, restaurantId, status)\n      const { userId, restaurantId, status } = req.query;\n\n      const reservations = await prisma.reservation.findMany({\n        where: {\n          ...(userId && { userId: String(userId) }),\n          ...(restaurantId && { restaurantId: String(restaurantId) }),\n          ...(status && { status: String(status) }),\n        },\n        include: {\n          user: {\n            select: { id: true, name: true, email: true }, \/\/ G\u00fcvenlik i\u00e7in \u015fifre veya hassas bilgi g\u00f6ndermeyin\n          },\n          restaurant: {\n            select: { id: true, name: true, address: true, phone: true },\n          },\n        },\n        orderBy: {\n          date: 'asc',\n        },\n      });\n\n      return res.status(200).json(reservations);\n    } catch (error) {\n      console.error('Rezervasyonlar getirilirken hata:', error);\n      return res.status(500).json({ message: 'Dahili sunucu hatas\u0131.' });\n    }\n  } else {\n    res.setHeader('Allow', ['POST', 'GET']);\n    return res.status(405).end(<code>Metot ${req.method} Desteklenmiyor.<\/code>);\n  }\n}\n    <\/pre>\n<p><\/code><\/p>\n<p>Bu GET iste\u011fi i\u015fleyici;<\/p>\n<ul>\n<li>Gelen <code>userId<\/code>, <code>restaurantId<\/code> veya <code>status<\/code> query parametrelerine g\u00f6re rezervasyonlar\u0131 filtreler.<\/li>\n<li><code>include<\/code> \u00f6zelli\u011fi ile ilgili kullan\u0131c\u0131 ve restoran bilgilerini de rezervasyon objesine dahil eder (g\u00fcvenlik nedeniyle hassas bilgileri hari\u00e7 tutarak).<\/li>\n<li>Rezervasyonlar\u0131 tarihe g\u00f6re s\u0131ralar.<\/li>\n<\/ul>\n<h3>Hata Y\u00f6netimi ve G\u00fcvenlik \u0130pu\u00e7lar\u0131<\/h3>\n<ul>\n<li><strong>Giri\u015f Do\u011frulama:<\/strong> Her zaman istemciden gelen verileri sunucu taraf\u0131nda do\u011frulay\u0131n. Sadece bo\u015f olup olmad\u0131\u011f\u0131n\u0131 kontrol etmekle kalmay\u0131p, veri t\u00fcrlerini, uzunluklar\u0131n\u0131 ve formatlar\u0131n\u0131 da kontrol edin (\u00f6rne\u011fin, e-posta format\u0131, tarih ge\u00e7erlili\u011fi). Zod veya Yup gibi \u015fema do\u011frulama k\u00fct\u00fcphanelerini kullanmak bu s\u00fcreci \u00e7ok daha kolay ve g\u00fcvenli hale getirebilir.<\/li>\n<li><strong>Hata Mesajlar\u0131:<\/strong> Kullan\u0131c\u0131lara anla\u015f\u0131l\u0131r ama genel hata mesajlar\u0131 sunun. Detayl\u0131 hata mesajlar\u0131 (\u00f6rne\u011fin, veritaban\u0131 hata mesajlar\u0131) hassas bilgiler i\u00e7erebilece\u011fi i\u00e7in \u00fcretim ortam\u0131nda kesinlikle ka\u00e7\u0131n\u0131lmal\u0131d\u0131r.<\/li>\n<li><strong>Kimlik Do\u011frulama ve Yetkilendirme:<\/strong> API rotalar\u0131n\u0131za eri\u015fimi k\u0131s\u0131tlamak i\u00e7in kimlik do\u011frulama (authentication) ve yetkilendirme (authorization) mekanizmalar\u0131 uygulay\u0131n. Kullan\u0131c\u0131n\u0131n ger\u00e7ekten bir rezervasyon yapmaya veya kendi rezervasyonlar\u0131n\u0131 g\u00f6r\u00fcnt\u00fclemeye yetkili olup olmad\u0131\u011f\u0131n\u0131 kontrol edin. NextAuth.js, bu konuda g\u00fc\u00e7l\u00fc bir \u00e7\u00f6z\u00fcm sunar.<\/li>\n<li><strong>Veri G\u00fcvenli\u011fi:<\/strong> Asla \u015fifreleri d\u00fcz metin olarak saklamay\u0131n. bcrypt gibi k\u00fct\u00fcphaneler kullanarak \u015fifreleri hashleyin. Veritaban\u0131ndan hassas verileri (\u015fifreler, API anahtarlar\u0131) do\u011frudan istemciye g\u00f6ndermekten ka\u00e7\u0131n\u0131n.<\/li>\n<\/ul>\n<p>Bu temel API rotalar\u0131yla, rezervasyon sistemimizin backend omurgas\u0131n\u0131 olu\u015fturmu\u015f oluyoruz. \u0130leri d\u00fczey senaryolarda, masa m\u00fcsaitli\u011fi, iptal i\u015flemleri, \u00f6deme entegrasyonlar\u0131 gibi daha karma\u015f\u0131k mant\u0131klar\u0131 da bu API'lere ekleyebilirsiniz.<\/p>\n<h2>\ud83c\udfa8 Frontend Mimarisi: Kullan\u0131c\u0131 Deneyimi Odakl\u0131 Aray\u00fcz Nas\u0131l Tasarlan\u0131r?<\/h2>\n<p>G\u00fc\u00e7l\u00fc bir backend'e sahip olmak harika, ancak l\u00fcks bir rezervasyon sisteminin ba\u015far\u0131s\u0131 b\u00fcy\u00fck \u00f6l\u00e7\u00fcde kullan\u0131c\u0131 aray\u00fcz\u00fcn\u00fcn (UI) ve kullan\u0131c\u0131 deneyiminin (UX) kalitesine ba\u011fl\u0131d\u0131r. Bu b\u00f6l\u00fcmde, Next.js ve React'\u0131n bile\u015fen tabanl\u0131 yap\u0131s\u0131n\u0131 kullanarak, sezgisel, estetik ve i\u015flevsel bir rezervasyon aray\u00fcz\u00fcn\u00fc nas\u0131l geli\u015ftirece\u011fimizi inceleyece\u011fiz.<\/p>\n<h3>Kullan\u0131c\u0131 Aray\u00fcz\u00fc \u0130\u00e7in Bile\u015fen Tabanl\u0131 Yakla\u015f\u0131m<\/h3>\n<p>React'\u0131n en b\u00fcy\u00fck avantajlar\u0131ndan biri, aray\u00fcz\u00fc y\u00f6netilebilir ve yeniden kullan\u0131labilir bile\u015fenlere ay\u0131rma yetene\u011fidir. Rezervasyon sistemi i\u00e7in \u015fu temel bile\u015fenleri d\u00fc\u015f\u00fcnebiliriz:<\/p>\n<ul>\n<li><code><ReservationForm \/><\/code>: Tarih, saat, ki\u015fi say\u0131s\u0131 gibi bilgileri alan ana form.<\/li>\n<li><code><RestaurantCard \/><\/code>: Restoranlar\u0131 listeleyen ve her bir restoran\u0131n detaylar\u0131n\u0131 g\u00f6steren kart.<\/li>\n<li><code><DatePicker \/><\/code>: Kullan\u0131c\u0131n\u0131n rezervasyon tarihini se\u00e7mesini sa\u011flayan bir tarih se\u00e7ici.<\/li>\n<li><code><TimeSlotPicker \/><\/code>: M\u00fcsait saat dilimlerini g\u00f6steren ve se\u00e7meyi sa\u011flayan bile\u015fen.<\/li>\n<li><code><ConfirmationModal \/><\/code>: Rezervasyon onay\u0131 veya hata mesajlar\u0131n\u0131 g\u00f6steren modal pencere.<\/li>\n<\/ul>\n<p>Bu bile\u015fenleri bir araya getirerek, karma\u015f\u0131k bir aray\u00fcz\u00fc daha basit ve y\u00f6netilebilir par\u00e7alara ay\u0131rabiliriz.<\/p>\n<h3>Rezervasyon Formu Olu\u015fturma<\/h3>\n<p>Ana rezervasyon formumuz, kullan\u0131c\u0131n\u0131n rezervasyon bilgilerini girmesi i\u00e7in merkezi bir nokta olacakt\u0131r. <code>pages\/book\/[restaurantId].tsx<\/code> veya <code>components\/ReservationForm.tsx<\/code> gibi bir yap\u0131 d\u00fc\u015f\u00fcnebiliriz.<\/p>\n<pre><code>\n\/\/ components\/ReservationForm.tsx\n\"use client\"; \/\/ Next.js 13+ App Router i\u00e7in, e\u011fer App Router kullan\u0131l\u0131yorsa\n\nimport React, { useState } from 'react';\nimport DatePicker from 'react-datepicker';\nimport 'react-datepicker\/dist\/react-datepicker.css';\nimport { useRouter } from 'next\/router'; \/\/ Pages Router i\u00e7in\n\ninterface ReservationFormProps {\n  restaurantId: string;\n}\n\nconst ReservationForm: React.FC<ReservationFormProps> = ({ restaurantId }) => {\n  const [selectedDate, setSelectedDate] = useState<Date | null>(null);\n  const [selectedTime, setSelectedTime] = useState<string>('');\n  const [partySize, setPartySize] = useState<number>(1);\n  const [notes, setNotes] = useState<string>('');\n  const [error, setError] = useState<string | null>(null);\n  const [loading, setLoading] = useState<boolean>(false);\n  \n  \/\/ \u00d6rnek m\u00fcsait saatler (ger\u00e7ekte API'den \u00e7ekilmeli)\n  const availableTimes = ['18:00', '19:00', '20:00', '21:00']; \n  const router = useRouter();\n\n  const handleSubmit = async (e: React.FormEvent) => {\n    e.preventDefault();\n    setLoading(true);\n    setError(null);\n\n    if (!selectedDate || !selectedTime || partySize < 1) {\n      setError('L\u00fctfen t\u00fcm alanlar\u0131 doldurun.');\n      setLoading(false);\n      return;\n    }\n\n    try {\n      const response = await fetch('\/api\/reservations', {\n        method: 'POST',\n        headers: {\n          'Content-Type': 'application\/json',\n        },\n        body: JSON.stringify({\n          userId: 'some-user-id', \/\/ Kimlik do\u011frulama sonras\u0131 dinamik olacak\n          restaurantId,\n          date: selectedDate.toISOString(),\n          time: selectedTime,\n          partySize,\n          notes,\n        }),\n      });\n\n      if (!response.ok) {\n        const errorData = await response.json();\n        throw new Error(errorData.message || 'Rezervasyon ba\u015far\u0131s\u0131z.');\n      }\n\n      const data = await response.json();\n      alert('Rezervasyon ba\u015far\u0131yla olu\u015fturuldu!');\n      router.push(<code>\/reservations\/${data.id}<\/code>); \/\/ Rezervasyon detay sayfas\u0131na y\u00f6nlendir\n    } catch (err: any) {\n      setError(err.message || 'Bir hata olu\u015ftu.');\n    } finally {\n      setLoading(false);\n    }\n  };\n\n  return (\n    <form onSubmit={handleSubmit} className=\"p-6 bg-white rounded-lg shadow-md max-w-lg mx-auto\">\n      <h3 className=\"text-2xl font-semibold mb-4 text-center\">Rezervasyon Yap<\/h3>\n      {error && <div className=\"bg-red-100 text-red-700 p-3 rounded mb-4\">{error}<\/div>}\n      \n      <div className=\"mb-4\">\n        <label htmlFor=\"date\" className=\"block text-gray-700 text-sm font-bold mb-2\">Tarih:<\/label>\n        <DatePicker\n          selected={selectedDate}\n          onChange={(date: Date | null) => setSelectedDate(date)}\n          minDate={new Date()}\n          dateFormat=\"dd\/MM\/yyyy\"\n          className=\"shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline\"\n        \/>\n      <\/div>\n\n      <div className=\"mb-4\">\n        <label htmlFor=\"time\" className=\"block text-gray-700 text-sm font-bold mb-2\">Saat:<\/label>\n        <select\n          id=\"time\"\n          value={selectedTime}\n          onChange={(e) => setSelectedTime(e.target.value)}\n          className=\"shadow border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline\"\n        >\n          <option value=\"\" disabled>Saat Se\u00e7iniz<\/option>\n          {availableTimes.map(time => (\n            <option key={time} value={time}>{time}<\/option>\n          ))}\n        <\/select>\n      <\/div>\n\n      <div className=\"mb-4\">\n        <label htmlFor=\"partySize\" className=\"block text-gray-700 text-sm font-bold mb-2\">Ki\u015fi Say\u0131s\u0131:<\/label>\n        <input\n          type=\"number\"\n          id=\"partySize\"\n          value={partySize}\n          onChange={(e) => setPartySize(parseInt(e.target.value) || 1)}\n          min=\"1\"\n          className=\"shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline\"\n        \/>\n      <\/div>\n\n      <div className=\"mb-6\">\n        <label htmlFor=\"notes\" className=\"block text-gray-700 text-sm font-bold mb-2\">Notlar (iste\u011fe ba\u011fl\u0131):<\/label>\n        <textarea\n          id=\"notes\"\n          value={notes}\n          onChange={(e) => setNotes(e.target.value)}\n          rows={3}\n          className=\"shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline\"\n        ><\/textarea>\n      <\/div>\n\n      <div className=\"flex items-center justify-between\">\n        <button\n          type=\"submit\"\n          disabled={loading}\n          className=\"bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded focus:outline-none focus:shadow-outline disabled:opacity-50\"\n        >\n          {loading ? 'Rezervasyon Yap\u0131l\u0131yor...' : 'Rezervasyon Yap'}\n        <\/button>\n      <\/div>\n    <\/form>\n  );\n};\n\nexport default ReservationForm;\n    <\/pre>\n<p><\/code><\/p>\n<p>Bu form bile\u015feni;<\/p>\n<ul>\n<li><code>useState<\/code> hook'lar\u0131n\u0131 kullanarak form alanlar\u0131n\u0131n durumunu y\u00f6netir.<\/li>\n<li><code>react-datepicker<\/code> k\u00fct\u00fcphanesi ile kullan\u0131c\u0131 dostu bir tarih se\u00e7ici sunar.<\/li>\n<li>Form g\u00f6nderildi\u011finde, <code>\/api\/reservations<\/code> endpoint'ine bir POST iste\u011fi g\u00f6nderir.<\/li>\n<li>Y\u00fckleme (loading) durumunu ve hata mesajlar\u0131n\u0131 kullan\u0131c\u0131ya g\u00f6sterir.<\/li>\n<li>Rezervasyon ba\u015far\u0131l\u0131 oldu\u011funda kullan\u0131c\u0131y\u0131 rezervasyon detay sayfas\u0131na y\u00f6nlendirir.<\/li>\n<\/ul>\n<h3>State Y\u00f6netimi ve Veri \u00c7ekme<\/h3>\n<p>Frontend taraf\u0131nda veri \u00e7ekme ve state y\u00f6netimi i\u00e7in React Query (veya SWR) gibi k\u00fct\u00fcphaneler kullanmak, \u00f6nbellekleme, arka plan yenileme, hata tekrar deneme gibi bir\u00e7ok \u00f6zelli\u011fi otomatik olarak y\u00f6neterek geli\u015ftirme deneyimini b\u00fcy\u00fck \u00f6l\u00e7\u00fcde iyile\u015ftirir. \u00d6rne\u011fin, bir restoran\u0131n m\u00fcsait saatlerini \u00e7ekmek i\u00e7in:<\/p>\n<pre><code>\n\/\/ pages\/book\/[restaurantId].tsx (sayfa i\u00e7inde veya RestaurantDetails bile\u015feninde)\nimport { useQuery } from '@tanstack\/react-query'; \/\/ React Query kullan\u0131l\u0131yorsa\n\nconst fetchAvailableTimes = async (restaurantId: string, date: string) => {\n  const res = await fetch(<code>\/api\/restaurants\/${restaurantId}\/available-times?date=${date}<\/code>);\n  if (!res.ok) {\n    throw new Error('M\u00fcsait saatler \u00e7ekilemedi.');\n  }\n  return res.json();\n};\n\nfunction RestaurantBookingPage({ restaurantId }: { restaurantId: string }) {\n  const [selectedDate, setSelectedDate] = useState<Date | null>(new Date());\n\n  const { data: availableTimes, isLoading, error } = useQuery({\n    queryKey: ['availableTimes', restaurantId, selectedDate?.toISOString()],\n    queryFn: () => fetchAvailableTimes(restaurantId, selectedDate?.toISOString() || ''),\n    enabled: !!selectedDate, \/\/ Yaln\u0131zca tarih se\u00e7iliyse sorguyu \u00e7al\u0131\u015ft\u0131r\n  });\n\n  if (isLoading) return <div>M\u00fcsait saatler y\u00fckleniyor...<\/div>;\n  if (error) return <div>Hata: {error.message}<\/div>;\n\n  return (\n    <div>\n      <h1>{restaurantId} i\u00e7in Rezervasyon Yap<\/h1>\n      <DatePicker selected={selectedDate} onChange={setSelectedDate} \/>\n      <ReservationForm \n        restaurantId={restaurantId} \n        availableTimes={availableTimes} \/\/ API'den gelen m\u00fcsait saatleri prop olarak ge\u00e7\n      \/>\n    <\/div>\n  );\n}\n    <\/pre>\n<p><\/code><\/p>\n<p>Bu yakla\u015f\u0131m, UI'\u0131n veritaban\u0131 ile senkronize kalmas\u0131n\u0131 ve kullan\u0131c\u0131ya her zaman g\u00fcncel bilgileri sunmas\u0131n\u0131 sa\u011flar.<\/p>\n<h3>Mobil Uyumluluk ve Duyarl\u0131 Tasar\u0131m<\/h3>\n<p>L\u00fcks restoran m\u00fc\u015fterileri, rezervasyonlar\u0131n\u0131 mobil cihazlar\u0131ndan yapmay\u0131 tercih edebilirler. Bu nedenle, duyarl\u0131 tasar\u0131m (responsive design) olmazsa olmazd\u0131r. Tailwind CSS gibi bir CSS framework'\u00fc kullanarak veya elle media query'ler yazarak mobil uyumluluk sa\u011flayabiliriz.<\/p>\n<pre><code>\n\/* styles\/globals.css veya bir CSS mod\u00fcl\u00fcnde *\/\n\/* K\u00fc\u00e7\u00fck ekranlar i\u00e7in varsay\u0131lan stiller *\/\n.reservation-container {\n  padding: 1rem;\n  max-width: 100%;\n}\n\n.reservation-form-group {\n  margin-bottom: 1rem;\n}\n\n\/* Orta ve b\u00fcy\u00fck ekranlar i\u00e7in media query *\/\n@media (min-width: 768px) {\n  .reservation-container {\n    padding: 2rem;\n    max-width: 600px; \/* Belirli bir geni\u015flikten sonra formu merkeze al *\/\n  }\n\n  .reservation-form-group {\n    display: flex;\n    align-items: center;\n    gap: 1rem;\n  }\n\n  .reservation-form-group label {\n    flex: 1;\n    text-align: right;\n  }\n\n  .reservation-form-group input,\n  .reservation-form-group select,\n  .reservation-form-group textarea {\n    flex: 2;\n  }\n}\n    <\/pre>\n<p><\/code><\/p>\n<p>Yukar\u0131daki CSS \u00f6rne\u011fi, k\u00fc\u00e7\u00fck ekranlarda form elemanlar\u0131n\u0131n dikey olarak y\u0131\u011f\u0131lmas\u0131n\u0131, daha b\u00fcy\u00fck ekranlarda ise yatay olarak hizalanmas\u0131n\u0131 sa\u011flar. Bu sayede, farkl\u0131 cihazlarda optimize edilmi\u015f bir g\u00f6r\u00fcnt\u00fc elde ederiz. Tailwind CSS kullan\u0131rken, bu t\u00fcr duyarl\u0131 tasar\u0131mlar\u0131 do\u011frudan HTML s\u0131n\u0131flar\u0131 arac\u0131l\u0131\u011f\u0131yla \u00e7ok daha h\u0131zl\u0131 bir \u015fekilde yapabiliriz (\u00f6rne\u011fin, <code>md:flex md:gap-4<\/code>).<\/p>\n<p>Kullan\u0131c\u0131 deneyimi, sadece g\u00f6rsel estetikle s\u0131n\u0131rl\u0131 de\u011fildir. H\u0131zl\u0131 y\u00fckleme s\u00fcreleri, net geri bildirimler (ba\u015far\u0131\/hata mesajlar\u0131), kolay navigasyon ve eri\u015filebilirlik gibi fakt\u00f6rler, l\u00fcks bir rezervasyon sisteminin kalitesini belirler. Next.js'in performans optimizasyonlar\u0131 ve React'\u0131n esnekli\u011fi sayesinde, bu hedeflere ula\u015fmak olduk\u00e7a kolayd\u0131r.<\/p>\n<h2>\ud83d\udd12 G\u00fcvenlik ve \u00d6l\u00e7eklenebilirlik: L\u00fcks Sistemlerde Kritik Fakt\u00f6rler Nelerdir?<\/h2>\n<p>Bir l\u00fcks restoran rezervasyon sistemi, sadece i\u015flevsel olmakla kalmay\u0131p, ayn\u0131 zamanda son derece g\u00fcvenli ve \u00f6l\u00e7eklenebilir olmal\u0131d\u0131r. M\u00fc\u015fteri verilerinin gizlili\u011fi, rezervasyon bilgilerinin b\u00fct\u00fcnl\u00fc\u011f\u00fc ve yo\u011fun talep anlar\u0131nda sistemin sorunsuz \u00e7al\u0131\u015fmas\u0131, bu t\u00fcr bir platform i\u00e7in hayati \u00f6neme sahiptir. Bu b\u00f6l\u00fcmde, projemizin g\u00fcvenli\u011fini ve gelecekteki b\u00fcy\u00fcmesini destekleyecek \u00f6l\u00e7eklenebilirlik stratejilerini ele alaca\u011f\u0131z.<\/p>\n<h3>Kimlik Do\u011frulama (Authentication) ve Yetkilendirme (Authorization)<\/h3>\n<p>Kullan\u0131c\u0131lar\u0131n sisteme g\u00fcvenli bir \u015fekilde giri\u015f yapmas\u0131n\u0131 ve yaln\u0131zca yetkili olduklar\u0131 i\u015flemleri ger\u00e7ekle\u015ftirmesini sa\u011flamak, g\u00fcvenlik katman\u0131n\u0131n temelidir.<\/p>\n<ul>\n<li><strong>Kimlik Do\u011frulama:<\/strong>\n<ul>\n<li><strong>NextAuth.js:<\/strong> Next.js uygulamalar\u0131 i\u00e7in en pop\u00fcler ve kapsaml\u0131 kimlik do\u011frulama k\u00fct\u00fcphanesidir. OAuth sa\u011flay\u0131c\u0131lar\u0131 (Google, Facebook vb.), e-posta\/\u015fifre tabanl\u0131 giri\u015f veya sihirli ba\u011flant\u0131lar (magic links) gibi \u00e7e\u015fitli y\u00f6ntemleri destekler. \u00c7erez tabanl\u0131 oturum y\u00f6netimi (session management) sunarak sunucu taraf\u0131nda g\u00fcvenli\u011fi sa\u011flar.<\/li>\n<li><strong>JWT (JSON Web Tokens):<\/strong> E\u011fer daha esnek veya mikroservis tabanl\u0131 bir mimari tercih ediliyorsa, JWT'ler kullan\u0131labilir. Kullan\u0131c\u0131 giri\u015fi sonras\u0131 verilen bir token, sonraki isteklerde kimlik do\u011frulamas\u0131 i\u00e7in kullan\u0131l\u0131r. Ancak, JWT'lerin istemci taraf\u0131nda g\u00fcvenli bir \u015fekilde saklanmas\u0131 (HTTP-only \u00e7erezlerde) ve yenilenme (refresh token) mekanizmalar\u0131n\u0131n do\u011fru kurulmas\u0131 \u00f6nemlidir.<\/li>\n<\/ul>\n<\/li>\n<li><strong>Yetkilendirme:<\/strong>\n<ul>\n<li><strong>Rol Tabanl\u0131 Eri\u015fim Kontrol\u00fc (RBAC):<\/strong> Sistemde farkl\u0131 kullan\u0131c\u0131 rolleri tan\u0131mlay\u0131n (\u00f6rne\u011fin, M\u00fc\u015fteri, Restoran Y\u00f6neticisi, S\u00fcper Y\u00f6netici). Her rol\u00fcn belirli eylemleri ger\u00e7ekle\u015ftirme veya belirli verilere eri\u015fim yetkisi olsun. \u00d6rne\u011fin, bir m\u00fc\u015fteri sadece kendi rezervasyonlar\u0131n\u0131 g\u00f6r\u00fcnt\u00fcleyebilir ve de\u011fi\u015ftirebilirken, bir restoran y\u00f6neticisi kendi restoran\u0131n\u0131n t\u00fcm rezervasyonlar\u0131n\u0131 y\u00f6netebilir. Bu mant\u0131k, API rotalar\u0131n\u0131zda ve frontend'de uygulanmal\u0131d\u0131r.<\/li>\n<li><strong>Sunucu Taraf\u0131 Kontrol\u00fc:<\/strong> Asla yetkilendirme kararlar\u0131n\u0131 yaln\u0131zca frontend \u00fczerinde almay\u0131n. Kullan\u0131c\u0131n\u0131n bir eylemi ger\u00e7ekle\u015ftirmeye yetkili olup olmad\u0131\u011f\u0131n\u0131 her zaman sunucu taraf\u0131nda do\u011frulay\u0131n. \u00d6rne\u011fin, bir rezervasyon iptal iste\u011fi geldi\u011finde, iste\u011fi yapan kullan\u0131c\u0131n\u0131n bu rezervasyonun sahibi olup olmad\u0131\u011f\u0131n\u0131 veya y\u00f6netici yetkisine sahip olup olmad\u0131\u011f\u0131n\u0131 kontrol edin.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<pre><code>\n\/\/ pages\/api\/reservations\/[id].ts (\u00d6rnek: Rezervasyon g\u00fcncelleme\/iptal)\nimport type { NextApiRequest, NextApiResponse } from 'next';\nimport prisma from '@\/lib\/prisma';\n\/\/ import { getSession } from 'next-auth\/react'; \/\/ NextAuth.js ile oturum bilgisi almak i\u00e7in\n\nexport default async function handler(req: NextApiRequest, res: NextApiResponse) {\n  const { id } = req.query; \/\/ rezervasyon ID\n  \/\/ const session = await getSession({ req }); \/\/ NextAuth.js kullan\u0131l\u0131yorsa\n\n  \/\/ if (!session) {\n  \/\/   return res.status(401).json({ message: 'Giri\u015f yapmal\u0131s\u0131n\u0131z.' });\n  \/\/ }\n\n  if (req.method === 'PUT') {\n    const { status, notes } = req.body;\n\n    try {\n      const reservation = await prisma.reservation.findUnique({\n        where: { id: String(id) },\n      });\n\n      if (!reservation) {\n        return res.status(404).json({ message: 'Rezervasyon bulunamad\u0131.' });\n      }\n\n      \/\/ Yetkilendirme kontrol\u00fc: Sadece rezervasyon sahibi veya admin g\u00fcncelleyebilir\n      \/\/ if (reservation.userId !== session.user.id && session.user.role !== 'ADMIN') {\n      \/\/   return res.status(403).json({ message: 'Bu rezervasyonu g\u00fcncelleme yetkiniz yok.' });\n      \/\/ }\n\n      const updatedReservation = await prisma.reservation.update({\n        where: { id: String(id) },\n        data: { status, notes },\n      });\n\n      return res.status(200).json(updatedReservation);\n    } catch (error) {\n      console.error('Rezervasyon g\u00fcncellenirken hata:', error);\n      return res.status(500).json({ message: 'Dahili sunucu hatas\u0131.' });\n    }\n  } else {\n    res.setHeader('Allow', ['PUT']);\n    return res.status(405).end(<code>Metot ${req.method} Desteklenmiyor.<\/code>);\n  }\n}\n    <\/pre>\n<p><\/code><\/p>\n<h3>Veritaban\u0131 Optimizasyonlar\u0131<\/h3>\n<p>Yo\u011fun kullan\u0131ml\u0131 sistemlerde veritaban\u0131 performans\u0131 kritik \u00f6neme sahiptir. Prisma ile bile, veritaban\u0131 seviyesinde optimizasyonlara dikkat etmek gerekir.<\/p>\n<ul>\n<li><strong>\u0130ndeksler (Indexes):<\/strong> S\u0131k\u00e7a sorgulanan alanlara (\u00f6rne\u011fin <code>userId<\/code>, <code>restaurantId<\/code>, <code>date<\/code>, <code>time<\/code>) indeks ekleyin. Prisma \u015femas\u0131nda <code>@@index([alanAdi])<\/code> veya <code>@@unique([alanAdi])<\/code> kullanarak bunu yapabilirsiniz. Bu, sorgu s\u00fcrelerini \u00f6nemli \u00f6l\u00e7\u00fcde h\u0131zland\u0131r\u0131r.<\/li>\n<li><strong>Sorgu Optimizasyonu:<\/strong> N+1 sorgu problemlerinden ka\u00e7\u0131n\u0131n. Prisma'n\u0131n <code>include<\/code> ve <code>select<\/code> \u00f6zelliklerini ak\u0131ll\u0131ca kullanarak sadece ihtiyac\u0131n\u0131z olan veriyi \u00e7ekin ve ili\u015fkili verileri tek sorguda getirin.<\/li>\n<li><strong>Ba\u011flant\u0131 Havuzlama (Connection Pooling):<\/strong> \u00d6zellikle sunucusuz (serverless) ortamlarda, her istek i\u00e7in yeni bir veritaban\u0131 ba\u011flant\u0131s\u0131 a\u00e7mak performans\u0131 d\u00fc\u015f\u00fcrebilir. Prisma, ba\u011flant\u0131 havuzlamay\u0131 y\u00f6netir, ancak sunucusuz fonksiyonlar i\u00e7in veritaban\u0131 sa\u011flay\u0131c\u0131n\u0131z\u0131n (\u00f6rne\u011fin Vercel Postgres, Supabase) sundu\u011fu ba\u011flant\u0131 havuzu \u00e7\u00f6z\u00fcmlerini (PgBouncer gibi) kullanmak \u00f6nemlidir.<\/li>\n<\/ul>\n<h3>\u00d6l\u00e7eklenebilirlik Stratejileri<\/h3>\n<p>L\u00fcks bir restoran zinciri b\u00fcy\u00fcd\u00fck\u00e7e veya pop\u00fclaritesi artt\u0131k\u00e7a, rezervasyon sistemi de bu y\u00fck\u00fc kald\u0131rabilmelidir.<\/p>\n<ul>\n<li><strong>Sunucusuz (Serverless) Fonksiyonlar:<\/strong> Next.js API Routes, Vercel gibi platformlarda sunucusuz fonksiyonlar olarak da\u011f\u0131t\u0131l\u0131r. Bu, talep artt\u0131k\u00e7a otomatik olarak \u00f6l\u00e7eklenebilecekleri anlam\u0131na gelir. Kullan\u0131m ba\u015f\u0131na \u00f6deme modeli sayesinde maliyet avantaj\u0131 da sa\u011flayabilirler.<\/li>\n<li><strong>Veri \u00d6nbellekleme (Caching):<\/strong> S\u0131k\u00e7a eri\u015filen ve nadiren de\u011fi\u015fen veriler i\u00e7in \u00f6nbellekleme kullan\u0131n. \u00d6rne\u011fin, restoran bilgileri gibi statik verileri CDN (Content Delivery Network) veya in-memory cache (Redis gibi) \u00fczerinde \u00f6nbellekleyebilirsiniz. Next.js'in veri \u00f6nbellekleme mekanizmalar\u0131 (\u00f6rn. <code>revalidate<\/code> option ile ISR) veya React Query\/SWR gibi k\u00fct\u00fcphanelerin istemci taraf\u0131 \u00f6nbelleklemesi bu konuda yard\u0131mc\u0131 olur.<\/li>\n<li><strong>Veritaban\u0131 \u00d6l\u00e7eklendirme:<\/strong> Dikey (daha g\u00fc\u00e7l\u00fc sunucu) veya yatay (daha fazla sunucu, sharding) olarak veritaban\u0131n\u0131z\u0131 \u00f6l\u00e7eklendirmeye haz\u0131r olun. PostgreSQL gibi veritabanlar\u0131, replikasyon ve okuma replikalar\u0131 ile \u00f6l\u00e7eklenebilirlik sunar.<\/li>\n<li><strong>Y\u00fck Dengeleme (Load Balancing):<\/strong> \u00c7ok say\u0131da istek geldi\u011finde, gelen trafi\u011fi birden fazla sunucuya da\u011f\u0131tmak i\u00e7in bir y\u00fck dengeleyici kullan\u0131n. Vercel gibi platformlar bu altyap\u0131y\u0131 sizin i\u00e7in y\u00f6netir.<\/li>\n<\/ul>\n<div class=\"expert-tip\">\n        Uzman \u0130pucu: G\u00fcvenlik ba\u015fl\u0131\u011f\u0131 alt\u0131nda, kullan\u0131c\u0131 \u015fifrelerini asla do\u011frudan veritaban\u0131na kaydetmeyin. Bunun yerine, <code>bcryptjs<\/code> gibi bir k\u00fct\u00fcphane kullanarak \u015fifreleri hash'leyin. Kullan\u0131c\u0131 giri\u015fi s\u0131ras\u0131nda da girilen \u015fifreyi hashleyip veritaban\u0131ndaki hash ile kar\u015f\u0131la\u015ft\u0131r\u0131n. \u00d6rne\u011fin:<\/p>\n<pre><code>\n\/\/ \u015eifre hashleme\nimport bcrypt from 'bcryptjs';\nconst hashedPassword = await bcrypt.hash(password, 10);\n\n\/\/ \u015eifre kar\u015f\u0131la\u015ft\u0131rma\nconst passwordMatch = await bcrypt.compare(plainPassword, hashedPassword);\n        <\/pre>\n<p><\/code>\n    <\/div>\n<p>Bu g\u00fcvenlik ve \u00f6l\u00e7eklenebilirlik yakla\u015f\u0131mlar\u0131n\u0131 projenin ba\u015f\u0131ndan itibaren d\u00fc\u015f\u00fcnmek, uzun vadede daha sa\u011flam, g\u00fcvenilir ve ba\u015far\u0131l\u0131 bir rezervasyon sistemi in\u015fa etmenin anahtar\u0131d\u0131r. L\u00fcks bir sistemde, bu fakt\u00f6rlerin g\u00f6z ard\u0131 edilmesi, hem m\u00fc\u015fteri kayb\u0131na hem de operasyonel sorunlara yol a\u00e7abilir.<\/p>\n<h2>\ud83d\udcc8 \u0130leri D\u00fczey Optimizasyonlar ve Ek \u00d6zellikler: Deneyimi Nas\u0131l Zenginle\u015ftirebiliriz?<\/h2>\n<p>Temel bir rezervasyon sistemi olu\u015fturduk, ancak l\u00fcks segmentte rekabet edebilmek ve ger\u00e7ekten \u00fcst d\u00fczey bir deneyim sunabilmek i\u00e7in ileri d\u00fczey \u00f6zellikler ve optimizasyonlar eklememiz gerekiyor. Bu b\u00f6l\u00fcmde, sistemimizi bir ad\u0131m \u00f6teye ta\u015f\u0131yacak baz\u0131 ek \u00f6zelliklere ve performans iyile\u015ftirmelerine odaklanaca\u011f\u0131z.<\/p>\n<h3>Ger\u00e7ek Zamanl\u0131 Masa M\u00fcsaitli\u011fi ve \u00c7ak\u0131\u015fma Y\u00f6netimi<\/h3>\n<p>Basit bir \"ayn\u0131 saatte ba\u015fka rezervasyon var m\u0131?\" kontrol\u00fc, l\u00fcks bir restoran i\u00e7in yeterli de\u011fildir. Restoranlar\u0131n farkl\u0131 masa tipleri (cam kenar\u0131, \u00f6zel oda), farkl\u0131 kapasitelerdeki masalar\u0131 ve anl\u0131k iptaller gibi durumlar\u0131 y\u00f6netmesi gerekir.<\/p>\n<ul>\n<li><strong>Masa Y\u00f6netim Sistemi:<\/strong> Veritaban\u0131m\u0131zda <code>Table<\/code> (Masa) ad\u0131nda ayr\u0131 bir model tan\u0131mlayabiliriz. Bu model, her masan\u0131n kapasitesini, konumunu ve mevcut durumunu (\u00f6rne\u011fin, temizleniyor, dolu, bo\u015f) i\u00e7erebilir. Rezervasyon yaparken, kullan\u0131c\u0131n\u0131n tercihine ve ki\u015fi say\u0131s\u0131na uygun bir masa otomatik olarak atanabilir.<\/li>\n<li><strong>WebSockets (Socket.io\/Pusher):<\/strong> Ger\u00e7ek zamanl\u0131 g\u00fcncellemeler i\u00e7in WebSockets kullanmak, birden fazla kullan\u0131c\u0131n\u0131n veya restoran personelinin ayn\u0131 anda masa m\u00fcsaitli\u011fini g\u00f6rmesini sa\u011flar. Bir masa rezerve edildi\u011finde veya bo\u015fald\u0131\u011f\u0131nda, bu bilgi an\u0131nda di\u011fer t\u00fcm kullan\u0131c\u0131lara iletilir, b\u00f6ylece \u00e7ak\u0131\u015fmalar\u0131n \u00f6n\u00fcne ge\u00e7ilir ve do\u011fru bilgi her zaman g\u00f6sterilir.<\/li>\n<li><strong>\u0130yimser Kilitleme (Optimistic Locking):<\/strong> E\u015f zamanl\u0131 rezervasyon denemelerinde \u00e7ak\u0131\u015fmalar\u0131 \u00f6nlemek i\u00e7in bir stratejidir. Veritaban\u0131 kay\u0131tlar\u0131na bir s\u00fcr\u00fcm (version) alan\u0131 ekleyerek, bir kay\u0131t g\u00fcncellenmeye \u00e7al\u0131\u015f\u0131ld\u0131\u011f\u0131nda s\u00fcr\u00fcm kontrol edilir. E\u011fer s\u00fcr\u00fcm de\u011fi\u015fmi\u015fse, ba\u015fka bir kullan\u0131c\u0131n\u0131n kayd\u0131 daha \u00f6nce g\u00fcncelledi\u011fi anla\u015f\u0131l\u0131r ve rezervasyon iste\u011fi reddedilir.<\/li>\n<\/ul>\n<h3>G\u00fcvenli \u00d6deme Entegrasyonu<\/h3>\n<p>Baz\u0131 l\u00fcks restoranlar, rezervasyon garantisi olarak \u00f6n \u00f6deme veya depozito isteyebilir. Bu durumda, g\u00fcvenli bir \u00f6deme ge\u00e7idi entegrasyonu \u015fartt\u0131r.<\/p>\n<ul>\n<li><strong>Stripe veya Braintree:<\/strong> Bu \u00f6deme sa\u011flay\u0131c\u0131lar\u0131, kart bilgilerini g\u00fcvenli bir \u015fekilde i\u015flemek i\u00e7in g\u00fc\u00e7l\u00fc API'ler ve SDK'lar sunar. Kredi kart\u0131 bilgilerini kendi sunucular\u0131n\u0131zda saklamaktan ka\u00e7\u0131n\u0131n (PCI DSS uyumlulu\u011fu nedeniyle). Bunun yerine, \u00f6deme sa\u011flay\u0131c\u0131s\u0131n\u0131n tokenizasyon hizmetlerini kullan\u0131n.<\/li>\n<li><strong>\u00d6n Yetkilendirme (Pre-authorization):<\/strong> Rezervasyon an\u0131nda karttan belirli bir miktar \u00e7ekmek yerine, sadece bir \u00f6n yetkilendirme yaparak kart\u0131n ge\u00e7erlili\u011fini ve yeterli bakiyeyi kontrol edebilirsiniz. \u00d6deme, misafir restorana geldi\u011finde veya belirli bir s\u00fcre sonra tamamlan\u0131r.<\/li>\n<\/ul>\n<h3>Geli\u015fmi\u015f Y\u00f6netim Paneli ve Raporlama<\/h3>\n<p>Restoran y\u00f6neticileri i\u00e7in, rezervasyonlar\u0131 kolayca g\u00f6r\u00fcnt\u00fcleyebilecekleri, y\u00f6netebilecekleri ve analiz edebilecekleri kapsaml\u0131 bir y\u00f6netim paneli olmazsa olmazd\u0131r.<\/p>\n<ul>\n<li><strong>Admin Paneli:<\/strong> Belirli bir g\u00fcne ait t\u00fcm rezervasyonlar\u0131 listeleme, filtreleme, arama, manuel olarak rezervasyon ekleme\/d\u00fczenleme\/iptal etme yetene\u011fi.<\/li>\n<li><strong>Masa Plan\u0131 G\u00f6rselle\u015ftirme:<\/strong> Restoran\u0131n masa d\u00fczenini g\u00f6steren interaktif bir harita, hangi masalar\u0131n dolu, bo\u015f veya rezerve oldu\u011funu anl\u0131k olarak g\u00f6sterir.<\/li>\n<li><strong>Raporlama ve Analiz:<\/strong> Doluluk oranlar\u0131, en yo\u011fun saatler, m\u00fc\u015fteri tercihleri, iptal oranlar\u0131 gibi verilerin g\u00f6rsel raporlar\u0131, restoran\u0131n operasyonel kararlar almas\u0131na yard\u0131mc\u0131 olur. Metabase veya Grafana gibi ara\u00e7lar, bu t\u00fcr analizler i\u00e7in entegre edilebilir.<\/li>\n<\/ul>\n<h3>Bildirimler ve Hat\u0131rlat\u0131c\u0131lar<\/h3>\n<p>M\u00fc\u015fteri deneyimini art\u0131rmak ve no-show oranlar\u0131n\u0131 azaltmak i\u00e7in otomatik bildirimler \u00f6nemlidir.<\/p>\n<ul>\n<li><strong>E-posta Onay\u0131:<\/strong> Rezervasyon yap\u0131ld\u0131ktan hemen sonra detayl\u0131 bir onay e-postas\u0131 g\u00f6nderme.<\/li>\n<li><strong>SMS Hat\u0131rlat\u0131c\u0131lar\u0131:<\/strong> Rezervasyon tarihinden belirli bir s\u00fcre \u00f6nce (\u00f6rne\u011fin 24 saat \u00f6nce) SMS ile hat\u0131rlatma g\u00f6nderme. Twilio gibi servisler bu ama\u00e7la kullan\u0131labilir.<\/li>\n<li><strong>Webhook'lar:<\/strong> Harici CRM veya Pazarlama Otomasyon sistemlerine rezervasyon olaylar\u0131n\u0131 (olu\u015fturma, iptal) bildirmek i\u00e7in webhook'lar tan\u0131mlama.<\/li>\n<\/ul>\n<h3>Test Stratejileri<\/h3>\n<p>Uygulaman\u0131n kalitesini ve g\u00fcvenilirli\u011fini sa\u011flamak i\u00e7in kapsaml\u0131 testler \u00e7ok \u00f6nemlidir.<\/p>\n<ul>\n<li><strong>Birim Testleri (Unit Tests):<\/strong> Her bir fonksiyon veya bile\u015fenin ayr\u0131 ayr\u0131 do\u011fru \u00e7al\u0131\u015ft\u0131\u011f\u0131n\u0131 test edin (Jest, React Testing Library).<\/li>\n<li><strong>Entegrasyon Testleri (Integration Tests):<\/strong> Farkl\u0131 mod\u00fcllerin (\u00f6rne\u011fin, API rotas\u0131 ve veritaban\u0131 etkile\u015fimi) birlikte do\u011fru \u00e7al\u0131\u015ft\u0131\u011f\u0131n\u0131 test edin.<\/li>\n<li><strong>U\u00e7tan Uca Testler (End-to-End Tests - E2E):<\/strong> Kullan\u0131c\u0131 senaryolar\u0131n\u0131 bir taray\u0131c\u0131 ortam\u0131nda test edin (Playwright, Cypress). Bir kullan\u0131c\u0131n\u0131n rezervasyon yapma s\u00fcrecini ba\u015ftan sona sim\u00fcle edin.<\/li>\n<\/ul>\n<p>Bu ileri d\u00fczey \u00f6zellikler ve optimizasyonlar, bir l\u00fcks restoran rezervasyon sistemini sadece i\u015flevsel olmaktan \u00e7\u0131kar\u0131p, rekabet\u00e7i bir piyasada \u00f6ne \u00e7\u0131kmas\u0131n\u0131 sa\u011flayan, kullan\u0131c\u0131lar ve i\u015fletmeler i\u00e7in vazge\u00e7ilmez bir ara\u00e7 haline getirecektir. Next.js ve Prisma'n\u0131n mod\u00fcler yap\u0131s\u0131, bu \u00f6zelliklerin kademeli olarak entegre edilmesine olanak tan\u0131r.<\/p>\n<h2>\ud83c\udfaf Sonu\u00e7: Gelece\u011fin L\u00fcks Rezervasyon Deneyimi Avcunuzda<\/h2>\n<p>Bu kapsaml\u0131 makale boyunca, modern web geli\u015ftirme d\u00fcnyas\u0131n\u0131n iki g\u00fc\u00e7l\u00fc akt\u00f6r\u00fc olan Next.js ve Prisma'y\u0131 kullanarak l\u00fcks bir restoran rezervasyon sistemini s\u0131f\u0131rdan nas\u0131l in\u015fa edebilece\u011fimizi ad\u0131m ad\u0131m inceledik. Giri\u015f k\u0131sm\u0131nda kar\u015f\u0131la\u015ft\u0131\u011f\u0131m\u0131z operasyonel zorluklardan, temel proje kurulumuna, g\u00fc\u00e7l\u00fc API rotalar\u0131 geli\u015ftirmekten zarif bir kullan\u0131c\u0131 aray\u00fcz\u00fc tasarlamaya ve en \u00f6nemlisi, g\u00fcvenlik ve \u00f6l\u00e7eklenebilirlik gibi kritik konular\u0131 ele almaya kadar bir\u00e7ok \u00f6nemli ba\u015fl\u0131\u011f\u0131 kapsad\u0131k. Ayr\u0131ca, ger\u00e7ek zamanl\u0131 m\u00fcsaitlik takibi, g\u00fcvenli \u00f6deme entegrasyonlar\u0131 ve kapsaml\u0131 y\u00f6netim panelleri gibi ileri d\u00fczey \u00f6zelliklerle bu sistemin nas\u0131l zenginle\u015ftirilebilece\u011fini de g\u00f6rd\u00fck.<\/p>\n<p>Geli\u015ftirdi\u011fimiz bu sistem, sadece rezervasyon s\u00fcre\u00e7lerini otomatikle\u015ftirerek restoranlar\u0131n operasyonel y\u00fck\u00fcn\u00fc hafifletmekle kalmayacak, ayn\u0131 zamanda m\u00fc\u015fterilere h\u0131zl\u0131, sorunsuz ve g\u00fcvenli bir deneyim sunarak l\u00fcks hizmet anlay\u0131\u015f\u0131n\u0131 dijital d\u00fcnyaya ta\u015f\u0131yacakt\u0131r. Next.js'in performans, SEO ve geli\u015ftirici deneyimi konusundaki avantajlar\u0131 ile Prisma'n\u0131n tip g\u00fcvenli\u011fi, kolay veritaban\u0131 y\u00f6netimi ve h\u0131zl\u0131 prototipleme yetenekleri birle\u015fti\u011finde, ortaya \u00e7\u0131kan sonu\u00e7 ger\u00e7ekten etkileyicidir. Bu g\u00fc\u00e7l\u00fc kombinasyon, hem k\u00fc\u00e7\u00fck butik restoranlardan b\u00fcy\u00fck zincirlere kadar geni\u015f bir yelpazede i\u015fletmelerin ihtiya\u00e7lar\u0131na cevap verebilecek, hem de gelecekteki b\u00fcy\u00fcme ve ek \u00f6zellik entegrasyonlar\u0131 i\u00e7in sa\u011flam bir temel olu\u015fturacakt\u0131r.<\/p>\n<p>Unutmay\u0131n ki teknoloji s\u00fcrekli geli\u015fiyor. Bu makaledeki bilgiler, size sa\u011flam bir ba\u015flang\u0131\u00e7 noktas\u0131 sunsa da, en son teknolojileri ve en iyi uygulamalar\u0131 takip etmek, sisteminizi her zaman g\u00fcncel ve rekabet\u00e7i tutman\u0131n anahtar\u0131d\u0131r. Bu yolculukta edindi\u011finiz bilgilerle, siz de kendi l\u00fcks rezervasyon sisteminizi in\u015fa edebilir ve misafirlerinize unutulmaz bir dijital deneyim sunabilirsiniz.<\/p>\n<h3>\u2753 S\u0131k\u00e7a Sorulan Sorular (SSS)<\/h3>\n<ol>\n<li>\n<p><strong>Next.js ve Prisma ikilisi b\u00fcy\u00fck \u00f6l\u00e7ekli uygulamalar i\u00e7in uygun mu?<\/strong><\/p>\n<p>Kesinlikle evet. Next.js, SSR, SSG ve Incremental Static Regeneration (ISR) gibi \u00f6zellikleri sayesinde y\u00fcksek trafikli web siteleri i\u00e7in ola\u011fan\u00fcst\u00fc performans ve \u00f6l\u00e7eklenebilirlik sunar. API Routes ise sunucusuz mimariyle birle\u015fti\u011finde, talep artt\u0131k\u00e7a otomatik olarak \u00f6l\u00e7eklenebilir backend \u00e7\u00f6z\u00fcmleri sa\u011flar. Prisma ise geli\u015fmi\u015f ba\u011flant\u0131 havuzlama, sorgu optimizasyonu ve g\u00fc\u00e7l\u00fc migration sistemi ile b\u00fcy\u00fck veritabanlar\u0131n\u0131 etkin bir \u015fekilde y\u00f6netebilir. Bu iki teknoloji, birlikte \u00e7al\u0131\u015farak l\u00fcks rezervasyon sisteminiz i\u00e7in hem frontend hem de backend taraf\u0131nda g\u00fc\u00e7l\u00fc ve \u00f6l\u00e7eklenebilir bir altyap\u0131 olu\u015fturur.<\/p>\n<\/li>\n<li>\n<p><strong>Sistemde g\u00fcvenlik nas\u0131l sa\u011flan\u0131r?<\/strong><\/p>\n<p>G\u00fcvenlik, bu t\u00fcr bir sistemde en \u00f6nemli fakt\u00f6rlerden biridir. Makalede bahsedildi\u011fi gibi, NextAuth.js veya JWT kullanarak g\u00fc\u00e7l\u00fc kimlik do\u011frulama mekanizmalar\u0131 uygulayabiliriz. Veritaban\u0131nda hassas verileri (\u00f6rne\u011fin \u015fifreleri) asla d\u00fcz metin olarak saklamamal\u0131, bunun yerine bcrypt gibi k\u00fct\u00fcphanelerle hashlemeliyiz. T\u00fcm API istekleri i\u00e7in sunucu taraf\u0131nda kapsaml\u0131 giri\u015f do\u011frulama ve yetkilendirme (rol tabanl\u0131 eri\u015fim kontrol\u00fc) yap\u0131lmal\u0131d\u0131r. Ayr\u0131ca, SQL enjeksiyonu gibi yayg\u0131n g\u00fcvenlik a\u00e7\u0131klar\u0131na kar\u015f\u0131 Prisma gibi ORM'ler do\u011fal koruma sa\u011flar.<\/p>\n<\/li>\n<li>\n<p><strong>Mobil uyumluluk i\u00e7in nelere dikkat etmeliyim?<\/strong><\/p>\n<p>Mobil uyumluluk i\u00e7in duyarl\u0131 tasar\u0131m (responsive design) \u015fartt\u0131r. Tailwind CSS gibi bir utility-first CSS framework'\u00fc kullanarak veya CSS media query'leri ile farkl\u0131 ekran boyutlar\u0131na uygun stiller tan\u0131mlayarak ba\u015flayabilirsiniz. Kullan\u0131c\u0131 aray\u00fcz\u00fc bile\u015fenlerinin k\u00fc\u00e7\u00fck ekranlarda iyi g\u00f6r\u00fcnmesini ve kolayca etkile\u015fim kurulabilmesini sa\u011flamal\u0131s\u0131n\u0131z. Dokunmatik ekran dostu navigasyon, b\u00fcy\u00fck ve t\u0131klanabilir d\u00fc\u011fmeler, okunabilir yaz\u0131 tipleri ve form elemanlar\u0131n\u0131n optimize edilmi\u015f d\u00fczeni mobil deneyimi iyile\u015ftirir.<\/p>\n<\/li>\n<li>\n<p><strong>Rezervasyon sistemini canl\u0131ya almak (deploy etmek) i\u00e7in hangi platformlar\u0131 \u00f6nerirsiniz?<\/strong><\/p>\n<p>Next.js uygulamalar\u0131 i\u00e7in Vercel, en pop\u00fcler ve \u00f6nerilen da\u011f\u0131t\u0131m platformudur. Next.js'in yarat\u0131c\u0131lar\u0131 taraf\u0131ndan geli\u015ftirildi\u011fi i\u00e7in en iyi performans\u0131 ve entegrasyonu sunar. Otomatik da\u011f\u0131t\u0131m, sunucusuz fonksiyonlar i\u00e7in optimize edilmi\u015f hosting, CDN ve global edge network gibi \u00f6zellikler i\u00e7erir. Veritaban\u0131 i\u00e7in ise Vercel'in kendi Postgres \u00e7\u00f6z\u00fcm\u00fc, Supabase veya Railway gibi y\u00f6netilen PostgreSQL hizmetleri h\u0131zl\u0131 ve kolay kurulum sa\u011flar.<\/p>\n<\/li>\n<li>\n<p><strong>Ger\u00e7ek zamanl\u0131 masa m\u00fcsaitli\u011fi \u00f6zelli\u011fi nas\u0131l uygulan\u0131r?<\/strong><\/p>\n<p>Ger\u00e7ek zamanl\u0131 masa m\u00fcsaitli\u011fi i\u00e7in WebSockets teknolojisinden faydalanabilirsiniz. Socket.io veya Pusher gibi k\u00fct\u00fcphaneleri kullanarak istemci ile sunucu aras\u0131nda \u00e7ift y\u00f6nl\u00fc, kal\u0131c\u0131 bir ba\u011flant\u0131 kurabilirsiniz. Bir masa rezerve edildi\u011finde veya iptal edildi\u011finde, sunucu bu durumu WebSocket \u00fczerinden ba\u011fl\u0131 t\u00fcm istemcilere (\u00f6rne\u011fin, di\u011fer m\u00fc\u015fterilere veya restoran personeline ait panellere) an\u0131nda bildirir. Bu sayede, kullan\u0131c\u0131lar her zaman g\u00fcncel m\u00fcsaitlik durumunu g\u00f6r\u00fcr ve \u00e7ak\u0131\u015fan rezervasyonlar\u0131n \u00f6n\u00fcne ge\u00e7ilmi\u015f olur.<\/p>\n<\/li>\n<\/ol>\n<p><\/body><\/p>\n","protected":false},"excerpt":{"rendered":"L\u00fcks restoranlarda rezervasyon yapmak, bazen yorucu bir s\u00fcre\u00e7 haline gelebilir. Peki, modern web teknolojilerini kullanarak, bu deneyimi hem&hellip;","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"csco_page_header_type":"","csco_page_load_nextpost":"","csco_page_subscribe_form":"","csco_page_contact_form":"","footnotes":""},"categories":[1469],"tags":[],"class_list":{"0":"post-30781","1":"post","2":"type-post","3":"status-publish","4":"format-standard","6":"category-nextjs","7":"cs-entry","8":"cs-video-wrap"},"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v20.5 (Yoast SEO v25.3.1) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>L\u00fcks Restoran Rezervasyon Sistemi: Next.js &amp; Prisma ile Nas\u0131l Yap\u0131l\u0131r?<\/title>\n<meta name=\"description\" content=\"L\u00fcks restoranlarda rezervasyon yapmak, bazen yorucu bir s\u00fcre\u00e7 haline gelebilir. Peki, modern web teknolojilerini kullanarak, bu deneyimi hem restoranlar hem de m\u00fc\u015fteriler i\u00e7in p\u00fcr\u00fczs\u00fcz ve keyifli bir hale getirebilir miyiz? Bu makalede, Next.js ve Prisma ikilisinin g\u00fcc\u00fcn\u00fc birle\u015ftirerek nas\u0131l \u00fcst d\u00fczey bir restoran rezervasyon sistemi geli\u015ftirebilece\u011fimizi ad\u0131m ad\u0131m inceleyece\u011fiz. Bu rehber, sadece teknik detaylar\u0131 de\u011fil, ayn\u0131 zamanda kullan\u0131c\u0131 deneyimi ve \u00f6l\u00e7eklenebilirlik gibi kritik fakt\u00f6rleri de kapsayarak, projeyi s\u0131f\u0131rdan hayata ge\u00e7irmenize yard\u0131mc\u0131 olacak.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/fatihsoysal.com\/blog\/luks-restoran-rezervasyon-sistemi-next-js-prisma-ile-nasil-yapilir\/\" \/>\n<meta property=\"og:locale\" content=\"tr_TR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"L\u00fcks Restoran Rezervasyon Sistemi: Next.js &amp; Prisma ile Nas\u0131l Yap\u0131l\u0131r?\" \/>\n<meta property=\"og:description\" content=\"L\u00fcks restoranlarda rezervasyon yapmak, bazen yorucu bir s\u00fcre\u00e7 haline gelebilir. Peki, modern web teknolojilerini kullanarak, bu deneyimi hem restoranlar hem de m\u00fc\u015fteriler i\u00e7in p\u00fcr\u00fczs\u00fcz ve keyifli bir hale getirebilir miyiz? Bu makalede, Next.js ve Prisma ikilisinin g\u00fcc\u00fcn\u00fc birle\u015ftirerek nas\u0131l \u00fcst d\u00fczey bir restoran rezervasyon sistemi geli\u015ftirebilece\u011fimizi ad\u0131m ad\u0131m inceleyece\u011fiz. Bu rehber, sadece teknik detaylar\u0131 de\u011fil, ayn\u0131 zamanda kullan\u0131c\u0131 deneyimi ve \u00f6l\u00e7eklenebilirlik gibi kritik fakt\u00f6rleri de kapsayarak, projeyi s\u0131f\u0131rdan hayata ge\u00e7irmenize yard\u0131mc\u0131 olacak.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/fatihsoysal.com\/blog\/luks-restoran-rezervasyon-sistemi-next-js-prisma-ile-nasil-yapilir\/\" \/>\n<meta property=\"og:site_name\" content=\"Kodlar\u0131n Gizemli D\u00fcnyas\u0131\" \/>\n<meta property=\"article:published_time\" content=\"2025-10-01T23:32:14+00:00\" \/>\n<meta name=\"author\" content=\"Fatih Soysal\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Yazan:\" \/>\n\t<meta name=\"twitter:data1\" content=\"Fatih Soysal\" \/>\n\t<meta name=\"twitter:label2\" content=\"Tahmini okuma s\u00fcresi\" \/>\n\t<meta name=\"twitter:data2\" content=\"20 dakika\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/luks-restoran-rezervasyon-sistemi-next-js-prisma-ile-nasil-yapilir\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/luks-restoran-rezervasyon-sistemi-next-js-prisma-ile-nasil-yapilir\/\"},\"author\":{\"name\":\"Fatih Soysal\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\"},\"headline\":\"L\u00fcks Restoran Rezervasyon Sistemi: Next.js &amp; Prisma ile Nas\u0131l Yap\u0131l\u0131r?\",\"datePublished\":\"2025-10-01T23:32:14+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/luks-restoran-rezervasyon-sistemi-next-js-prisma-ile-nasil-yapilir\/\"},\"wordCount\":5530,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\"},\"articleSection\":[\"NextJS\"],\"inLanguage\":\"tr\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/fatihsoysal.com\/blog\/luks-restoran-rezervasyon-sistemi-next-js-prisma-ile-nasil-yapilir\/#respond\"]}],\"copyrightYear\":\"2025\",\"copyrightHolder\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/luks-restoran-rezervasyon-sistemi-next-js-prisma-ile-nasil-yapilir\/\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/luks-restoran-rezervasyon-sistemi-next-js-prisma-ile-nasil-yapilir\/\",\"name\":\"L\u00fcks Restoran Rezervasyon Sistemi: Next.js &amp; Prisma ile Nas\u0131l Yap\u0131l\u0131r?\",\"isPartOf\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#website\"},\"datePublished\":\"2025-10-01T23:32:14+00:00\",\"description\":\"L\u00fcks restoranlarda rezervasyon yapmak, bazen yorucu bir s\u00fcre\u00e7 haline gelebilir. Peki, modern web teknolojilerini kullanarak, bu deneyimi hem restoranlar hem de m\u00fc\u015fteriler i\u00e7in p\u00fcr\u00fczs\u00fcz ve keyifli bir hale getirebilir miyiz? Bu makalede, Next.js ve Prisma ikilisinin g\u00fcc\u00fcn\u00fc birle\u015ftirerek nas\u0131l \u00fcst d\u00fczey bir restoran rezervasyon sistemi geli\u015ftirebilece\u011fimizi ad\u0131m ad\u0131m inceleyece\u011fiz. Bu rehber, sadece teknik detaylar\u0131 de\u011fil, ayn\u0131 zamanda kullan\u0131c\u0131 deneyimi ve \u00f6l\u00e7eklenebilirlik gibi kritik fakt\u00f6rleri de kapsayarak, projeyi s\u0131f\u0131rdan hayata ge\u00e7irmenize yard\u0131mc\u0131 olacak.\",\"breadcrumb\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/luks-restoran-rezervasyon-sistemi-next-js-prisma-ile-nasil-yapilir\/#breadcrumb\"},\"inLanguage\":\"tr\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/fatihsoysal.com\/blog\/luks-restoran-rezervasyon-sistemi-next-js-prisma-ile-nasil-yapilir\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/luks-restoran-rezervasyon-sistemi-next-js-prisma-ile-nasil-yapilir\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Anasayfa\",\"item\":\"https:\/\/fatihsoysal.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"L\u00fcks Restoran Rezervasyon Sistemi: Next.js &amp; Prisma ile Nas\u0131l Yap\u0131l\u0131r?\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#website\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/\",\"name\":\"Fatihsoysal.com\",\"description\":\"Blog - Yaz\u0131l\u0131m D\u00fcnyas\u0131 Tecr\u00fcbelerim\",\"publisher\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/fatihsoysal.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"tr\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\",\"name\":\"Fatih Soysal\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"tr\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png\",\"contentUrl\":\"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png\",\"width\":512,\"height\":512,\"caption\":\"Fatih Soysal\"},\"logo\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/\"},\"description\":\"Kullan\u0131m ve kodlama m\u00fckemmeliyetini odak alan uygulamalar olu\u015fturma deneyimine sahip, profesyonel olarak 15+ y\u0131l \u00fczeri deneyime sahip bir yaz\u0131l\u0131m m\u00fchendisi.\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/author\/fatihsoysal\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"L\u00fcks Restoran Rezervasyon Sistemi: Next.js &amp; Prisma ile Nas\u0131l Yap\u0131l\u0131r?","description":"L\u00fcks restoranlarda rezervasyon yapmak, bazen yorucu bir s\u00fcre\u00e7 haline gelebilir. Peki, modern web teknolojilerini kullanarak, bu deneyimi hem restoranlar hem de m\u00fc\u015fteriler i\u00e7in p\u00fcr\u00fczs\u00fcz ve keyifli bir hale getirebilir miyiz? Bu makalede, Next.js ve Prisma ikilisinin g\u00fcc\u00fcn\u00fc birle\u015ftirerek nas\u0131l \u00fcst d\u00fczey bir restoran rezervasyon sistemi geli\u015ftirebilece\u011fimizi ad\u0131m ad\u0131m inceleyece\u011fiz. Bu rehber, sadece teknik detaylar\u0131 de\u011fil, ayn\u0131 zamanda kullan\u0131c\u0131 deneyimi ve \u00f6l\u00e7eklenebilirlik gibi kritik fakt\u00f6rleri de kapsayarak, projeyi s\u0131f\u0131rdan hayata ge\u00e7irmenize yard\u0131mc\u0131 olacak.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/fatihsoysal.com\/blog\/luks-restoran-rezervasyon-sistemi-next-js-prisma-ile-nasil-yapilir\/","og_locale":"tr_TR","og_type":"article","og_title":"L\u00fcks Restoran Rezervasyon Sistemi: Next.js &amp; Prisma ile Nas\u0131l Yap\u0131l\u0131r?","og_description":"L\u00fcks restoranlarda rezervasyon yapmak, bazen yorucu bir s\u00fcre\u00e7 haline gelebilir. Peki, modern web teknolojilerini kullanarak, bu deneyimi hem restoranlar hem de m\u00fc\u015fteriler i\u00e7in p\u00fcr\u00fczs\u00fcz ve keyifli bir hale getirebilir miyiz? Bu makalede, Next.js ve Prisma ikilisinin g\u00fcc\u00fcn\u00fc birle\u015ftirerek nas\u0131l \u00fcst d\u00fczey bir restoran rezervasyon sistemi geli\u015ftirebilece\u011fimizi ad\u0131m ad\u0131m inceleyece\u011fiz. Bu rehber, sadece teknik detaylar\u0131 de\u011fil, ayn\u0131 zamanda kullan\u0131c\u0131 deneyimi ve \u00f6l\u00e7eklenebilirlik gibi kritik fakt\u00f6rleri de kapsayarak, projeyi s\u0131f\u0131rdan hayata ge\u00e7irmenize yard\u0131mc\u0131 olacak.","og_url":"https:\/\/fatihsoysal.com\/blog\/luks-restoran-rezervasyon-sistemi-next-js-prisma-ile-nasil-yapilir\/","og_site_name":"Kodlar\u0131n Gizemli D\u00fcnyas\u0131","article_published_time":"2025-10-01T23:32:14+00:00","author":"Fatih Soysal","twitter_card":"summary_large_image","twitter_misc":{"Yazan:":"Fatih Soysal","Tahmini okuma s\u00fcresi":"20 dakika"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/fatihsoysal.com\/blog\/luks-restoran-rezervasyon-sistemi-next-js-prisma-ile-nasil-yapilir\/#article","isPartOf":{"@id":"https:\/\/fatihsoysal.com\/blog\/luks-restoran-rezervasyon-sistemi-next-js-prisma-ile-nasil-yapilir\/"},"author":{"name":"Fatih Soysal","@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1"},"headline":"L\u00fcks Restoran Rezervasyon Sistemi: Next.js &amp; Prisma ile Nas\u0131l Yap\u0131l\u0131r?","datePublished":"2025-10-01T23:32:14+00:00","mainEntityOfPage":{"@id":"https:\/\/fatihsoysal.com\/blog\/luks-restoran-rezervasyon-sistemi-next-js-prisma-ile-nasil-yapilir\/"},"wordCount":5530,"commentCount":0,"publisher":{"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1"},"articleSection":["NextJS"],"inLanguage":"tr","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/fatihsoysal.com\/blog\/luks-restoran-rezervasyon-sistemi-next-js-prisma-ile-nasil-yapilir\/#respond"]}],"copyrightYear":"2025","copyrightHolder":{"@id":"https:\/\/fatihsoysal.com\/blog\/#organization"}},{"@type":"WebPage","@id":"https:\/\/fatihsoysal.com\/blog\/luks-restoran-rezervasyon-sistemi-next-js-prisma-ile-nasil-yapilir\/","url":"https:\/\/fatihsoysal.com\/blog\/luks-restoran-rezervasyon-sistemi-next-js-prisma-ile-nasil-yapilir\/","name":"L\u00fcks Restoran Rezervasyon Sistemi: Next.js &amp; Prisma ile Nas\u0131l Yap\u0131l\u0131r?","isPartOf":{"@id":"https:\/\/fatihsoysal.com\/blog\/#website"},"datePublished":"2025-10-01T23:32:14+00:00","description":"L\u00fcks restoranlarda rezervasyon yapmak, bazen yorucu bir s\u00fcre\u00e7 haline gelebilir. Peki, modern web teknolojilerini kullanarak, bu deneyimi hem restoranlar hem de m\u00fc\u015fteriler i\u00e7in p\u00fcr\u00fczs\u00fcz ve keyifli bir hale getirebilir miyiz? Bu makalede, Next.js ve Prisma ikilisinin g\u00fcc\u00fcn\u00fc birle\u015ftirerek nas\u0131l \u00fcst d\u00fczey bir restoran rezervasyon sistemi geli\u015ftirebilece\u011fimizi ad\u0131m ad\u0131m inceleyece\u011fiz. Bu rehber, sadece teknik detaylar\u0131 de\u011fil, ayn\u0131 zamanda kullan\u0131c\u0131 deneyimi ve \u00f6l\u00e7eklenebilirlik gibi kritik fakt\u00f6rleri de kapsayarak, projeyi s\u0131f\u0131rdan hayata ge\u00e7irmenize yard\u0131mc\u0131 olacak.","breadcrumb":{"@id":"https:\/\/fatihsoysal.com\/blog\/luks-restoran-rezervasyon-sistemi-next-js-prisma-ile-nasil-yapilir\/#breadcrumb"},"inLanguage":"tr","potentialAction":[{"@type":"ReadAction","target":["https:\/\/fatihsoysal.com\/blog\/luks-restoran-rezervasyon-sistemi-next-js-prisma-ile-nasil-yapilir\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/fatihsoysal.com\/blog\/luks-restoran-rezervasyon-sistemi-next-js-prisma-ile-nasil-yapilir\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Anasayfa","item":"https:\/\/fatihsoysal.com\/blog\/"},{"@type":"ListItem","position":2,"name":"L\u00fcks Restoran Rezervasyon Sistemi: Next.js &amp; Prisma ile Nas\u0131l Yap\u0131l\u0131r?"}]},{"@type":"WebSite","@id":"https:\/\/fatihsoysal.com\/blog\/#website","url":"https:\/\/fatihsoysal.com\/blog\/","name":"Fatihsoysal.com","description":"Blog - Yaz\u0131l\u0131m D\u00fcnyas\u0131 Tecr\u00fcbelerim","publisher":{"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/fatihsoysal.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"tr"},{"@type":["Person","Organization"],"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1","name":"Fatih Soysal","image":{"@type":"ImageObject","inLanguage":"tr","@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/","url":"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png","contentUrl":"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png","width":512,"height":512,"caption":"Fatih Soysal"},"logo":{"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/"},"description":"Kullan\u0131m ve kodlama m\u00fckemmeliyetini odak alan uygulamalar olu\u015fturma deneyimine sahip, profesyonel olarak 15+ y\u0131l \u00fczeri deneyime sahip bir yaz\u0131l\u0131m m\u00fchendisi.","url":"https:\/\/fatihsoysal.com\/blog\/author\/fatihsoysal\/"}]}},"yoast_meta":{"yoast_wpseo_title":"","yoast_wpseo_metadesc":"","yoast_wpseo_canonical":""},"amp_enabled":true,"_links":{"self":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts\/30781","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/comments?post=30781"}],"version-history":[{"count":0,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts\/30781\/revisions"}],"wp:attachment":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/media?parent=30781"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/categories?post=30781"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/tags?post=30781"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}