نوشته‌ها

تحویل پلتفرم‌های واقعی با SvelteKit، TypeScript و PostgreSQL

بیشتر پلتفرم‌هایی که در کنوین می‌سازم — جذوه، درمانجو، ام‌کی پاور، پناه سرام، کپی‌پاستا و ۱۱۸ایکس — روی یک ستون فقرات مشترک‌اند: SvelteKit و TypeScript، Drizzle روی PostgreSQL و استقرار روی Vercel. اینجا می‌گویم چرا این پشته برنده شد و محصول فارسیِ واقعی چه یادم داد.

یک ستون فقرات پشت بیشتر پلتفرم‌های اخیر من

به پلتفرم‌هایی که این اواخر در کنوین تحویل داده‌ام نگاه کنی یک الگو تکرار می‌شود: جذوه کافه را از سر تا ته می‌چرخاند، درمانجو یک کلینیک زخم را، ام‌کی پاور قطعهٔ موتور را با شمارهٔ فنی می‌فروشد، پناه سرام کاتالوگ تجهیزات بهداشتی است، کپی‌پاستا متن و کد به اشتراک می‌گذارد و ۱۱۸ایکس به کسب‌وکار محلی صفحهٔ خودش را می‌دهد. کسب‌وکارها فرق دارند، ستون فقرات یکی است: SvelteKit و TypeScript، لایهٔ دادهٔ PostgreSQL با Drizzle، رابط Tailwind و استقرار روی Vercel. این نوشته دربارهٔ این است که چرا این پشته لایق تکرار شد.

ستون فقرات مشترک یک معاملهٔ آگاهانه است: تازگیِ هر پروژه را می‌دهی و برای یک استودیوی کوچک چیز باارزش‌تری می‌گیری؛ هر درس سخت — احراز هویت، آپلود، محدودیت نرخ، ویرایش ادمین، تایپوگرافی فارسی، استقرار — یک‌بار آموخته می‌شود و محصول بعدی به ارث می‌بردش، به جای اینکه دوباره به قیمت کامل خریده شود.

چرا SvelteKit به کار محصول می‌خورد؟

کار محصول بیشترش فرم و فهرست و سطح دسترسی و فایل و پول است. مدل SvelteKit تمیز روی همین واقعیت می‌نشیند: صفحه‌ها پیش‌فرض سمت سرور رندر می‌شوند، اکشن فرم و تابع load کنار همان مسیری‌اند که سرو می‌کنند و تایپ‌های TypeScript از اسکیمای دیتابیس تا کامپوننت جریان دارند، بی‌آنکه یک لایهٔ API دست‌نویس وسط باشد. حاصلش یک کدبیس است که در آن فاصلهٔ «کافه‌دار فلان چیز را می‌خواهد» تا تحویل همان چیز کوتاه می‌ماند؛ برای نوع پلتفرم‌هایی که من می‌سازم این از هر بنچمارک فریم‌ورکی مهم‌تر است.

خود Svelte هم کمک می‌کند چون سر راه نمی‌ایستد: کامپوننت شبیه همان HTMLای خوانده می‌شود که تولید می‌کند، واکنش‌پذیری‌اش صریح است و خروجی کامپایل‌شده صفحه‌ها را برای کاربر با گوشی و اینترنت معمولی سبک نگه می‌دارد؛ همان آدمی که کد QR میز کافه را اسکن می‌کند یا از تعمیرگاه قیمت قطعه چک می‌کند.

Drizzle و PostgreSQL؛ کسل‌کننده، به بهترین معنا

زیر این پلتفرم‌ها PostgreSQL نشسته و Drizzle لایهٔ کوئری و اسکیماست. جایی دیگر دربارهٔ احترام به دیتابیس نوشته‌ام؛ Drizzle با آن نگاه جور است چون SQL جلوی چشم می‌ماند: کوئری شبیه همان چیزی است که اجرا می‌شود، اسکیما TypeScript است و وقتی صفحه‌ای کند شد می‌توانم دربارهٔ خود کوئری فکر کنم، نه رمزگشایی رفتار ORM. هرجا شکل استقرار بخواهد آن PostgreSQL روی Neon است — ام‌کی پاور و پناه سرام همین‌طورند — بی‌آنکه خواندن کد عوض شود.

خلاصهٔ صادقانهٔ فلسفهٔ دیتابیس من بعد از جاجیگا و این پلتفرم‌ها: دیتابیس رابطه‌ای را انتخاب کن، داده را ساده مدل کن، روی چیزی ایندکس بگذار که محصول واقعاً کوئری می‌زند و یک جای واضح برای زندگی کوئری‌ها داشته باش. لایهٔ دادهٔ عجیب، مالیاتی است که هر فیچر آینده می‌پردازد.

محصول فارسی و کاربر واقعی

بیشتر این پلتفرم‌ها فارسی‌اند و راست‌به‌چپ و این یک محدودیت مهندسی است، نه یک لایه رنگ. پنل جذوه از سر تا ته فارسی و راست‌به‌چپ است چون پرسنل کافه فارسی کار می‌کنند؛ درمانجو محتوای فارسی را با ساختار چندزبانهٔ Paraglide ترکیب می‌کند؛ ام‌کی پاور باید شمارهٔ فنی را برای مکانیکی پیدا کند که آن را از روی یادداشت تعمیرگاه تایپ می‌کند. عدد و تاریخ و پول و رفتار جست‌وجو و حتی اینکه جریان اسکن QR میز از کدام طرف شروع شود؛ زبان به همه‌اش می‌رسد.

این‌طوری ساختن پیش‌فرض‌هایم را عوض کرد: تایپوگرافی فارسی (وزیرمتن همه‌جا)، نمایش آگاه از تقویم و محتوای دوجهته — یک شمارهٔ فنی لاتین وسط جملهٔ فارسی — برای من دغدغهٔ روز اول است. چسباندن راست‌به‌چپ روی محصول تمام‌شده پنج برابر طراحی از اول با آن کار می‌برد و کاربر همیشه می‌فهمد کدام را انجام داده‌ای.

جزئیاتی که روی هم اثر مرکب می‌گذارند

ستون فقرات یعنی تصمیم‌های کوچک هم اثر مرکب پیدا می‌کنند: آپلودها با لینک امضاشده مستقیم روی فضای S3 می‌روند نه از دل سرور برنامه؛ ادمین محتوا را در Tiptap ویرایش می‌کند نه اینکه من ردیف دیتابیس دست‌کاری کنم؛ ام‌کی پاور جایی که ترافیک کاتالوگش توجیه می‌کند tRPC و محدودیت نرخ با Upstash دارد و کپی‌پاستا عمداً تقریباً هیچی جز SvelteKit و Postgres ندارد چون محصول یک ابزار تیزِ تک‌کاره است. یک ستون فقرات، وزن متفاوت برای هر محصول؛ پشته خم می‌شود بی‌آنکه بشکند.

استقرار هم مرکب می‌شود: یک آداپتور، یک شکل میزبانی، پیش‌نمایش برای هر برنچ و همان غریزه‌های عملیاتی روی شش محصول. وقتی ساعت نه شب در یک پلتفرم چیزی بدرفتاری می‌کند، معمولاً همان جنس مسئله را قبلاً در یکی دیگر دیده‌ام. این آشنایی یک قابلیت عملیاتی است که هیچ جدول مقایسهٔ فریم‌ورکی نشانت نمی‌دهد.

سرعت و دیده‌شدن هم برای این کسب‌وکارها به همان اندازه عملی مهم است: صفحهٔ عمومی — سرویس‌های یک کلینیک، کاتالوگ تجهیزات بهداشتی، صفحهٔ یک کسب‌وکار محلی در ۱۱۸ایکس — باید هم سریع باز شود هم برای موتور جست‌وجو و موتور پاسخ خوانا باشد؛ برای همین رندر سمت سرور و پیش‌رندر پیش‌فرض من است و غنای سمت کلاینت فقط جایی اضافه می‌شود که محصول واقعاً لازمش دارد: پنل زندهٔ کافه، جست‌وجوی قطعه، نمایشگر پیست. در همین سایت این انضباط به افراطش رسیده: هر صفحه در هر دو زبان پیش‌رندر می‌شود و دادهٔ ساخت‌یافته و نسخهٔ متنی‌اش از همان محتوای واحد تولید می‌شود. سرعت به ندرت محصول بهینه‌سازی قهرمانانه است؛ محصول این است که وزنی را که صفحه لازم ندارد نفرستی.

حواسم به چه چیزهایی هست؟

هیچ پشته‌ای مجانی نیست. اکوسیستم SvelteKit از React جوان‌تر است و بعضی اتصال‌ها قلمرو «خودت بساز» است؛ کار فریم‌ورکی‌ام روی SvelteKit یعنی Yoshi بخشی برای صاف کردن دقیقاً همین لبه‌هاست. استقرار Serverless دسترسی پرحرف به دیتابیس را تنبیه می‌کند، پس انضباط کوئری از فیچر اول لازم است. و ستون فقرات مشترک فقط وقتی جواب می‌دهد که در برابر فورک کردنش برای هر پروژه مقاومت کنی تا بخش «مشترک»ش نظری نشود.

با همهٔ این هزینه‌ها روی میز، این همان پشته‌ای است که امروز دوباره برای پلتفرم محصولی انتخابش می‌کنم؛ چون شش تای آن‌ها — به اضافهٔ همین سایت — را با همان چند ایدهٔ کوچک از بریف به پروداکشن رسانده است. اگر در فکر ساخت یک پلتفرمی و می‌خواهی رو چیزی ساخته شود که امتحانش را پس داده، رزومه‌ام جای شروع است.

همه نوشته‌ها