تخطَّ إلى المحتوى الرئيسي

Developer Page Specifications

Data Model

16 tables backing the module — Opportunity core, *Lang i18n, child detail tables.

مكتمل

الجداول التي تَدعم موديول Opportunity Radar. 16 جدول إجمالاً: 1 سجل أساسي، 1 رفيق i18n، 1 منظِّم، 5 lookup/taxonomy، 5 جداول تفاصيل فرعية، 2 مساعدات cross-module، 1 اشتراك، 1 سجل أحداث تحليلات. كل حقل bilingual يَستخدم جدول رفيق *Lang؛ أبداً لا تُخَزِّن EN + AR في نفس الصف.

الجدول 1 · Opportunity (الأساسي)

Id (PK, uuid, مطلوب)
مفتاح أساسي مستقر. لا يُكشَف لـ URLs أبداً (استخدم Slug).
Slug
مُعَرِّف URL. kebab-case ASCII. يُستخدم في المسار /:lang/opportunity-radar/{slug}.
TypeId
نوع واحد لكل فرصة.
OrganizerId
منظِّم قياسي واحد؛ المنظِّمون المُشاركون (لو وُجدوا) يَعيشون في جدول join OpportunityCoOrganizer منفصل.
CountryId
ارتساء الدولة الأساسية. أهلية متعدّدة-الدول مُتَتَبَّعة منفصلة عبر join OpportunityCountry.
Status
القيم: Open / ClosingSoon / Rolling / Closed. بعض الحالات محتسبة (انظر صفحة Status Logic) لكن مُحفوظة ليلياً للفلترة السريعة.
IsRolling
حين true، DeadlineDate يُتجاهَل؛ الفرصة تَقبل التقديمات باستمرار.
IsSponsored
علم الترويج التجاري. يَقود شارة "SPONSORED" + شريط إفصاح الراعي عند الضبط.
IsVerified
بوّابة التحقّق التحريري. يَقود شارة ✓ الخضراء.
IsActive
علم soft-delete. IsActive=false يُخفي الصف من كل الاستعلامات العامة لكن يَحفظ السجل + مراجع cross-module.
DeadlineDate
ISO 8601 مع منطقة زمنية. null فقط حين IsRolling=true. يُستخدم لاحتساب الحالة.
OfficialUrl
URL قياسي للتقديم من المنظِّم. مطلوب حين Status ∈ { Open، ClosingSoon، Rolling }.
ValueSignal
عبارة قصيرة bilingual تُلخِّص ما تُقَدِّمه الفرصة — "Up to $100K equity-free" / "Mentorship + workspace". مُخَزَّن على Opportunity نفسه (ليس Lang) حين غير-متمحوِر-بالمحلّية.
TimeRequired
تقدير نصّ-حرّ. "15 minutes" / "2 hours" / "1 day". يَقود قسم D.
DisplayOrder
ترتيب تحريري. الأرقام الأقل تَبرز أعلى في القوائم غير المفروزة.
EditorialPriority
standard / featured / spotlight. يُرآة §9.3 OpportunityRadar editorialPriority. الافتراضي: standard.
PublishedAt
يُضبط حين السجل يَدخل IsActive=true لأول مرة. يَقود فرز "Newest" + JSON-LD datePublished.
LastVerifiedAt
يُحَدَّث من التحرير أثناء إعادة التحقّق. يَقود ملاحظة "Last verified N days ago".
VerifiedByUserId
المستخدم الذي قام بآخر تحقّق.
CreatedAt / UpdatedAt
أعمدة تدقيق قياسية.

الجدول 2 · OpportunityLang (رفيق i18n)

  • PK مُرَكَّب: (OpportunityId, Lang). Lang ∈ {'en', 'ar'}.
  • الحقول: Title (varchar(200)، مطلوب) · ShortDescription (varchar(220)، مطلوب، ≤200 عملياً) · FullDescription (text، مطلوب) · ProgramStructure (text، nullable) · WhyItMatters (text، nullable) · FounderProfile (text، nullable) · MinimumRequirements (text، nullable) · ApplicationRequirements (text، nullable) · BestForStages (text، nullable).
  • مطلوب: على الأقل صف (en) + صف (ar) يجب أن يَوجدا مع Title، ShortDescription، FullDescription معبَّأين. الحقول الأخرى nullable فردياً.

الجداول 3-7 · Lookup / taxonomy

OpportunityType
Id، Slug (مثلاً 'accelerator')، DisplayOrder. رفيق NameLang. القيم المُعَبَّأة: accelerator · incubator · grant · competition · fellowship · soft-landing · residency · vc-program.
OpportunityStatus
مرجع شبه-enum. مُعَبَّأ: Open · ClosingSoon · Rolling · Closed. الكود مسموح يَستخدم سلسلة حرفية خام — الجدول لبحث UI admin.
Country
مُشترك مع موديولات calendar / coverage. Id، Code (ISO 3166-1 alpha-2)، Region (GCC / Levant / North Africa). رفيق NameLang.
OpportunityStage (join: OpportunityId ↔ StageCode)
كثير-إلى-كثير. قيم StageCode: idea، pre-seed، seed، series-a، growth، sme، scaleup.
OpportunitySector (join: OpportunityId ↔ SectorCode)
كثير-إلى-كثير. SectorCode هو taxonomy تحريرية حرّة: fintech، healthtech، edtech، climatetech، deeptech، agritech، إلخ.

الجدول 8 · Organizer

  • Id، Name (varchar(200))، Type (Accelerator / Incubator / VC / Corporate / Government / University / Community / Media / Other)، CountryCode، LogoUrl، WebsiteUrl، IsVerified.
  • رفيق OrganizerLang: DescriptionLang (text، nullable).

الجداول 9-13 · جداول التفاصيل الفرعية

OpportunityBenefit
Id، OpportunityId، Type (funding / mentorship / investor-access / workspace / corporate-pilots / legal-support / cloud-credits / network-access)، IconKey، DisplayOrder. رفيق Lang: TitleLang + DescriptionLang.
OpportunityEligibilityCriteria
Id، OpportunityId، IsRequired (bool)، DisplayOrder. رفيق Lang: TitleLang + NotesLang.
OpportunityApplicationRequirements
صف واحد لكل فرصة. RequiredDocs (text[])، OptionalDocs (text[])، PitchDeckRequired (bool)، FounderProfileRequired (bool)، ProductDemoRequired (bool)، FormUrl (varchar(500)، nullable).
OpportunityTimeline
Id، OpportunityId، Date (timestamptz)، Status (past / current / upcoming — محتسبة وقت الرسم، غير مُخَزَّنة)، DisplayOrder. رفيق Lang: LabelLang + DescriptionLang.
OpportunityCountry (join، أهلية متعدّدة-الدول)
OpportunityId ↔ CountryCode. متمايز عن Opportunity.CountryId (دولة الارتساء)؛ الـ join يَلتقط القائمة الكاملة للأهلية حين تَمتدّ الفرصة عبر عدة دول.

الجداول 14-16 · Cross-module + admin

OpportunityRelatedOpportunity (روابط related يدوية)
OpportunityId ↔ RelatedOpportunityId، DisplayOrder. علاقات صريحة منَسَّقة-من-المحرّر.
EcosystemEntityLinks (نسيج cross-module)
جدول مشترك واحد عبر المنصّة. الحقول: Id، EntityType ('opportunity' | 'founder' | 'startup' | 'editorial' | 'event' | 'coverage' | 'founder-file')، EntityId، RelatedEntityType، RelatedEntityId، RelationType، ReasonLang (جدول رفيق)، DisplayOrder.
OpportunitySubscription
Id، Email، CountryPreference (nullable)، StagePreference (nullable)، ConsentPlatform (bool، مطلوب true)، ConsentPartners (bool، افتراضي false)، Source ('listing' | 'details')، OpportunityIdContext (FK nullable، مضبوط حين source=details)، CreatedAt.