<?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: Geetansh Vikram</title>
    <description>The latest articles on DEV Community by Geetansh Vikram (@geetansh_vikram_836d7f761).</description>
    <link>https://dev.to/geetansh_vikram_836d7f761</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%2F3960431%2F6fd3b3d4-ae10-4d6d-b108-6765a2ff5d5d.png</url>
      <title>DEV Community: Geetansh Vikram</title>
      <link>https://dev.to/geetansh_vikram_836d7f761</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/geetansh_vikram_836d7f761"/>
    <language>en</language>
    <item>
      <title>I Built a Relationship Intelligence CRM with Claude Code + Coral — Here's the Route</title>
      <dc:creator>Geetansh Vikram</dc:creator>
      <pubDate>Sat, 30 May 2026 19:55:51 +0000</pubDate>
      <link>https://dev.to/geetansh_vikram_836d7f761/i-built-a-relationship-intelligence-crm-with-claude-code-coral-heres-the-route-2bd4</link>
      <guid>https://dev.to/geetansh_vikram_836d7f761/i-built-a-relationship-intelligence-crm-with-claude-code-coral-heres-the-route-2bd4</guid>
      <description>&lt;p&gt;&lt;strong&gt;Live demo:&lt;/strong&gt; &lt;a href="https://coral-hackaton.onrender.com" rel="noopener noreferrer"&gt;coral-hackaton.onrender.com&lt;/a&gt;&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Repo:&lt;/strong&gt; &lt;a href="https://github.com/Geetansh-12/coral_hackaton" rel="noopener noreferrer"&gt;github.com/Geetansh-12/coral_hackaton&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Most people don't lose touch with contacts because they don't care — they lose touch because relationship data is scattered across Gmail, Slack, LinkedIn, calendar invites, and community servers. I built &lt;strong&gt;Coral CRM&lt;/strong&gt; for the Pirates of the Coral-bean hackathon to show what happens when you stop treating those surfaces as separate apps and start treating them as &lt;strong&gt;one SQL graph&lt;/strong&gt; powered by &lt;a href="https://withcoral.com" rel="noopener noreferrer"&gt;Coral&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This post is the reproducible route: problem → architecture → Coral capabilities → live demo → custom Discord source spec.&lt;/p&gt;


&lt;h2&gt;
  
  
  The problem
&lt;/h2&gt;

&lt;p&gt;Relationship intelligence breaks when every channel owns a slice of context:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Gmail knows what you said&lt;/li&gt;
&lt;li&gt;Calendar knows when you meet&lt;/li&gt;
&lt;li&gt;Slack knows what happened in DMs&lt;/li&gt;
&lt;li&gt;LinkedIn knows job changes&lt;/li&gt;
&lt;li&gt;Discord knows community engagement&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;An AI agent can't recommend "reach out to Sarah before Thursday's meeting" if it only sees one inbox. You need a &lt;strong&gt;unified graph&lt;/strong&gt; the agent can query safely.&lt;/p&gt;


&lt;h2&gt;
  
  
  Why Coral (not just MCP connectors)
&lt;/h2&gt;

&lt;p&gt;MCP connectors are great for tool calls. Coral adds something different: &lt;strong&gt;SQL over APIs&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Instead of writing bespoke fetch logic for every source, Coral exposes tables you can &lt;code&gt;JOIN&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="k"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;company&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;health_score&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
       &lt;span class="k"&gt;g&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;public_repos&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;g&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;followers&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;contacts&lt;/span&gt; &lt;span class="k"&gt;c&lt;/span&gt;
&lt;span class="k"&gt;JOIN&lt;/span&gt; &lt;span class="n"&gt;github&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;users&lt;/span&gt; &lt;span class="k"&gt;g&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="k"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;github_username&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;g&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;username&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="k"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;health_score&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That query runs in the SQL Explorer of Coral CRM and returns live GitHub profile data joined against local contacts — proof that federated joins aren't vaporware.&lt;/p&gt;

&lt;p&gt;Coral also gives you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Catalog discovery&lt;/strong&gt; — &lt;code&gt;coral.tables&lt;/code&gt;, &lt;code&gt;coral.columns&lt;/code&gt;, &lt;code&gt;coral.inputs&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cache/freshness observability&lt;/strong&gt; — &lt;code&gt;coral.query_log&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;One auth/retry/pagination layer&lt;/strong&gt; for agent workloads&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Architecture in 60 seconds
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Landing / Dashboard / Explorer / AI Chat
              ↓
        Next.js API routes (/api/query, /api/chat, /api/brief)
              ↓
     Demo Mode (mock)  OR  Live Mode (SQLite + coral CLI)
              ↓
   contact_relationship_graph  ← 6 seeded sources + live GitHub/Discord
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Demo Mode&lt;/strong&gt; works with zero API keys — judges can click through immediately.&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Live Mode&lt;/strong&gt; seeds SQLite locally and spawns the real &lt;code&gt;coral&lt;/code&gt; binary for federated queries.&lt;/p&gt;

&lt;p&gt;Tech stack: Next.js 14, TypeScript, Tailwind, Gemini (free tier) for AI, better-sqlite3, Coral CLI.&lt;/p&gt;


&lt;h2&gt;
  
  
  Step-by-step: run it yourself
&lt;/h2&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/Geetansh-12/coral_hackaton.git
&lt;span class="nb"&gt;cd &lt;/span&gt;coral_hackaton
npm &lt;span class="nb"&gt;install
&lt;/span&gt;npm run seed   &lt;span class="c"&gt;# optional — seeds SQLite for live mode&lt;/span&gt;
npm run dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Open &lt;strong&gt;&lt;a href="http://localhost:3000" rel="noopener noreferrer"&gt;http://localhost:3000&lt;/a&gt;&lt;/strong&gt;. The app starts in Demo Mode with 34 realistic contacts.&lt;/p&gt;
&lt;h3&gt;
  
  
  Switch to Live Mode
&lt;/h3&gt;

&lt;p&gt;Copy &lt;code&gt;.env.local.example&lt;/code&gt; → &lt;code&gt;.env.local&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;DEMO_MODE=false
GEMINI_API_KEY=your_key
GITHUB_TOKEN=ghp_...
DISCORD_BOT_TOKEN=your_bot_token   # for the custom Discord source
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Install the Discord source spec:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;coral &lt;span class="nb"&gt;source &lt;/span&gt;lint ./sources/discord/manifest.yaml
coral &lt;span class="nb"&gt;source &lt;/span&gt;add &lt;span class="nt"&gt;--file&lt;/span&gt; ./sources/discord/manifest.yaml &lt;span class="nt"&gt;--interactive&lt;/span&gt;
coral &lt;span class="nb"&gt;source test &lt;/span&gt;discord
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Coral capabilities we demonstrate (7/7)
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. SQL interface over multiple sources
&lt;/h3&gt;

&lt;p&gt;Six seeded tables in &lt;code&gt;sql/schema.sql&lt;/code&gt;: Gmail threads, Calendar events, Slack messages, LinkedIn activity, Twitter activity, Notion contacts.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Cross-source JOINs
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;contact_relationship_graph&lt;/code&gt; materialized view LEFT JOINs all six on email and computes a &lt;code&gt;health_score&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Catalog discovery
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="k"&gt;schema&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;table&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sql_reference&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;source_type&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;freshness&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;coral&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tables&lt;/span&gt; &lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="k"&gt;schema&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4. Parameter hints
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;parameter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;type&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;required&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;coral&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;inputs&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  5. Cache &amp;amp; freshness
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;query_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sources_joined&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cache_hit_rate&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;avg_ms&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;coral&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;query_log&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  6. Real CLI execution
&lt;/h3&gt;

&lt;p&gt;In Live Mode, &lt;code&gt;/api/query&lt;/code&gt; spawns &lt;code&gt;coral sql --format json&lt;/code&gt; asynchronously — no blocking the Next.js event loop on slow API calls.&lt;/p&gt;

&lt;h3&gt;
  
  
  7. Pluggable source architecture
&lt;/h3&gt;

&lt;p&gt;Settings page shows connector diagnostics per source. We added a &lt;strong&gt;custom Discord source spec&lt;/strong&gt; (see below).&lt;/p&gt;




&lt;h2&gt;
  
  
  The judge demo flow
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Open &lt;code&gt;/dashboard&lt;/code&gt; → click &lt;strong&gt;Judge Demo&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Show &lt;strong&gt;Agent Plan&lt;/strong&gt; and &lt;strong&gt;Coral Capability Cockpit&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Open &lt;strong&gt;SQL Explorer&lt;/strong&gt; → run the cross-source GitHub JOIN recipe&lt;/li&gt;
&lt;li&gt;Open a contact → generate a &lt;strong&gt;pre-meeting brief&lt;/strong&gt; → export it&lt;/li&gt;
&lt;li&gt;Ask the chat agent: &lt;em&gt;"What Coral capabilities does this demo use?"&lt;/em&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Screenshots are in &lt;code&gt;docs/screenshots/&lt;/code&gt; in the repo.&lt;/p&gt;




&lt;h2&gt;
  
  
  Building a custom Discord source spec (bounty track)
&lt;/h2&gt;

&lt;p&gt;Coral ships Gmail, GitHub, Slack, etc. — but &lt;strong&gt;Discord wasn't in the catalog&lt;/strong&gt;. For the hackathon "Chart New Waters" track, I wrote a YAML source spec that maps Discord REST API v10 endpoints to SQL tables.&lt;/p&gt;

&lt;p&gt;File: &lt;code&gt;sources/discord/manifest.yaml&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tables exposed:&lt;/strong&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;SQL table&lt;/th&gt;
&lt;th&gt;Discord API&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;discord.current_user&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;GET /users/@me&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;discord.guilds&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;GET /users/@me/guilds&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;discord.channels&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;GET /guilds/{guild_id}/channels&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;discord.messages&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;GET /channels/{channel_id}/messages&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;discord.members&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;GET /guilds/{guild_id}/members&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Auth pattern:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;auth&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;HeaderAuth&lt;/span&gt;
  &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Authorization&lt;/span&gt;
      &lt;span class="na"&gt;from&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;template&lt;/span&gt;
      &lt;span class="na"&gt;template&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Bot {{input.DISCORD_BOT_TOKEN}}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Nested JSON → SQL columns&lt;/strong&gt; using Coral's &lt;code&gt;__&lt;/code&gt; convention:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;author__username&lt;/span&gt;
  &lt;span class="na"&gt;expr&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;path&lt;/span&gt;
    &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;author&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;username&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Validation workflow:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;coral &lt;span class="nb"&gt;source &lt;/span&gt;lint ./sources/discord/manifest.yaml
coral &lt;span class="nb"&gt;source &lt;/span&gt;add &lt;span class="nt"&gt;--file&lt;/span&gt; ./sources/discord/manifest.yaml
coral &lt;span class="nb"&gt;source test &lt;/span&gt;discord
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Example CRM query once installed:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;author__username&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;timestamp&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;discord&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;messages&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;channel_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'YOUR_CHANNEL_ID'&lt;/span&gt;
&lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="nb"&gt;timestamp&lt;/span&gt; &lt;span class="k"&gt;DESC&lt;/span&gt;
&lt;span class="k"&gt;LIMIT&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Full docs: &lt;code&gt;sources/discord/README.md&lt;/code&gt;&lt;br&gt;&lt;br&gt;
Upstream PR target: &lt;code&gt;withcoral/coral&lt;/code&gt; → &lt;code&gt;sources/community/discord/&lt;/code&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  What I learned
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Start with one table.&lt;/strong&gt; Guilds first, then channels, then messages. Run &lt;code&gt;coral source test&lt;/code&gt; after each addition.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Nested fields need explicit &lt;code&gt;expr&lt;/code&gt;.&lt;/strong&gt; Don't assume &lt;code&gt;author__username&lt;/code&gt; auto-flattens — declare the path.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Filters in URL paths&lt;/strong&gt; use &lt;code&gt;{{filter.guild_id}}&lt;/code&gt; — same pattern as other community specs (OSV, dbt Cloud).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Demo + Live dual mode&lt;/strong&gt; was the right call for hackathon judges — zero friction to explore, real CLI when credentials exist.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Docker on Render&lt;/strong&gt; beats serverless for a 150MB Coral binary — one container, authentic live URL.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  What's next
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Open upstream PR for the Discord source spec&lt;/li&gt;
&lt;li&gt;Join Discord messages into &lt;code&gt;contact_relationship_graph&lt;/code&gt; on username/nickname&lt;/li&gt;
&lt;li&gt;OAuth device flow for Gmail/Calendar in production&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Links
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Live app:&lt;/strong&gt; &lt;a href="https://coral-hackaton.onrender.com" rel="noopener noreferrer"&gt;coral-hackaton.onrender.com&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GitHub:&lt;/strong&gt; &lt;a href="https://github.com/Geetansh-12/coral_hackaton" rel="noopener noreferrer"&gt;Geetansh-12/coral_hackaton&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Coral docs:&lt;/strong&gt; &lt;a href="https://withcoral.com/docs" rel="noopener noreferrer"&gt;withcoral.com/docs&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Custom source guide:&lt;/strong&gt; &lt;a href="https://withcoral.com/docs/guides/write-a-custom-source" rel="noopener noreferrer"&gt;Write a custom source spec&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hackathon:&lt;/strong&gt; &lt;a href="https://wemakedevs.org/hackathons/coral" rel="noopener noreferrer"&gt;WeMakeDevs × Coral&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;




</description>
      <category>coral</category>
      <category>ai</category>
      <category>discord</category>
      <category>nextjs</category>
    </item>
  </channel>
</rss>
