Developer Page Specifications
Data Model
12 tables — Founder core, FounderLang, FounderStartup join with role+dates, FounderEventRole, etc.
Complete
Database tables for Founder Profiles. Largest cross-module surface — needs fast reverse-lookups from EcosystemEntityLinks. 12 tables: Founder core + FounderLang (i18n) + 4 lookups + 4 child detail tables + 2 cross-module joins.
Table 1 · Founder (core)
- Id (PK, uuid, required)
- Stable primary key.
- Slug (varchar(120), unique, required)
- URL identifier. Kebab-case. e.g. "ahmed-hassan".
- Flavor (varchar(20), required)
- Values: editorial | founder-led. Drives ownership rules + edit affordances.
- OwnerUserId (FK → User, nullable)
- Set only when Flavor=founder-led. Drives "Edit profile" CTA visibility on details page.
- CountryCode (varchar(2), required)
- ISO 3166-1 alpha-2. Anchor country (founder may be active across MENA but is anchored to one home country).
- PrimaryRole (varchar(20), required)
- Values: ceo | cto | cofounder | founder | operator. Lookup-table-backed.
- AvatarUrl (varchar(500), nullable)
- Square photo, ≥400×400, jpeg/webp/avif. Falls back to generated SVG when null.
- LinkedInUrl, TwitterUrl, PersonalSiteUrl (varchar(500), nullable)
- External social profile URLs. Required for IsVerified=true gates.
- IsVerified (bool, required, default false)
- Editorial verification flag (real photo + ≥1 published startup + LinkedIn confirmed). Drives the green ✓.
- IsActive (bool, required, default true)
- Soft-delete. IsActive=false hides from public queries, preserves the record + cross-module mentions.
- IsFeatured (bool, default false)
- Editorial spotlight flag. Surfaces on homepage rail + bumps in default sort.
- PublishedAt (timestamptz, nullable)
- Drives Newest sort + JSON-LD datePublished.
- CreatedAt, UpdatedAt (timestamptz, required)
- Audit columns.
Table 2 · FounderLang (i18n)
- Composite PK: (FounderId, Lang). Lang ∈ {'en', 'ar'}.
- Fields: DisplayName (varchar(120), required), Headline (varchar(160), required), Bio (text, required), MetaTitle (varchar(80), nullable), MetaDescription (varchar(200), nullable).
- Both EN and AR rows must exist with DisplayName + Headline + Bio populated before IsActive can be true.
Child detail tables
- FounderSkills (join: FounderId ↔ SkillCode)
- SkillCode is free editorial taxonomy (e.g. fundraising, growth, product, b2b-sales, ops).
- FounderLanguages (join: FounderId ↔ LangCode)
- ISO 639-1 codes. Display on bio section.
- FounderStartup (bidirectional join)
- FounderId ↔ StartupId, Role (varchar(60)), StartedYear (int), EndedYear (int, nullable). One row per founder-startup association.
- FounderEventRole (FounderId ↔ EventId, Role)
- Role values: speaker | judge | panelist | mentor | attendee. Optional join — when present, drives the role chip on the Speaking history section. When absent, just shows the event card without role overlay.
- FounderRelatedFounder (manual related)
- FounderId ↔ RelatedFounderId, DisplayOrder. Editor-curated relationships.
