<?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>Forem: Johan</title>
    <description>The latest articles on Forem by Johan (@johan_c7e77c866baaf5c2586).</description>
    <link>https://forem.com/johan_c7e77c866baaf5c2586</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.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3717056%2F691a9816-bf3a-47a4-9050-e6efdf10d99b.png</url>
      <title>Forem: Johan</title>
      <link>https://forem.com/johan_c7e77c866baaf5c2586</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/johan_c7e77c866baaf5c2586"/>
    <language>en</language>
    <item>
      <title>How I Modeled 13,000 Political Entities into 86,000 Searchable Pages</title>
      <dc:creator>Johan</dc:creator>
      <pubDate>Wed, 08 Apr 2026 14:39:09 +0000</pubDate>
      <link>https://forem.com/johan_c7e77c866baaf5c2586/how-i-modeled-13000-political-entities-into-86000-searchable-pages-2p4h</link>
      <guid>https://forem.com/johan_c7e77c866baaf5c2586/how-i-modeled-13000-political-entities-into-86000-searchable-pages-2p4h</guid>
      <description>&lt;p&gt;Most political information online lives in flat pages.&lt;/p&gt;

&lt;p&gt;A country article.&lt;br&gt;
A politician bio.&lt;br&gt;
A party overview.&lt;br&gt;
An election page.&lt;/p&gt;

&lt;p&gt;That works for facts, but it breaks down when people want to understand how power actually moves.&lt;/p&gt;

&lt;p&gt;Who appoints whom?&lt;br&gt;
How do coalition partners connect?&lt;br&gt;
What office inherits power during a resignation?&lt;br&gt;
How do institutions interact during a constitutional crisis?&lt;/p&gt;

&lt;p&gt;Those are graph problems.&lt;/p&gt;

&lt;p&gt;So I started building PoliticaHub, a global political knowledge graph designed to map countries, politicians, parties, offices, institutions, and elections as connected entities rather than isolated articles.&lt;/p&gt;

&lt;p&gt;Today the graph models 13,000+ political entities and powers 86,000 searchable pages.&lt;/p&gt;

&lt;p&gt;Why politics naturally becomes a graph&lt;/p&gt;

&lt;p&gt;Politics is almost never about standalone facts.&lt;/p&gt;

&lt;p&gt;A president is connected to:&lt;/p&gt;

&lt;p&gt;country&lt;br&gt;
office&lt;br&gt;
predecessor and successor&lt;br&gt;
party&lt;br&gt;
election&lt;br&gt;
legislature&lt;br&gt;
cabinet&lt;br&gt;
constitutional powers&lt;/p&gt;

&lt;p&gt;A legislature is connected to:&lt;/p&gt;

&lt;p&gt;chambers&lt;br&gt;
governing coalition&lt;br&gt;
opposition blocs&lt;br&gt;
party seat distributions&lt;br&gt;
electoral systems&lt;br&gt;
confidence rules&lt;/p&gt;

&lt;p&gt;A single relationship can unlock multiple ways to understand the same system.&lt;/p&gt;

&lt;p&gt;That means one clean graph layer can power:&lt;/p&gt;

&lt;p&gt;country dashboards&lt;br&gt;
office timelines&lt;br&gt;
election hubs&lt;br&gt;
coalition scenarios&lt;br&gt;
compare pages&lt;br&gt;
institutional explainers&lt;br&gt;
succession chains&lt;/p&gt;

&lt;p&gt;Instead of manually writing thousands of disconnected pages, the graph creates reusable political structure.&lt;/p&gt;

&lt;p&gt;The Firestore model&lt;/p&gt;

&lt;p&gt;I’m using Firestore as the main data layer.&lt;/p&gt;

&lt;p&gt;The core collections are intentionally simple:&lt;/p&gt;

&lt;p&gt;entities&lt;br&gt;
relationships&lt;br&gt;
entity_metadata&lt;br&gt;
office_terms&lt;/p&gt;

&lt;p&gt;Each entity has a type:&lt;/p&gt;

&lt;p&gt;country&lt;br&gt;
politician&lt;br&gt;
party&lt;br&gt;
office&lt;br&gt;
institution&lt;br&gt;
election&lt;/p&gt;

&lt;p&gt;The real power comes from typed relationships:&lt;/p&gt;

&lt;p&gt;holds_office&lt;br&gt;
member_of&lt;br&gt;
governs&lt;br&gt;
succeeded_by&lt;br&gt;
coalition_with&lt;br&gt;
participated_in&lt;br&gt;
reports_to&lt;/p&gt;

&lt;p&gt;Pages are generated by traversing those relationships.&lt;/p&gt;

&lt;p&gt;A country page, for example, can resolve:&lt;/p&gt;

&lt;p&gt;current leadership&lt;br&gt;
current government&lt;br&gt;
party ecosystem&lt;br&gt;
legislature structure&lt;br&gt;
next election&lt;br&gt;
recent office transitions&lt;br&gt;
constitutional system&lt;/p&gt;

&lt;p&gt;without hardcoding country-specific logic.&lt;/p&gt;

&lt;p&gt;That abstraction layer is what allowed the page count to scale.&lt;/p&gt;

&lt;p&gt;How the graph became 86,000 pages&lt;/p&gt;

&lt;p&gt;The interesting part is that the site was never designed around “let’s make thousands of SEO pages.”&lt;/p&gt;

&lt;p&gt;The page explosion came naturally from the relationships.&lt;/p&gt;

&lt;p&gt;Once the graph stabilized, each entity and relationship family started creating its own route surfaces:&lt;/p&gt;

&lt;p&gt;/country/[slug]&lt;br&gt;
/politician/[slug]&lt;br&gt;
/party/[slug]&lt;br&gt;
/office/[slug]&lt;br&gt;
/election/[slug]&lt;br&gt;
compare pages&lt;br&gt;
system explainers&lt;br&gt;
derived leadership pages&lt;br&gt;
historical office term pages&lt;/p&gt;

&lt;p&gt;The result is now 86,000+ searchable pages, but each page is rooted in real graph truth rather than thin templates.&lt;/p&gt;

&lt;p&gt;That distinction matters a lot.&lt;/p&gt;

&lt;p&gt;At scale, the only sustainable SEO is relationship-backed usefulness.&lt;/p&gt;

&lt;p&gt;The hardest problem: time-aware truth&lt;/p&gt;

&lt;p&gt;The hardest problem wasn’t scale.&lt;/p&gt;

&lt;p&gt;It was time.&lt;/p&gt;

&lt;p&gt;Political facts expire constantly:&lt;/p&gt;

&lt;p&gt;elections happen&lt;br&gt;
cabinets reshuffle&lt;br&gt;
coalitions collapse&lt;br&gt;
resignations happen overnight&lt;br&gt;
legislatures dissolve&lt;br&gt;
succession rules activate instantly&lt;/p&gt;

&lt;p&gt;“Person X is prime minister” is only true for a bounded period.&lt;/p&gt;

&lt;p&gt;That’s why office_terms became critical.&lt;/p&gt;

&lt;p&gt;Once terms became time-aware, the graph unlocked:&lt;/p&gt;

&lt;p&gt;leadership timelines&lt;br&gt;
succession after crises&lt;br&gt;
historical governments&lt;br&gt;
office overlap with elections&lt;br&gt;
“who was in power during X”&lt;br&gt;
coalition memory&lt;/p&gt;

&lt;p&gt;That temporal truth layer is probably the strongest long-term moat in the system.&lt;/p&gt;

&lt;p&gt;Biggest engineering lesson&lt;/p&gt;

&lt;p&gt;The biggest thing I’ve learned is this:&lt;/p&gt;

&lt;p&gt;politics is easier to understand as connected state than as articles.&lt;/p&gt;

&lt;p&gt;Editorial writing still matters, but the graph makes the writing structurally smarter.&lt;/p&gt;

&lt;p&gt;Instead of explaining isolated facts, pages can explain how power flows through institutions over time.&lt;/p&gt;

&lt;p&gt;That’s the real goal.&lt;/p&gt;

&lt;p&gt;If you want to see the live graph in action, it’s here:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://politicahub.com" rel="noopener noreferrer"&gt;https://politicahub.com&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Would love feedback from anyone working in civic tech, graph systems, Firestore, or large-scale SEO architectures.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>seo</category>
      <category>firebase</category>
    </item>
    <item>
      <title>I turned cookie consent dark patterns into games</title>
      <dc:creator>Johan</dc:creator>
      <pubDate>Sat, 17 Jan 2026 19:23:20 +0000</pubDate>
      <link>https://forem.com/johan_c7e77c866baaf5c2586/i-turned-cookie-consent-dark-patterns-into-games-56pk</link>
      <guid>https://forem.com/johan_c7e77c866baaf5c2586/i-turned-cookie-consent-dark-patterns-into-games-56pk</guid>
      <description>&lt;p&gt;Most explanations of cookie consent dark patterns are abstract.&lt;/p&gt;

&lt;p&gt;They describe what’s happening, but they never capture how it actually &lt;em&gt;feels&lt;/em&gt; to interact with these systems: the hesitation, the friction, the subtle pressure to give up and click “accept.”&lt;/p&gt;

&lt;p&gt;So instead of writing another breakdown, I built a set of small, playable experiments.&lt;/p&gt;

&lt;p&gt;Each game simulates a real consent tactic:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;delayed or hidden rejection&lt;/li&gt;
&lt;li&gt;asymmetric choices&lt;/li&gt;
&lt;li&gt;false urgency&lt;/li&gt;
&lt;li&gt;friction by design&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The site subtly changes based on how you interact, mirroring how real consent systems adapt to user behavior.&lt;/p&gt;

&lt;p&gt;There are no accounts, no cookies, and no tracking. Each experience takes under a minute.&lt;/p&gt;

&lt;p&gt;This started as a side project, but it turned into a surprisingly effective way to make dark patterns legible — especially for people who design or build the web.&lt;/p&gt;

&lt;p&gt;You can try it here:&lt;br&gt;
&lt;a href="https://thenonconsensualcookiebandit.com/" rel="noopener noreferrer"&gt;https://thenonconsensualcookiebandit.com/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I’d love feedback from other builders — especially on whether this kind of experiential explanation works better than documentation.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>ux</category>
      <category>privacy</category>
      <category>gamedev</category>
    </item>
  </channel>
</rss>
