بازگشت به نمونه کارها
TypeScriptNext.jsPrismaPostgreSQLFlutterDocker

مال تو — پلتفرم مدیریت زندگی

پلتفرم مدیریت زندگی با رویکرد «اول بک‌اند» — مالی، وظایف، عادت‌ها و تقویم جلالی پشت یک API واحد که وب، اندروید و ایجنت‌های هوش مصنوعی همگی از آن استفاده می‌کنند

معرفی

مال تو یک پلتفرم مدیریت زندگی است که با رویکرد «اول بک‌اند» ساخته شده: مدیریت مالی، وظایف، عادت‌ها، تقویم جلالی، یادداشت‌ها، گزارش‌ها و هوش مصنوعی — همه پشت یک API واحد. وب‌سایت در این معماری فقط «کلاینت شماره یک» است؛ اپلیکیشن اندروید، دسکتاپ، ربات تلگرام، ایجنت‌های هوش مصنوعی و کلاینت‌های MCP باید بتوانند بدون هیچ تغییری در بک‌اند، از همان API استفاده کنند.

چالش

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

  • محاسبه‌ی موجودی، استریک عادت‌ها و ترتیب کانبان اگر در کلاینت انجام شوند، در هر کلاینت جواب متفاوتی می‌دهند.

  • تقویم فارسی صرفاً یک مسئله‌ی نمایشی نیست؛ تکرار رویداد، تعطیلات رسمی ایران و بازه‌های گزارش‌گیری همگی باید سمت سرور درست باشند.

  • بدون مرز مشخص بین لایه‌ها، «فقط همین یک بار» وارد کردن دیتابیس در کامپوننت UI، به‌سرعت تبدیل به معماری دائمی می‌شود.

راهکار

یک مونوریپو با npm workspaces که در آن مرزهای معماری نه با توافق، بلکه به‌صورت مکانیکی اجرا می‌شوند:

  • packages/contracts — اسکیماهای Zod به‌عنوان قرارداد رسمی بین سرور و همه‌ی کلاینت‌ها.

  • packages/core — تنها جایی که منطق کسب‌وکار وجود دارد و تنها جایی که به لایه‌ی دیتابیس دسترسی دارد. بدون هیچ ایمپورتی از Next.js.

  • packages/db — اسکیمای Prisma و کلاس‌های ریپازیتوری، هرکدام با اینترفیس مجزا برای تست‌پذیری.

  • apps/web — رابط کاربری Next.js 16 با App Router و روت‌هندلرهای /api/v1 که فقط کنترلرهای نازک‌اند.

  • apps/worker — مصرف‌کننده‌های BullMQ و کران‌جاب‌ها.

  • mobile — کلاینت Flutter برای اندروید که دقیقاً همان API را مصرف می‌کند.

این مرزها با eslint-plugin-boundaries در ریشه‌ی پروژه تعریف شده‌اند؛ یعنی ایمپورت‌کردن @lifeos/db از داخل یک کامپوننت UI باعث شکست لینت می‌شود، نه صرفاً نقض یک قرارداد شفاهی.

ماژول‌ها

  • احراز هویت: ورود با کد یک‌بارمصرف، توکن دسترسی JWT کوتاه‌عمر به‌همراه رفرش‌توکن‌های مبهم و چرخشی، و مدیریت نشست‌ها و دستگاه‌های فعال.

  • مالی: کیف‌پول، دسته‌بندی، تراکنش و بودجه — با موجودیِ همیشه محاسبه‌شده (هرگز ذخیره‌نشده) و مسیر ایجاد/ویرایش idempotent از طریق هدر Idempotency-Key.

  • وظایف: تسک، ساب‌تسک، پروژه و برچسب، با ترتیب دستی کانبان که مالکیتش سمت سرور است.

  • تقویم: رویدادهای جلالی و میلادی با تکرار مبتنی بر rrule، تعطیلات رسمی ایران، نمای اجندا و نمای هفتگی با شروع از شنبه.

  • عادت‌ها: چک‌این روزانه و هفتگی با استریکی که هنگام خواندن از تاریخچه محاسبه می‌شود، نه ذخیره.

  • گزارش‌ها و اعلان‌ها: اعلان درون‌برنامه‌ای، تریگر «عبور از بودجه» و اندپوینت گزارش ترکیبی داشبورد.

نتیجه

  • هر شش ماژول رابط کاربری کامل دارند — رابط کاربری با Tailwind v4، shadcn/ui و TanStack Query، به‌صورت فارسی و راست‌به‌چپ.

  • اپلیکیشن اندروید با Flutter ساخته شده و بیلد ریلیز آن کار می‌کند؛ همان API وب را مصرف می‌کند بدون هیچ تغییری در بک‌اند.

  • استک کامل پروداکشن (Docker Compose، مایگریشن‌ها و اپ standalone) به‌صورت واقعی روی یک ماشین مجازی اوبونتو ۲۶.۰۴ تست شده است: هر پنج مایگریشن روی یک دیتابیس واقعاً خالی اجرا شد و یک چرخه‌ی کامل درخواست و تأیید کد یک‌بارمصرف با موفقیت انجام شد.

  • تصمیم‌های معماری که بازگرداندنشان گران است، در قالب ADR در docs/decisions/ ثبت می‌شوند — همراه با گزینه‌هایی که رد شده‌اند و دلیلش.

وضعیت فعلی: خط لوله‌ی استقرار به‌صورت کامل و سرتاسری تأیید شده، اما هنوز سروری با دسترسی عمومی راه‌اندازی نشده است؛ بنابراین نسخه‌ی زنده‌ای برای نمایش وجود ندارد. کد پروژه به‌صورت متن‌باز در دسترس است: github.com/Nikosonz/lifeos

تکنولوژی‌ها

  • زبان و قرارداد: TypeScript، Zod

  • بک‌اند: Next.js 16 (App Router)، Prisma، PostgreSQL، Redis، BullMQ

  • رابط کاربری: React، Tailwind CSS v4، shadcn/ui، TanStack Query

  • موبایل: Flutter (اندروید)

  • زیرساخت: Docker، Docker Compose، GitHub Actions

مال تو — پلتفرم مدیریت زندگی | پویا کریمی