تطبيق تجريبي واحد زائد واحد لتطوير البرمجيات الشعار

كيف نبني تطبيقًا جديدًا انطلاقًا من القالب

صفحة الإرشادات المرجعية — للبشر ولـ‏Claude. ‏DemoAppCore هو الشيفرة المصدرية للمنهجية: كل تطبيق جديد في واحد زائد واحد يبدأ كنسخة منه.

1 · البداية

  • ننسخ بنية الحل: ‏DataAccessLayer و‏BusinessLogicLayer و‏UI وتطبيق الويب (المبني على DemoApp).
  • تُنسخ طبقتا ‏DAL و‏UI نسخة طبق الأصل — فهما المرجع الذي لا يجوز تعديله لكل مشروع على حدة. إصلاح عام؟ يبدأ هنا في القالب.
  • اسم المشروع و‏namespace والشعار والعنوان — تُستبدل في التطبيق وحده.
  • منفذ تطوير فريد لكل تطبيق (‏launchSettings) — لا تكرّر المنافذ بين المشاريع.
  • تتوفّر مهارة آلية لذلك: ‏new-app-from-demoappcore.

2 · كيان جديد (BLL)

public class Invoice : Record
{
    [Column(Size = 300)]
    public override string Description { get; set; }
    [Column] public double Amount { get; set; }
    [Column] public DateTime Issued { get; set; }
    [Column] public bool IsPaid { get; set; }
}
  • يُنشأ الجدول ويُحدَّث تلقائيًا داخل SetupAsync — بلا كتابة SQL وبلا عمليات ترحيل.
  • أسماء الجداول بصيغة المفرد. ‏DateTime.MinValue = لا يوجد تاريخ.
  • كيان ليس جدولًا حقيقيًا (للعرض أو للتجربة): ‏[Table(Ignore = true)].
  • البيانات الأولية: تجاوز الدالة CreateAsync في الكيان (كما في Settings).

3 · شاشة إدارة

// DemoApp/Tables/InvoicesTable.cs
public class InvoicesTable : TableMakerEx<Invoice>
{
    public InvoicesTable()
    {
        this["Description"].HeaderText = "الوصف";
        this["Amount"].HeaderText = "المبلغ";
        this["IsPaid"].HeaderText = "مدفوعة";
        this["IsPaid"].Filterable = true;
    }
}

// Pages/Invoices.html
<h1>الفواتير</h1>
<div id="InvoicesTable" class="table"></div>

// Code/App.cs
public ReturnDetails Invoices() => AdminPage("Invoices");

// Pages/Main.html — زر في القائمة
<input type="button" id="Invoices" value="الفواتير" />

هذه شاشة كاملة: جدول وفرز وتصفية ونموذج وتصدير. بلا JS وبلا SQL.

4 · صفحات ليست جداول

  • الصفحة = ملف HTML داخل wwwroot/Pages + دالة في App تُعيد ReturnDetails.
  • الزر يستدعي الدالة بحسب قيمة id الخاصة به — بلا onclick وبلا نقطة نهاية جديدة.
  • تصل معاملات الصفحة عبر Data (قاموس)؛ ويستطيع ردّ الخادم أن يضخّ html أو ‏popUp أو ‏script أو أن يملأ القوائم.
  • صفحات Pages/ محجوبة عن الوصول المباشر من المتصفح — ولا تُقدَّم إلا عبر ButtonClicked.
  • حالة التطبيق (خصائص App) تُحفظ بين الطلبات — مشفّرة ومضغوطة لدى العميل.

5 · المحتوى و‏SEO وتعدّد اللغات

  • صفحة المحتوى = سجلّ (ContentPage) وليست ملفًا: عنوان صديق، و‏H1، و‏title منفصل، ووصف، وصورة مشاركة، وبيانات منظَّمة. تُحرَّر في شاشة "صفحات المحتوى".
  • تصيير من جانب الخادم لكل صفحة عامة (Code/Seo.cs): تتضمّن الاستجابة الأولى المحتوى و<head> كاملًا. أما واجهة الإدارة فتبقى SPA وتحصل على noindex.
  • شاشة جديدة يُراد فهرستها: أضِفها إلى Seo.PublicMethods وامنحها PageMeta داخل PageMeta.Screens. أما شاشة الإدارة فإلى AdminMethods.
  • البيانات الوصفية، محفوظة كانت أم محسوبة، تمرّ عبر واجهة واحدة — IPageMeta. والصفحة المولَّدة ديناميكيًا تبني PageMeta.For("/…").Titled(…) في زمن التشغيل.
  • كل تغيير في العنوان يستوجب سطرًا في "التحويلات" (PageRedirect)، وإلا انكسر كل رابط خارجي بصمت. ويبقى العنوان الرقمي القديم (/Page@41) قابلًا للتحويل إلى الأبد.
  • sitemap.xml وrobots.txt يُبنيان وحدهما من البيانات؛ ونصوص الواجهة تُترجَم عبر رموز ({نص}Word)، أما النصوص الطويلة فتُكتب كسجلّ لكل لغة.
  • ‏slug بالإنجليزية دائمًا، بأحرف صغيرة وشرطات. لغة النظام الافتراضية على الجذر، وبقية اللغات تحت /en/؛ وتُشتقّ وسوم hreflang وحدها من Identify المشترك.
  • في بيئة الإنتاج: املأ SiteBaseUrl في الإعدادات — فالعنوان الأساسي وخريطة الموقع يعتمدان عليه.

6 · قواعد كتابة كود مُلزِمة

  • reuse-first: قبل أي تطوير، تحقّق ممّا هو موجود بالفعل في Util و‏DAL و‏UI.
  • غير متزامن فقط: لا استدعاءات متزامنة لقاعدة البيانات؛ و‏async يمتدّ حتى وحدة التحكّم.
  • تحديث موجَّه:UpdatePropertiesAsync("Col") بدلًا من حفظ كامل.
  • التنسيق في CSS وحده، والمقاسات بوحدة rem؛ وأي تغيير في CSS/JS ⇐ رفع قيمة ?v=.
  • ‏Settings في قاعدة البيانات، لا في appsettings؛ وقاعدة بيانات التطوير = localhost/SQLite.
  • الحقول غير العربية (البريد الإلكتروني، الهاتف) — ‏LTR.
  • مهام الخلفية يجب أن تكون قابلة للاستئناف (resumable).

7 · قبل الإنهاء

  • ‏build نظيف — بلا تحذيرات مفتوحة.
  • ‏code-review على الـ‏diff + رأي ثانٍ (Gemini).
  • اختبار دخان حقيقي في المتصفح — المسار الكامل، لا مجرّد نجاح البناء.
  • ‏commit إلى SVN برسالة واضحة؛ وملفات ‏.md تُضاف هي أيضًا.
  • النشر: مجلد محمول (self-contained)؛ وإلى بيئة الإنتاج بموافقة صريحة فقط.