Data Monetization, Clinical Trial Matching, Consent Lifecycle — The B2C Side of Moonlitic
The Moonlitic platform has two revenue surfaces. The Marketplace (Folder 07) sells de-identified cohort data to B2B Tile Builders at $XXX,XXX/year. But where does that data come from? From patients who consented in Folder 01.
This portal is the patient's window into the value their data creates. It answers three questions every consented patient eventually asks:
Decision: The Patient/Consumer is added as a new role in the existing Marketplace Portal — NOT a separate application.
Rationale: A login is a login. The AuthEngine validates credentials, issues a JWT, and determines role. What changes after login is which tabs are visible and what actions are available. Duplicating auth layers creates security drift.
| Concern | B2B (Tile Companies, Approvers, Finance, Admin) | B2C (Patient/Consumer) | Implementation |
|---|---|---|---|
| Login mechanism | Email + password + MFA | Email + password + MFA | Same AuthEngine.login() |
| Identity verification | Company EIN + compliance screening | Clear IAL2 (biometric + gov ID) | Pre-auth: Clear is done in Folder 01 before they ever reach the portal |
| MFA requirement | Mandatory (TOTP) | Optional (encouraged) | Same engine, mfaRequired flag per role |
| Password policy | 12+ chars (enterprise) | 8+ chars (consumer-friendly) | Same engine, minLength per role |
| Session lifetime | 1 hour | 4 hours | Same JWT, expiry per role |
| Post-login tabs | Revenue, Onboard, Approval, Billing, Dashboard, ACL | My Data, Clinical Trials, Earnings | Same getEnabledTabs(role) |
| Data access direction | Queries warehouse (outbound) | Views own data + earnings (inbound) | Different engines behind the tabs |
Result: Zero duplicated auth logic. One security surface to audit. One place to patch.
With the Patient/Consumer addition, the Moonlitic platform now has 11 distinct actor types (Clinician is parked for future). Here is the complete roster:
| # | Actor | Type | Role Code | Portal Tabs | Primary Action |
|---|---|---|---|---|---|
| 1 | Patient / Consumer | External, B2C | PATIENT | My Data, Trials, Earnings | View data value, match trials, earn income |
| 2 | New Registrant | External, B2B | NEW_REGISTRANT | Onboard | Fill wizard, submit application |
| 3 | Tile Company (any type) | External, B2B | TILE_COMPANY | Onboard, Approval, Billing, Dashboard, ACL | Query data, manage credits |
| 4 | Approver — Business | Internal | APPROVER_BUSINESS | Approval, ACL | Approve/reject (1st) |
| 5 | Approver — Functional | Internal | APPROVER_FUNCTIONAL | Approval, ACL | Approve/reject (2nd) |
| 6 | Approver — Sales | Internal | APPROVER_SALES | Approval, ACL | Approve/reject (3rd) |
| 7 | Approver — Technical | Internal | APPROVER_TECHNICAL | Approval, ACL | Approve/reject (4th) |
| 8 | Finance | Internal | FINANCE | Billing, ACL | Confirm wire payments |
| 9 | Admin | Internal | ADMIN | Revenue, Onboard, Approval, Billing, Dashboard, ACL | Monitor marketplace, reinstate tiles |
| 10 | Clinician | TBD | CLINICIAN | TBD | PARKED — Future |
Who: A real person who has already completed Folder 01 consent (Clear IAL2 verified, 12-category consent selection). They are NOT anonymous. Their identity has been biometrically verified.
Pre-requisite to reach this portal:
What they can see:
What they can do:
What they CANNOT do:
Who: An already-approved Tile Builder of type CLINICAL_TRIAL. They declared their research intent during onboarding (what conditions, what data categories, what cohort size they need).
What's NEW for them (added to existing Dashboard):
What they CANNOT do:
Key rule: The CRO sees numbers. The patient sees details. The system sits in between. The CRO never knows WHO until the patient says YES and the interaction moves off-platform.
| Step | Where | Actor | What Happens | System Output |
|---|---|---|---|---|
| 1. Identity | Folder 01 | Patient | Completes Clear NIST IAL2 verification: government ID scan, selfie liveness, biometric match. Age verified (18+ or guardian path). | moonliticUserId, ial2Verified=true, verifiedName, verifiedDob |
| 2. Consent | Folder 01 | Patient | Selects from 12 consent categories (3×4 grid). Sensitive categories (Mental Health, SUD, Genetic) get enhanced confirmation modals. | Immutable ACL consent record with aclTransactionId |
| 3. EHR Connect | Folder 02 | System | Aggregator API pulls patient's EHR data from connected providers. FHIR mapping applied. De-identification for warehouse. | aggregatorId + clinical profile (conditions, medications, demographics) |
| 4. Portal Login | This Portal | Patient | Logs into the unified portal with email + password (+ optional MFA). AuthEngine returns role=PATIENT. Patient tabs enabled. | JWT (4h expiry), patient dashboard rendered |
| 5. View Value | My Data tab | Patient | Sees their consented categories, how many marketplace queries have touched their cohort, estimated earnings per category based on demand. | Data value dashboard with per-category breakdown |
| 6. Accept/Decline | My Data tab | Patient | Toggles monetization ON or OFF per category. ON = their de-identified data is included in marketplace queries. OFF = excluded going forward (historical usage preserved). | ACL record: MONETIZATION_ACCEPTED or MONETIZATION_REVOKED per category |
| 7. Match Trials | Trials tab | Patient | Sees clinical trials that match their health profile. Each shows: condition, phase, compensation, location, CRO name. Patient can ACCEPT or DECLINE. | On ACCEPT: ACL record + notification to CRO (aggregate count updated). Off-platform interaction begins. |
| 8. Earn | Earnings tab | Patient | Views total earnings, monthly breakdown, payout history (via Folder F06_Payouts engine). Clinical trial payments tracked separately from marketplace data income. | Payout records via Velo Payments (Folder 03) |
A patient's data generates revenue when Tile Builders query the marketplace. The patient's share is calculated from:
| Variable | Source | Example |
|---|---|---|
| Categories consented | Folder 01 consent record | Claims, Clinical Outcomes, Rx, Demographics (4 of 12) |
| Marketplace demand | Folder 07 query history | Claims queried 342 times this month, Rx queried 187 times |
| Cohort inclusion | Entitlement + de-identification match | Patient's de-identified record was in 28 query cohorts this month |
| Revenue share % | Platform policy | Patient receives X% of marketplace revenue attributed to their cohort |
What the patient sees when they open the My Data tab:
| UI Element | Description |
|---|---|
| Consent Summary Card | Shows all 12 categories. Green = consented + monetizing. Gray = consented but not monetizing. Red = not consented. Each has an ON/OFF toggle. |
| Estimated Monthly Value | Dollar estimate based on current marketplace demand for their consented categories. Updates monthly. Not a guarantee. |
| Data Activity Feed | Anonymized log: "Your data was included in 12 aggregate queries this week across Claims and Demographics." No company names. No query details. |
| Provenance Trail | Immutable timeline: when they consented, when monetization was toggled, when revocations occurred. Sourced from ACL. |
| Per-Category Value | Bar chart: which categories generate the most value. Helps patient understand which consents matter most financially. |
| Action | Effect | Reversible? | ACL Entry |
|---|---|---|---|
| Accept (toggle ON) | Patient's de-identified data for this category is included in future marketplace queries | Yes, anytime | MONETIZATION_ACCEPTED { patientId, category, timestamp } |
| Revoke (toggle OFF) | Patient's data for this category is excluded from future queries. Historical query results that already included their data are NOT retroactively removed (immutability). | Yes, can re-accept later | MONETIZATION_REVOKED { patientId, category, timestamp, priorQueryCount } |
The matching engine sits between two actors who never directly see each other until the patient says YES:
| Side | Actor | What They Declared | What They See |
|---|---|---|---|
| Supply | Patient | Consent categories + EHR-derived health profile (conditions, medications, demographics) | List of matching trials with: condition, phase, compensation, CRO name, eligibility criteria |
| Demand | CRO (CLINICAL_TRIAL tile) | During onboarding: target conditions (ICD-10 codes), required demographics, study phase, compensation offered, cohort size needed | Aggregate count only: "142 consented patients match your criteria." NO individual identities. |
| # | From | To | Action | System Rule |
|---|---|---|---|---|
| 1 | CRO | System | Declares trial criteria during Tile onboarding (or via dedicated trial listing form) | Criteria stored: conditions, demographics, phase, compensation, cohort size |
| 2 | System | System | Matching engine runs: cross-references CRO criteria against consented patient profiles | Only patients with: (a) active consent for relevant categories, (b) monetization ON, (c) matching health profile |
| 3 | System | CRO | "Patient Matching" card on their Dashboard: "142 patients match. Request recruitment?" | CRO sees AGGREGATE COUNT ONLY. No names, no IDs, no profiles. |
| 4 | CRO | System | Clicks "Request Recruitment" — submits recruitment request | System validates: active tile, paid invoices, BAA executed. If pass → invitations queued. |
| 5 | System | Patient | Trial invitation appears in patient's "Clinical Trials" tab | Patient sees: condition, phase, compensation, CRO name, eligibility summary. NOT the CRO contacting them — the SYSTEM presenting an opportunity. |
| 6a | Patient | System | ACCEPT — patient agrees to participate | ACL: TRIAL_ACCEPTED { patientId, trialId, croTileId, compensation }. CRO's enrollment count increments. Off-platform handoff initiated. |
| 6b | Patient | System | DECLINE — patient says no | ACL: TRIAL_DECLINED { patientId, trialId }. CRO sees aggregate decline count (not who). Patient can change mind later if trial still active. |
| 7 | System | Both | On ACCEPT: system provides CRO with a secure handoff token (single-use) to initiate off-platform contact | All further interaction between patient and CRO happens OUTSIDE Moonlitic. Platform's role ends at consent + payment. |
| Scenario | Rule | Money Flow |
|---|---|---|
| Patient ACCEPTS trial | Compensation amount is locked. CRO pays Moonlitic. Moonlitic pays patient via Folder F06_Payouts. | CRO → Moonlitic → Patient (Velo Payments) |
| Patient backs out AFTER accepting + payment | Patient must repay the compensation. Moonlitic facilitates repayment. Until repaid, patient's trial participation status = WITHDRAWN_UNPAID. | Patient → Moonlitic → CRO (less processing fee) |
| Patient DECLINES | No financial obligation. No contact. Trial invitation disappears. | No money moves |
| CRO cancels trial | All pending invitations withdrawn. Accepted patients keep compensation earned to date. No clawback by CRO. | CRO absorbs sunk cost |
The patient can accept or decline monetization per category, at any time. They can accept or decline any clinical trial. There is no penalty for declining. There is no pressure to accept. Their data has value, and they choose what to do with it.
When a patient revokes consent or declines a trial, their record is not deleted. The ACL entry marking their original consent remains. The ACL entry marking their revocation is appended. The chain is immutable. This protects both the patient (proof they revoked) and the platform (proof consent existed when data was used).
Revoking monetization means "stop including my data in future queries." It does NOT mean "retroactively erase my data from past query results." Past results were generated under valid consent. Retroactive deletion would corrupt data provenance and violate Tile Builder trust. The timestamp in the ACL is the legal boundary.
Unlike data monetization (free to revoke), clinical trial participation has a financial lock. If a patient accepted a trial and received compensation, backing out requires repayment. This protects the CRO from patient churn after investment. Moonlitic mediates the repayment. Once repaid, the patient is free.
This is the first feature that spans all major folders. Here is exactly what depends on what:
| This Portal Needs | From | Folder | Specific Component | Data Exchanged |
|---|---|---|---|---|
| Patient identity (verified) | Folder 01 | First Party Consent | clear-backend.js → Clear PKCE flow | moonliticUserId, ial2Verified, verifiedName, verifiedDob |
| Consent categories selected | Folder 01 | First Party Consent | texas-health-consent.html → ACL consent record | 12-category selection array, aclTransactionId, enhancedConsentFlags |
| Patient health profile | Folder 02 | Clinical Intelligence | Aggregator API → FHIR mapping | aggregatorId, conditions (ICD-10), medications, demographics, lab results |
| De-identified warehouse presence | Folder 02 | Clinical Intelligence | De-identification engine (Safe Harbor / Expert Determination) | De-identified patient record in warehouse (no direct PHI) |
| Marketplace query activity | Folder 07 | Marketplace | DeliveryEngine query history | Aggregate query counts per category (how many queries touched this patient's cohort) |
| CRO trial criteria | Folder 07 | Marketplace | CLINICAL_TRIAL tile onboarding data | Target conditions, demographics, phase, compensation, cohort size |
| Revenue attribution | Folder 07 | Marketplace | BillingEngine + credit consumption | Per-query credit cost → revenue share calculation |
| Patient payouts | Folder 03 | Payouts | disbursement-engine.js + velo-client.js | Payout amount, disbursement status, Velo payment ID |
| Clinical trial payment processing | Folder 03 | Payouts | payout-orchestrator.js | Trial compensation amount, CRO source, patient destination, repayment tracking |
| Immutable audit trail | All Folders | Cross-cutting | ACL (Azure Confidential Ledger) | Every consent, revocation, monetization toggle, trial accept/decline, payout |
| Concern | B2B Approach (existing) | B2C Approach (new) | Rationale |
|---|---|---|---|
| Identity verification | Company EIN + compliance screening | Clear NIST IAL2 (biometric + gov ID) | Patients need higher identity assurance — they're real people, not companies |
| MFA | Mandatory TOTP | Optional (strongly encouraged) | Consumer adoption barrier — mandatory MFA kills conversion. Encourage, don't block. |
| Session lifetime | 1 hour | 4 hours | Consumers browse casually. Forcing re-login hourly is hostile UX. |
| Data visibility | Sees de-identified warehouse data | Sees ONLY their own data + anonymized activity | Patient never sees other patients. Never sees raw query details. Aggregate activity only. |
| Revocation rights | N/A (companies don't "revoke") | Per-category, per-trial, anytime | Patient autonomy is foundational. HIPAA right of access and control. |
| Data deletion requests | N/A | Denied — records are immutable | Explain clearly: data is never deleted, but consent can be revoked (forward-looking). Provenance integrity. |
| Minor protection | N/A (B2B) | Age verified at Clear step. <18 routed to guardian consent (COPPA). | Legal requirement |
| Financial data | Wire references (B2B) | Payout details (B2C via Velo) | Different payment rail. Patient sees earning history, not wire refs. |
The PATIENT role gets 3 tabs in the unified portal. Here's the detailed screen spec:
On every login, patients see a contextual "Welcome back" card above their My Data KPIs showing what changed since their last visit:
| Card | Content | Action |
|---|---|---|
| New Trial Matches | Count + condition names + max compensation for new trials matching their profile | Click → jumps to Trials tab |
| Pending Payouts | Dollar amount + count of payouts being processed via Velo | Click → jumps to Earnings tab |
| Last Payout | Amount, source (data vs trial), date, Velo reference | Informational |
| Query Activity | Number of new queries on their de-identified data since last login | Informational |
Implementation: renderPatientWelcome() injects a card into the #patientWelcomePanel div above My Data KPIs. Each card is clickable and navigates to the relevant tab. Shows last login timestamp.
| UI Component | Content | Data Source |
|---|---|---|
| KPI Row | Estimated Monthly Income | Categories Active | Total Queries on Your Cohort | Lifetime Earnings | Folder 07 query stats + Folder 03 payout totals |
| Category Cards (12) | Each category: name, status (Consented/Not), monetization toggle (ON/OFF), demand indicator (High/Med/Low), estimated value | Folder 01 consent record + Folder 07 demand data |
| Data Activity Feed | Scrollable timeline: "Your data was included in N queries this week" (anonymized, no company names) | Folder 07 query history (aggregated) |
| Provenance Trail | Immutable event log: consent given, monetization toggled, revocations, payouts | ACL (cross-folder) |
| Value Chart | Bar chart: monthly earnings by category | Folder 03 payout records |
| UI Component | Content | Data Source |
|---|---|---|
| Matching Trials List | Cards per matching trial: condition, phase (I/II/III/IV), compensation, CRO name, locations, eligibility summary | Matching engine (Folder 02 profile × Folder 07 CRO criteria) |
| Accept/Decline Buttons | Per-trial action. Accept shows confirmation with payment lock warning. Decline is silent. | ACL write on action |
| My Enrollments | Trials accepted: status (ENROLLED, ACTIVE, COMPLETED, WITHDRAWN), compensation received, dates | ACL + Folder 03 payout records |
| Withdrawal Flow | If enrolled: "Withdraw" button with repayment warning modal showing amount owed | ACL + Folder 03 repayment tracking |
| UI Component | Content | Data Source |
|---|---|---|
| Total Earnings KPI | Lifetime earnings, This Month, Pending Payout | Folder 03 disbursement-engine.js |
| Income Breakdown | Two streams: (1) Data Monetization income (marketplace queries), (2) Clinical Trial compensation. Separate totals. | Folder 03 + Folder 07 |
| Payout History | Table: date, amount, source (marketplace/trial), status (PAID/PENDING/PROCESSING), Velo reference | Folder 03 velo-client.js |
| Revocation History | Timeline of monetization revocations with financial impact: "Revoked Claims on March 15 — estimated $X/month reduction" | ACL + revenue attribution |
| Feature | Prototype State |
|---|---|
| PATIENT role in AuthEngine | Demo patient user with simulated consent record |
| My Data dashboard | 12 category cards with toggles, simulated demand/value data |
| Accept/Revoke monetization | Working toggles with ACL logging, provenance trail |
| Clinical trial matching | 3–5 simulated trials matched to demo patient's profile |
| Accept/Decline trial | Working with payment lock rules, withdrawal flow |
| Earnings dashboard | Simulated payout history for both income streams |
| CRO matching card | Aggregate match count on CLINICAL_TRIAL tile dashboard |
| Item | Priority | Production Requirement | Suggested Tech |
|---|---|---|---|
| Clear Integration | P0 | Real PKCE flow with Clear production endpoint. IAL2 verification. Session binding. | Folder 01 clear-backend.js (already built) |
| Aggregator EHR Connection | P0 | Real patient health profile from connected EHR providers. FHIR mapping. | Folder 02 Aggregator API integration |
| Revenue Attribution Engine | P0 | Calculate patient's share of marketplace revenue. Per-query attribution to cohort members. | New engine: maps Folder 07 query results to consented patient pool |
| Matching Engine | P0 | Cross-reference CRO criteria against patient profiles. Real-time or batch. | Azure Functions + Cosmos DB queries on de-identified profiles |
| Velo Payout Integration | P1 | Real money movement to patients. KYC, tax reporting (1099), disbursement. | Folder 03 velo-client.js + disbursement-engine.js (already built) |
| Secure Handoff (Trial Accept) | P1 | Single-use, time-limited token for CRO to initiate off-platform contact with accepted patient. | HMAC-signed token with 72h expiry + ACL tracking |
| Trial Repayment Flow | P1 | Patient repays compensation on withdrawal. Moonlitic mediates. CRO receives minus processing fee. | Folder 03 payout-orchestrator.js reverse flow |
| Guardian Consent (Minors) | P2 | COPPA-compliant guardian consent pathway for patients under 18. | Folder 01 clear-backend.js age check (already built) |
| Push Notifications | P2 | Notify patients of new matching trials, payout arrivals, revocation confirmations. | Azure Notification Hubs or Firebase |
Phase A (Weeks 1–3): Add PATIENT role to existing portal. Build My Data dashboard with consent card grid, monetization toggles, simulated value data, provenance trail. All ACL logging. Demo patient user.
Phase B (Weeks 4–6): Build Clinical Trial matching. Patient-side: trial cards, accept/decline, payment lock, withdrawal. CRO-side: matching count card on their existing dashboard, recruitment request. Matching engine with simulated profiles.
Phase C (Weeks 7–8): Build Earnings dashboard. Two income streams. Payout history (simulated Velo data). Revocation history with financial impact. Monthly breakdown charts.
Estimated prototype: 8 weeks. Builds on top of existing 3,005-line portal — no new file, no new auth layer.