Control Panel Specifications
Lead Capture (Download Modal)
Visitor-side gated download modal. The 5 lead fields + 2 consent checkboxes. DownloadLead schema (legal 7-year retention) + auto-captured UTM / language / source.
When a visitor clicks the Download CTA on a gated Founder File, this modal opens and collects the data the platform needs to (a) email them the PDF, (b) qualify the lead for CRM, and (c) honour consent for marketing + sponsor sharing. Every field below produces a column on the `DownloadLead` row that gets created on submit.
Visitor-facing fields (lead capture)
Full name
- Purpose — Personalise the delivery email and the CRM record. Used as the `To:` name when the PDF is emailed and as the display name in lead lists.
- DB type — `DownloadLead.FullName` · NVARCHAR(120) NOT NULL · 2–120 chars.
- Validation — Trimmed, non-empty, no URLs (spam guard: reject if matches `/https?:\/\//`). QC tests: enter 1 char → reject; paste a URL → reject; enter " John Doe " → trim + accept as "John Doe".
Email address
- Purpose — Single most important field — used to deliver the PDF and to dedupe leads across files. Also the primary key for newsletter subscription downstream.
- DB type — `DownloadLead.Email` · NVARCHAR(254) NOT NULL · indexed for dedupe queries · RFC 5321 max length.
- Validation — Regex `^[^\s@]+@[^\s@]+\.[^\s@]+$` · lowercased on save · MX-record check on the domain (async, non-blocking). Disposable-email domains rejected via a blocklist refreshed weekly. QC tests: `test@test` → reject (no TLD); `john@10minutemail.com` → reject (disposable list).
Country
- Purpose — Geographic segmentation for editorial + sponsor reports. Drives the GEO meta when this lead later visits a profile page (analytics enrichment).
- DB type — `DownloadLead.Country` · CHAR(2) NOT NULL · ISO-3166-1 alpha-2.
- Validation — Single-select dropdown sourced from a static `Country` list (~250 entries). Default selection = inferred from IP via the request CDN header `cf-ipcountry` / `x-vercel-ip-country` (visitor can override). QC test: open modal from a Cairo IP → "Egypt" pre-selected; can switch to any other country.
Role
- Purpose — Lead qualification — distinguishes a founder from an investor from a student. Drives the segmented onboarding the lead receives after download.
- DB type — `DownloadLead.Role` · NVARCHAR(30) NOT NULL · CHECK Role IN ('founder','team-member','investor','accelerator','corporate','student','consultant','other').
- Validation — Single-select dropdown. Required. QC test: leave default placeholder → submit fails with "Role is required".
Primary interest
- Purpose — Why the visitor is on the platform. Drives the cross-module recommendation engine — picking "Founder Profile" routes them into the create-profile funnel after download.
- DB type — `DownloadLead.PrimaryInterest` · NVARCHAR(30) NOT NULL · CHECK PrimaryInterest IN ('reading-files','founder-profile','startup-showcase','sponsorship','opportunities','other').
- Validation — Single-select dropdown. Required. QC test: each option triggers a different post-download CTA on the thank-you screen.
Consent checkboxes (legal)
Newsletter consent
- Purpose — Explicit opt-in for receiving StartupHub.today founder resources + opportunities by email. GDPR / Egyptian Data Protection Law requires this to be UNCHECKED by default.
- DB type — `DownloadLead.ConsentNewsletter` · BIT NOT NULL · DEFAULT 0 (false).
- Validation — Optional (download succeeds either way). When 1, lead joins the newsletter list and an unsubscribe token is generated. QC test: submit unchecked → lead receives ONLY the PDF email, no marketing emails. Submit checked → lead receives PDF email + the first newsletter onboarding sequence.
Sponsor consent (conditional)
- Purpose — When the file has a sponsor, this checkbox controls whether the lead is shared with that sponsor. The sponsor block above the checkboxes shows WHO the sponsor is so the visitor makes an informed choice.
- DB type — `DownloadLead.ConsentSponsor` · BIT NOT NULL · DEFAULT 0 (false). NULL is NOT allowed even when the file is unsponsored — stored as 0 in that case for consistency.
- Validation — Checkbox only RENDERED when `FounderFile.sponsorId IS NOT NULL`. Optional. When 1, the lead row is pushed to the sponsor's CRM webhook within 5 minutes. QC tests: download an unsponsored file → checkbox absent + ConsentSponsor=0; download a sponsored file with checkbox unticked → ConsentSponsor=0 + no webhook fired; download sponsored with checkbox ticked → ConsentSponsor=1 + sponsor webhook called.
Auto-captured fields (no visitor input)
- founderFileId
- UUID FK to FounderFile. Filled from the modal context (which file the visitor clicked). NOT editable.
- language
- CHAR(2) — the locale the visitor was browsing in (`en` / `ar` / `fr`). Drives which PDF gets emailed.
- source
- NVARCHAR(20) · CHECK source IN ('listing','details','reader','direct'). Which surface the visitor clicked Download from. Listing = the spotlight CTA on /founder-files; Details = the details page CTA; Direct = arrived via deep link with `?download=1` (CRM campaigns).
- utmSource / utmMedium / utmCampaign?
- NVARCHAR(80) NULL each. Captured from the URL query string at modal open. Used by marketing attribution.
- downloadedAt
- DATETIME2 NOT NULL · GETUTCDATE() on insert.
- deliveredAt?
- DATETIME2 NULL · stamped when the email-with-PDF actually sends (SendGrid / SES webhook). NULL until delivery succeeds.
- pdfVersionDelivered
- TINYINT NOT NULL · which `vN.pdf` the lead received. Captured at delivery time. Lets the audit trail reproduce exactly what bytes the lead got.
Phase-2 optional fields
These exist on the model but the Phase-1 modal does NOT collect them. Phase-2 progressive profiling will reveal them gradually based on Role (e.g. "Founder" → shows companyName + startupStage on second download).
- companyName?
- NVARCHAR(120) NULL.
- linkedinUrl?
- NVARCHAR(500) NULL · regex check.
- startupStage?
- NVARCHAR(30) NULL · enum (pre-seed/seed/series-a/…).
- industry?
- NVARCHAR(60) NULL · shared with Articles industry taxonomy.
- websiteUrl?
- NVARCHAR(500) NULL.
Form preview — Download modal (sponsored file)
This is the exact modal a visitor sees when clicking Download on a gated, sponsored Founder File. Showing the sponsored variant because it includes BOTH consent checkboxes — the unsponsored variant just hides the sponsor consent row.
