<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: corpdigest</title>
    <description>The latest articles on DEV Community by corpdigest (@corpdigest).</description>
    <link>https://dev.to/corpdigest</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4064698%2Ff2577747-8acc-46b3-852b-b652e3547004.png</url>
      <title>DEV Community: corpdigest</title>
      <link>https://dev.to/corpdigest</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/corpdigest"/>
    <language>en</language>
    <item>
      <title>foundedYear Is the Wrong Field for Company Data</title>
      <dc:creator>corpdigest</dc:creator>
      <pubDate>Wed, 05 Aug 2026 18:48:46 +0000</pubDate>
      <link>https://dev.to/corpdigest/foundedyear-is-the-wrong-field-for-company-data-37n1</link>
      <guid>https://dev.to/corpdigest/foundedyear-is-the-wrong-field-for-company-data-37n1</guid>
      <description>&lt;p&gt;Almost every company dataset stores founding as a single integer. It is the first field you add and the first one that turns out to be a lie.&lt;/p&gt;

&lt;p&gt;Take Visa Inc. What year was it founded?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;1958, when Bank of America launched the BankAmericard programme&lt;/li&gt;
&lt;li&gt;The early 1970s, when the programme was reorganised into a member-owned network under Dee Hock&lt;/li&gt;
&lt;li&gt;1976, when it took the Visa name&lt;/li&gt;
&lt;li&gt;2007-2008, when Visa Inc. was incorporated as a stock corporation and went public&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All four are defensible. Your integer field forces you to pick one and silently discard the other three. Worse, whichever you pick becomes unfalsifiable downstream, because the reasoning is not stored anywhere.&lt;/p&gt;

&lt;h2&gt;
  
  
  Model entity events, not a founding year
&lt;/h2&gt;

&lt;p&gt;Keep the integer for display, but make it derived rather than authoritative. Store the events:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"slug"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"visa"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"displayFoundedYear"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1958&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"entityEvents"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"year"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1958&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"program_launch"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"note"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"BankAmericard"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"year"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1976&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"rename"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"note"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Visa"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"year"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2008&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ipo"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Three things get easier immediately. Conflicting sources stop being bugs and become different event types. "Companies founded before 1970" becomes a question you can answer precisely instead of approximately. And when someone challenges a date, you can show them why you chose it.&lt;/p&gt;

&lt;p&gt;The rendered version of that record, for reference: &lt;a href="https://corpdigest.com/company/visa" rel="noopener noreferrer"&gt;Visa company data&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Banks, insurers and anything that has been through a demutualisation will break the same way. If your schema has a single founding integer, pick your oldest company and try to defend the number. That exercise is the whole argument.&lt;/p&gt;

</description>
      <category>database</category>
      <category>api</category>
      <category>fintech</category>
    </item>
    <item>
      <title>Modelling Corporate Acquisition History as a Graph, Not a List</title>
      <dc:creator>corpdigest</dc:creator>
      <pubDate>Wed, 05 Aug 2026 17:59:41 +0000</pubDate>
      <link>https://dev.to/corpdigest/modelling-corporate-acquisition-history-as-a-graph-not-a-list-1clp</link>
      <guid>https://dev.to/corpdigest/modelling-corporate-acquisition-history-as-a-graph-not-a-list-1clp</guid>
      <description>&lt;p&gt;Most acquisition data on the web is stored as a flat list: acquirer, target, date, price. That shape is easy to render in a table and nearly useless for analysis, because it throws away the thing you actually want - structure.&lt;/p&gt;

&lt;p&gt;Acquisitions are a graph. Nodes are entities, edges are transactions with a direction and a timestamp. Once you model it that way, a set of queries opens up that a flat table cannot answer:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Chains.&lt;/strong&gt; Company A buys B; B had previously bought C. The IP you care about moved twice. A flat list shows two unrelated rows.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Divestments.&lt;/strong&gt; An entity leaves the graph and re-enters elsewhere. Spin-offs are edges too, and omitting them makes portfolios look monotonically expanding.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Clustering by category.&lt;/strong&gt; Group edges by target category and the acquirer's strategy becomes visible as a shape rather than a narrative.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Pharmaceutical companies are the clearest test case for this, because their acquisition activity is pipeline acquisition. Buying a company is often buying one molecule at a specific trial phase. Novartis AG is a useful example - the company was itself formed in 1996 by the merger of Ciba-Geigy and Sandoz, so its own root node is a merger, and its subsequent activity includes both acquisitions and significant divestments as it moved away from generics.&lt;/p&gt;

&lt;p&gt;A schema that survives contact with real data:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"acquirer"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"novartis"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"target"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"example-bio"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"announced"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2024-03-11"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"closed"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2024-07-02"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"acquisition"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"category"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"oncology"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"disclosed_value_usd"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"source_url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://..."&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Two design notes.&lt;/p&gt;

&lt;p&gt;Keep &lt;code&gt;announced&lt;/code&gt; and &lt;code&gt;closed&lt;/code&gt; separate. Deals fall through, and collapsing the two dates silently rewrites history.&lt;/p&gt;

&lt;p&gt;Make &lt;code&gt;disclosed_value_usd&lt;/code&gt; explicitly nullable rather than defaulting to zero. "Undisclosed" and "zero" are very different facts, and &lt;code&gt;0&lt;/code&gt; will quietly poison every aggregate you compute.&lt;/p&gt;

&lt;p&gt;For a worked example of the raw material, the &lt;a href="https://corpdigest.com/company/novartis/acquisitions" rel="noopener noreferrer"&gt;Novartis acquisition history&lt;/a&gt; is laid out chronologically, which is a reasonable input format before you normalise it into edges.&lt;/p&gt;

&lt;p&gt;Once the graph exists, the interesting queries are the ones about time: how long between a therapeutic area's first acquisition and its second, and does that interval shorten when a strategy is working?&lt;/p&gt;

</description>
      <category>datascience</category>
      <category>data</category>
      <category>beginners</category>
    </item>
  </channel>
</rss>
