<?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: Mochi</title>
    <description>The latest articles on DEV Community by Mochi (@beyza312).</description>
    <link>https://dev.to/beyza312</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%2F3955121%2Fc386d8de-d3ab-44a2-8aed-a41cfa005143.png</url>
      <title>DEV Community: Mochi</title>
      <link>https://dev.to/beyza312</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/beyza312"/>
    <language>en</language>
    <item>
      <title>Chingu AI: Building an AI Chat App with Spring Boot &amp; GitHub Copilot</title>
      <dc:creator>Mochi</dc:creator>
      <pubDate>Mon, 01 Jun 2026 20:46:41 +0000</pubDate>
      <link>https://dev.to/beyza312/chingu-ai-building-an-ai-chat-app-with-spring-boot-github-copilot-4mja</link>
      <guid>https://dev.to/beyza312/chingu-ai-building-an-ai-chat-app-with-spring-boot-github-copilot-4mja</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/github-2026-05-21"&gt;GitHub Finish-Up-A-Thon Challenge&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

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

&lt;p&gt;&lt;strong&gt;Chingu AI&lt;/strong&gt; is a full-stack AI chat application built with Spring Boot 3, secured with Google OAuth2, and powered by the Groq API for fast LLM inference.&lt;/p&gt;

&lt;p&gt;The name "Chingu" (친구) means &lt;em&gt;"Friend"&lt;/em&gt; in Korean — and that's exactly what I wanted to build: a coding companion that feels like a peer, not a rigid tool.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tech Stack:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Backend:&lt;/strong&gt; Java 17, Spring Boot 3, Spring Security, Spring Data JPA&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Frontend:&lt;/strong&gt; Thymeleaf, Bootstrap 5, custom dark/purple cyberpunk UI&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Database:&lt;/strong&gt; SQL Server (message history persistence)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AI Engine:&lt;/strong&gt; Groq API&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Auth:&lt;/strong&gt; Google OAuth2 SSO + Form Login&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6f5vycrznzt3o4v98a3u.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6f5vycrznzt3o4v98a3u.png" alt=" " width="277" height="365"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Feaclnoqug9e9ls45p3d6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Feaclnoqug9e9ls45p3d6.png" alt=" " width="800" height="595"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo8wy4thp47jed7gx0ro7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo8wy4thp47jed7gx0ro7.png" alt=" " width="270" height="404"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;👉 &lt;strong&gt;&lt;a href="https://github.com/beyzanur314/ChinguAi" rel="noopener noreferrer"&gt;GitHub Repository: beyzanur314/ChinguAi&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  The Comeback Story
&lt;/h2&gt;

&lt;p&gt;This project had been sitting at "almost done" for weeks. It worked — technically. But it had real problems that made it unusable for others.&lt;/p&gt;

&lt;h3&gt;
  
  
  Where I started:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Basic Spring Boot project with no authentication&lt;/li&gt;
&lt;li&gt;No AI integration&lt;/li&gt;
&lt;li&gt;No message history&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  The problems I hit (and fixed):
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;1. The OAuth2 Infinite Loop 🔄&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;After integrating Google OAuth2, authenticated users kept getting bounced back to the login screen with a &lt;code&gt;401 Unauthorized&lt;/code&gt; error. The fix was buried in Spring Security's filter chain — I needed to explicitly permit &lt;code&gt;/login/oauth2/code/**&lt;/code&gt; for the token exchange callback.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. The Ambiguous Mapping Crash 💥&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Spring Boot refused to start due to an &lt;code&gt;IllegalStateException: Ambiguous mapping&lt;/code&gt; — two controller beans were competing for the same &lt;code&gt;GET /chingu/ui&lt;/code&gt; route. I resolved this by unifying them into a single polymorphic endpoint using &lt;code&gt;@AuthenticationPrincipal Object principal&lt;/code&gt; to handle both &lt;code&gt;UserDetails&lt;/code&gt; and &lt;code&gt;OAuth2User&lt;/code&gt; dynamically.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. The Secret Leak Incident 🔐&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;During a Git push, GitHub's Push Protection hard-blocked my commit — my Groq API keys and Google client secrets were exposed in &lt;code&gt;application.properties&lt;/code&gt;. Instead of bypassing the warning, I cleaned the Git history, invalidated the leaked credentials on Groq Console, and moved all secrets to environment variables.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Groq 401 Unauthorized&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Even after the secret leak fix, I hit Groq API 401 errors because the environment variables weren't being picked up correctly at runtime. Debugging this taught me a lot about how Spring Boot loads external configuration.&lt;/p&gt;




&lt;h2&gt;
  
  
  My Experience with GitHub Copilot
&lt;/h2&gt;

&lt;p&gt;GitHub Copilot completely changed how I debugged this project inside IntelliJ IDEA.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Security Refactoring:&lt;/strong&gt; When I was lost in Spring Security's fluent DSL, Copilot scaffolded the correct &lt;code&gt;SecurityFilterChain&lt;/code&gt; bean structure — including the exact syntax for chaining &lt;code&gt;formLogin&lt;/code&gt; and &lt;code&gt;oauth2Login&lt;/code&gt; together.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Thymeleaf Templates:&lt;/strong&gt; Writing &lt;code&gt;th:action&lt;/code&gt; paths and dynamic conditional headers with OAuth2 user attributes is surprisingly tricky. Copilot accurately predicted token pathways like &lt;code&gt;oauth2User.getAttribute('picture')&lt;/code&gt; for rendering user avatars.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Stack Trace Debugging:&lt;/strong&gt; When Spring threw 50+ line stack traces about ambiguous mappings, Copilot pinpointed the exact controller lines causing the conflict — saving me hours of manual tracing.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Secret Management:&lt;/strong&gt; Copilot proactively suggested moving hardcoded credentials to environment variables before the leak happened. I should have listened earlier.&lt;/p&gt;




&lt;h2&gt;
  
  
  Lessons Learned
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;OAuth2 requires exact configuration — one wrong redirect URI breaks everything&lt;/li&gt;
&lt;li&gt;Environment variables &amp;gt; hardcoded secrets, always&lt;/li&gt;
&lt;li&gt;GitHub Copilot is most powerful when you give it the full error context&lt;/li&gt;
&lt;li&gt;Spring Security's filter chain order matters more than you think&lt;/li&gt;
&lt;li&gt;"Almost done" is not the same as "done" — finishing is a skill&lt;/li&gt;
&lt;/ol&gt;




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

&lt;ul&gt;
&lt;li&gt;Cloud deployment (Azure/Railway)&lt;/li&gt;
&lt;li&gt;Voice input/output&lt;/li&gt;
&lt;li&gt;User profiles and settings&lt;/li&gt;
&lt;li&gt;Rate limiting&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;em&gt;Built with Java, Spring Boot, Groq API, and GitHub Copilot&lt;/em&gt; ☕🤖&lt;/p&gt;

</description>
      <category>programming</category>
      <category>devchallenge</category>
      <category>ai</category>
      <category>githubcopilot</category>
    </item>
  </channel>
</rss>
