Skip to content

Organisations

The organisations domain tracks the companies and institutions behind every drug in the knowledge graph — pharmaceutical companies, biotechs, CROs, academic institutions, government agencies, investors, and diagnostics firms. Drug ownership is not static: it changes hands through mergers, acquisitions, licensing deals, and partnerships. This domain captures both the current state and the full history of those relationships.

erDiagram
    organisations ||--o{ deal_participants : "participates in"
    organisations ||--o{ drug_ownerships : "owns"
    organisations |o--o| organisations : "subsidiary_of"
    deals ||--o{ deal_participants : "involves"
    deals ||--o{ deal_drugs : "includes"
    deal_drugs }o--|| drugs : "references"
    drug_ownerships }o--|| drugs : "owned drug"

Company profiles with classification and financial data. One row per entity.

ColumnPurpose
bloupe_idStable Bioloupe identifier for the organisation
nameCanonical organisation name
synonymsJSON array of alternative names, abbreviations, former names
organisation_typepharma_biotech, academic, government, investor, diagnostic, cro
size_categoryMarket cap tier: large_cap, mid_cap, small_cap, micro_cap, nano_cap
ownership_statuspublic, private, subsidiary, government, non_profit
activeWhether the organisation is currently active
subsidiary_of_idSelf-referential FK to parent company
headquartersISO 3166-1 alpha-2 country code
stock_symbol / stock_exchangePrimary stock listing
market_capMarket capitalization in the currency column
revenue_ttmTrailing twelve months revenue
enterprise_valueMarket cap + debt - cash
total_cash_mrqCash and equivalents, most recent quarter
cash_runway_monthsEstimated months of runway at current burn rate (pre-revenue biotechs)
profit_marginNet profit margin as decimal (TTM)

Indexed on organisation_type, headquarters, subsidiary_of_id, and name.

M&A, licensing, co-development, distribution, and other business agreements between organisations. Tracks financial terms and geographic scope.

ColumnPurpose
deal_typemerger, acquisition, asset_acquisition, license, co_development, distribution, manufacturing, collaboration, option, spin_off
announced_dateWhen the deal was publicly announced
closed_dateWhen the deal completed (NULL if pending)
statusannounced, completed, terminated
total_valueTotal deal value (upfront + milestones + equity)
upfront_paymentCash upfront amount
milestone_paymentTotal potential milestone payments
equity_valueEquity component value
royaltiesRoyalty terms description
equity_percentageStake percentage acquired (0-100)
currencyISO 4217 currency code, defaults to USD
geography_include / geography_excludeJSON arrays scoping the deal territory
therapeutic_areasJSON array of relevant therapeutic areas

Check constraint enforces closed_date >= announced_date. Indexed on deal_type and announced_date.

Bridge table linking organisations to deals with their role. Each deal has at least two participants.

ColumnPurpose
deal_idFK to deals (cascade on delete)
organisation_idFK to organisations (restrict on delete)
roleacquirer, target, licensor, licensee, collaborator, merger_partner, co_developer, distributor, initiator

Unique constraint on (deal_id, organisation_id, role) — the same organisation can hold multiple roles in a single deal (rare but valid).

Links drugs to deals — which drug assets are part of a transaction.

ColumnPurpose
deal_idFK to deals (cascade on delete)
drug_idFK to drugs (cascade on delete)

Unique constraint on (deal_id, drug_id).

Current and historical ownership records mapping drugs to owning organisations. Supports multi-party ownership with geographic scoping. Cross-references the drugs domain.

ColumnPurpose
drug_idFK to drugs (cascade on delete)
organisation_idFK to organisations (restrict on delete)
is_currenttrue for active ownership, false for historical
deal_typeHow ownership was obtained: originator, acquisition, license, co_development, collaboration, spin_off
geography_include / geography_excludeJSON arrays of ISO country codes or regions
started_atWhen ownership began
ended_atWhen ownership ended (NULL if current)

Check constraints enforce ended_at >= started_at and that is_current = true only when ended_at IS NULL. Composite index on (drug_id, is_current) optimizes the most common query pattern: “who owns this drug right now?”

deal_participants bridge instead of fixed acquirer/target columns. Real-world deals frequently involve more than two parties. A three-way licensing agreement between a biotech, a regional distributor, and a co-development partner cannot fit into a two-column model. The bridge table with a role enum handles any number of participants. The unique constraint on (deal_id, organisation_id, role) prevents duplicates while allowing the same organisation to hold multiple roles.

drug_ownerships.is_current flag with check constraint. Ownership history is preserved indefinitely — rows are never deleted, only marked is_current = false with an ended_at timestamp. The check constraint (is_current = true AND ended_at IS NULL) OR is_current = false makes it impossible to have a “current” ownership with an end date. The composite index on (drug_id, is_current) means finding current owners never requires scanning historical rows.

organisation.subsidiary_of_id self-reference. Corporate hierarchy is modelled as a simple parent pointer rather than a full adjacency list or nested set. This is sufficient because the hierarchy is shallow (rarely more than 2-3 levels) and changes infrequently. Queries that need the full tree can use recursive CTEs.

restrict delete rule on organisation_id FKs. Organisations cannot be deleted if they participate in deals or own drugs. This prevents orphaned business records and forces explicit data cleanup before removal.

Two materialized views consume organisation data to power downstream queries.

mv_competitive_landscape — Drug-by-disease-by-phase matrix with owner info. Uses a LATERAL subquery to aggregate current_owner_names into an array, avoiding row duplication when a drug has multiple current owners. One row per (drug_id, disease_id).

mv_drug_pipeline — Pre-joined drug overview for zero-JOIN agent queries. Includes current_owner_names as an aggregated array from drug_ownerships joined to organisations. Also carries target names, technology, and highest development phase. One row per drug.

Both views use the same LATERAL + array_agg(DISTINCT ...) pattern to safely handle multi-owner drugs without breaking unique indexes.

Find all current owners of a drug by name:

SELECT o.name, o.organisation_type, dow.deal_type, dow.geography_include
FROM drug_ownerships dow
JOIN organisations o ON o.id = dow.organisation_id
JOIN drugs d ON d.id = dow.drug_id
WHERE d.name = 'sotorasib'
AND dow.is_current = true
ORDER BY o.name;

Top 10 deals by total value in the last year:

SELECT
d.deal_type,
d.total_value,
d.currency,
d.announced_date,
array_agg(o.name || ' (' || dp.role || ')') AS participants
FROM deals d
JOIN deal_participants dp ON dp.deal_id = d.id
JOIN organisations o ON o.id = dp.organisation_id
WHERE d.announced_date >= NOW() - INTERVAL '1 year'
AND d.total_value IS NOT NULL
GROUP BY d.id, d.deal_type, d.total_value, d.currency, d.announced_date
ORDER BY d.total_value DESC
LIMIT 10;

Ownership history for a drug, including which deals transferred it:

SELECT
o.name AS owner,
dow.deal_type,
dow.started_at,
dow.ended_at,
dow.is_current,
dow.geography_include
FROM drug_ownerships dow
JOIN organisations o ON o.id = dow.organisation_id
JOIN drugs d ON d.id = dow.drug_id
WHERE d.name = 'pembrolizumab'
ORDER BY dow.started_at NULLS FIRST;