<?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: Dmytro Werner</title>
    <description>The latest articles on DEV Community by Dmytro Werner (@york).</description>
    <link>https://dev.to/york</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%2F916092%2Fd9d74f2b-2498-46ff-b6d8-151aa1b8e2f5.jpg</url>
      <title>DEV Community: Dmytro Werner</title>
      <link>https://dev.to/york</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/york"/>
    <language>en</language>
    <item>
      <title>I don’t have to remember git commands - I built an AI Git Navigator to do them for me 🧭 🤖</title>
      <dc:creator>Dmytro Werner</dc:creator>
      <pubDate>Tue, 10 Feb 2026 19:30:18 +0000</pubDate>
      <link>https://dev.to/york/i-dont-have-to-remember-git-commands-i-built-an-ai-git-navigator-to-do-them-for-me-3l4k</link>
      <guid>https://dev.to/york/i-dont-have-to-remember-git-commands-i-built-an-ai-git-navigator-to-do-them-for-me-3l4k</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/github-2026-01-21"&gt;GitHub Copilot CLI Challenge&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

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

&lt;p&gt;Let’s be honest.&lt;/p&gt;

&lt;p&gt;I don’t really remember all git commands and usually have to google if I want to revert some changes or make cherry-picking or something like this.&lt;/p&gt;

&lt;p&gt;“I just want to revert the last commit… but on that branch… without breaking prod… please.”&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%2Fj5pikle12d0bonvvkbth.gif" 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%2Fj5pikle12d0bonvvkbth.gif" alt="Please" width="500" height="375"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So I built Git Navigator — an AI-powered CLI that turns natural language into safe, reviewable git commands.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Idea
&lt;/h2&gt;

&lt;p&gt;What if you could just say:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Please revert last commit from branch release/1&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And your terminal replied:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;“Cool. Here’s what I’m about to do.
Take a look. Breathe. Confirm.”
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;That’s Git Navigator.&lt;/p&gt;

&lt;p&gt;What Is Git Navigator?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Git Navigator is an AI-powered CLI that:&lt;/li&gt;
&lt;li&gt;Accepts natural language instructions&lt;/li&gt;
&lt;li&gt;Converts them into structured git operations&lt;/li&gt;
&lt;li&gt;Builds a step-by-step execution plan&lt;/li&gt;
&lt;li&gt;Shows risk level&lt;/li&gt;
&lt;li&gt;Runs in dry-run mode by default&lt;/li&gt;
&lt;li&gt;Asks for confirmation before doing anything dangerous&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In short:&lt;br&gt;
&lt;strong&gt;You describe what you want&lt;/strong&gt; &lt;br&gt;
&lt;strong&gt;The tool figures out how to do it — safely&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Example&lt;/p&gt;

&lt;p&gt;&lt;code&gt;gitnavigator -m = "Please revert last commit from branch release/1"&lt;br&gt;
&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;🧭 Git Navigator

Proposed plan:
1. Switch to branch release/1
   git checkout release/1
2. Revert last commit
   git revert HEAD

Risk level: high

Dry-run mode. No commands executed.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

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



&lt;blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;revert commits&lt;br&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%2Fzqufqt6z12slnr7142ve.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%2Fzqufqt6z12slnr7142ve.png" alt="Revert commits" width="800" height="251"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;create new branch&lt;br&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%2F895x25r78pux07edoyd0.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%2F895x25r78pux07edoyd0.png" alt="New branche" width="800" height="216"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/blockquote&gt;
&lt;h2&gt;
  
  
  Architecture
&lt;/h2&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Natural language
   ↓
AI (Copilot)
   ↓
Structured intent (JSON)
   ↓
buildPlan.ts
   ↓
Concrete git commands
   ↓
Execution

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Installation and Local (Development)
&lt;/h2&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install
&lt;/span&gt;npm run build
npm &lt;span class="nb"&gt;link&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;After linking, the CLI becomes globally available:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gitnavigator &lt;span class="nt"&gt;--help&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Code
&lt;/h2&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.dev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/Yordaniss" rel="noopener noreferrer"&gt;
        Yordaniss
      &lt;/a&gt; / &lt;a href="https://github.com/Yordaniss/git-navigator" rel="noopener noreferrer"&gt;
        git-navigator
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;🧭 Git Navigator&lt;/h1&gt;
&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Git Navigator&lt;/strong&gt; is an AI-powered CLI tool that converts natural language instructions into safe, structured, and executable git commands.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;You describe &lt;strong&gt;what you want to do&lt;/strong&gt;.&lt;br&gt;
Git Navigator figures out &lt;strong&gt;how to do it — safely&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;✨ Features&lt;/h2&gt;
&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;🧠 Natural language → git commands&lt;/li&gt;
&lt;li&gt;🧭 Step-by-step execution plan&lt;/li&gt;
&lt;li&gt;🔍 Dry-run mode by default (safe preview)&lt;/li&gt;
&lt;li&gt;
⚠️ Risk level estimation for each operation&lt;/li&gt;
&lt;li&gt;✅ User confirmation before execution&lt;/li&gt;
&lt;li&gt;🤖 AI-powered intent interpretation (GitHub Copilot / LLM)&lt;/li&gt;
&lt;li&gt;🛡 Designed for real production repositories&lt;/li&gt;
&lt;/ul&gt;




&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;📦 Installation&lt;/h2&gt;
&lt;/div&gt;

&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;Local (Development)&lt;/h3&gt;

&lt;/div&gt;

&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;npm install
npm run build
npm link&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;After linking, the CLI becomes globally available:&lt;/p&gt;
&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;gitnavigator --help&lt;/pre&gt;

&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;🚀 Usage&lt;/h2&gt;

&lt;/div&gt;

&lt;p&gt;Basic usage (dry-run)&lt;/p&gt;

&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;gitnavigator -- &lt;span class="pl-s"&gt;&lt;span class="pl-pds"&gt;"&lt;/span&gt;Please revert last commit&lt;span class="pl-pds"&gt;"&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;📝 By default, Git Navigator runs in dry-run mode and does not execute any git commands.&lt;/p&gt;

&lt;p&gt;Execute commands&lt;/p&gt;

&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;gitnavigator -- &lt;span class="pl-s"&gt;&lt;span class="pl-pds"&gt;"&lt;/span&gt;Please revert last commit from branch release/1&lt;span class="pl-pds"&gt;"&lt;/span&gt;&lt;/span&gt; --apply&lt;/pre&gt;

&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;You…&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/Yordaniss/git-navigator" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;

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



&lt;p&gt;While building &lt;strong&gt;Git Navigator&lt;/strong&gt; , GitHub Copilot CLI played a very specific and intentional role:&lt;br&gt;
it was used as a planning assistant, not as an execution engine.&lt;/p&gt;

&lt;p&gt;Instead of asking Copilot to run commands directly, I used it to translate natural language intent into structured JSON instructions. This allowed me to keep full control over execution logic while still benefiting from Copilot’s language understanding.&lt;/p&gt;
&lt;h3&gt;
  
  
  What Worked Well
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Intent interpretation&lt;br&gt;
Copilot CLI was very effective at understanding vague or high-level instructions like&lt;br&gt;
“Please revert last commit from branch release/1” and turning them into actionable intent.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Consistency with a strict prompt&lt;br&gt;
By enforcing a system prompt that allowed only JSON output, I was able to reliably parse responses and avoid hallucinated explanations or unsafe commands.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Fast iteration&lt;br&gt;
Using Copilot CLI directly in the terminal made it easy to iterate on prompts and immediately see how small prompt changes affected the output.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This forced me to design a clear separation:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Copilot plans&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The CLI decides&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The user confirms&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;


&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;Git Navigator is here to meet developers where they are — thinking in intent, not syntax.&lt;/p&gt;

&lt;p&gt;If you’ve ever:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Googled “how to revert last commit”? &lt;/li&gt;
&lt;li&gt;Panicked after pressing Enter?&lt;/li&gt;
&lt;li&gt;Or whispered “please work” to your terminal…?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This tool my be for you.&lt;/p&gt;

&lt;p&gt;Thanks for reading — and happy navigating 🧭 ⛴&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%2Fkrbr47k7dentvuxk4xui.gif" 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%2Fkrbr47k7dentvuxk4xui.gif" alt="Captain" width="245" height="300"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Feedback and contributions are more than welcome!&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;P.S. Covered image was generated by dev.to platform ;-)&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>devchallenge</category>
      <category>githubchallenge</category>
      <category>cli</category>
      <category>githubcopilot</category>
    </item>
    <item>
      <title>🔐 Permission Testing Toolkit — Build, Validate, and Ship Secure Authorization with Permit.io</title>
      <dc:creator>Dmytro Werner</dc:creator>
      <pubDate>Fri, 02 May 2025 20:45:33 +0000</pubDate>
      <link>https://dev.to/york/permission-testing-toolkit-build-validate-and-ship-secure-authorization-with-permitio-375b</link>
      <guid>https://dev.to/york/permission-testing-toolkit-build-validate-and-ship-secure-authorization-with-permitio-375b</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/permit_io"&gt;Permit.io Authorization Challenge&lt;/a&gt;: Permissions Redefined&lt;/em&gt;&lt;/p&gt;

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

&lt;p&gt;&lt;strong&gt;Permission Testing Toolkit&lt;/strong&gt; is a CLI utility built with TypeScript that allows teams to &lt;em&gt;validate&lt;/em&gt;, &lt;em&gt;simulate&lt;/em&gt;, and &lt;em&gt;test&lt;/em&gt; their fine-grained access control logic using &lt;a href="https://www.permit.io" rel="noopener noreferrer"&gt;Permit.io&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;✅ It supports both &lt;strong&gt;manual test cases via JSON&lt;/strong&gt; and &lt;strong&gt;dynamic test generation&lt;/strong&gt; using your &lt;strong&gt;live Permit.io schema&lt;/strong&gt;.&lt;br&gt;&lt;br&gt;
✅ It’s perfect for CI pipelines or security-conscious teams that want to &lt;strong&gt;"test their policies before they break production."&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
✅ Oh — and it looks nice in your terminal too. 🎨&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;You write the rules. This CLI makes sure they're followed.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;




&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;npm start

  ____                            ____ _               _    
 |  _ &lt;span class="se"&gt;\ &lt;/span&gt;___ _ __ _ __ ___        / ___| |__   ___  ___| | __
 | |_&lt;span class="o"&gt;)&lt;/span&gt; / _ &lt;span class="se"&gt;\ &lt;/span&gt;&lt;span class="s1"&gt;'__| '&lt;/span&gt;_ &lt;span class="sb"&gt;`&lt;/span&gt; _ &lt;span class="se"&gt;\ &lt;/span&gt;_____| |   | &lt;span class="s1"&gt;'_ \ / _ \/ __| |/ /
 |  __/  __/ |  | | | | | |_____| |___| | | |  __/ (__|   &amp;lt; 
 |_|   \___|_|  |_| |_| |_|      \____|_| |_|\___|\___|_|\_\

Running tests from config: test-cases/perm-config.json

📝 Permission Test Report:
========================================
1. Viewer can read a post
   ➤ User: viewer
   ➤ Resource: post
   ➤ Action: read
   ➤ Expected: allow, Actual: allow
   ➤ ✅ PASS

2. Editor cannot delete a post
   ➤ User: editor
   ➤ Resource: post
   ➤ Action: delete
   ➤ Expected: deny, Actual: deny
   ➤ ✅ PASS

✔️  2/2 tests passed.
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;blockquote&gt;
&lt;p&gt;perm-config.json:&lt;br&gt;
&lt;/p&gt;


&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="s2"&gt;"tests"&lt;/span&gt;: &lt;span class="o"&gt;[&lt;/span&gt;
    &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="s2"&gt;"user"&lt;/span&gt;: &lt;span class="s2"&gt;"admin"&lt;/span&gt;,
      &lt;span class="s2"&gt;"resource"&lt;/span&gt;: &lt;span class="s2"&gt;"post"&lt;/span&gt;,
      &lt;span class="s2"&gt;"action"&lt;/span&gt;: &lt;span class="s2"&gt;"delete"&lt;/span&gt;,
      &lt;span class="s2"&gt;"expected"&lt;/span&gt;: &lt;span class="s2"&gt;"allow"&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;,
    &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="s2"&gt;"user"&lt;/span&gt;: &lt;span class="s2"&gt;"editor"&lt;/span&gt;,
      &lt;span class="s2"&gt;"resource"&lt;/span&gt;: &lt;span class="s2"&gt;"post"&lt;/span&gt;,
      &lt;span class="s2"&gt;"action"&lt;/span&gt;: &lt;span class="s2"&gt;"delete"&lt;/span&gt;,
      &lt;span class="s2"&gt;"expected"&lt;/span&gt;: &lt;span class="s2"&gt;"deny"&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
  &lt;span class="o"&gt;]&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;blockquote&gt;
&lt;p&gt;Output example:&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;...
Check delete &lt;span class="k"&gt;for &lt;/span&gt;viewer
   ➤ User: Sam Smith
   ➤ Resource: Document_number_1
   ➤ Action: delete
   ➤ Expected: allow, Actual: deny
   ➤ ❌ FAIL
...
Summary:
✔ Passed: 4
✘ Failed: 4
Total: 8
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;blockquote&gt;
&lt;p&gt;Global CLI installation:&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; &lt;span class="nb"&gt;.&lt;/span&gt;
perm-check &lt;span class="nt"&gt;--config&lt;/span&gt; path/to/perm-config.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Project Repo
&lt;/h2&gt;




&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/Yordaniss" rel="noopener noreferrer"&gt;
        Yordaniss
      &lt;/a&gt; / &lt;a href="https://github.com/Yordaniss/permission-testing-toolkit" rel="noopener noreferrer"&gt;
        permission-testing-toolkit
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;🚦 Permission Testing Toolkit&lt;/h1&gt;
&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Permission Testing Toolkit&lt;/strong&gt; is a blazing-fast CLI tool that helps developers automatically test access rules (RBAC/ABAC) configured in &lt;a href="https://www.permit.io/" rel="nofollow noopener noreferrer"&gt;Permit.io&lt;/a&gt; across multiple users, resources, and actions — using both custom test cases and live schema introspection.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;✅ Built with performance, automation, and CI/CD integration in mind — no UI needed.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;📦 Features&lt;/h2&gt;
&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;✅ &lt;strong&gt;Custom Permission Tests&lt;/strong&gt; — Define explicit test cases for users, actions, and expected results.&lt;/li&gt;
&lt;li&gt;🚀 &lt;strong&gt;Live Schema Introspection&lt;/strong&gt; — Auto-generate permission tests based on your Permit.io policy schema.&lt;/li&gt;
&lt;li&gt;🧠 &lt;strong&gt;Role Coverage Testing&lt;/strong&gt; — Dynamically test every role against every action on every resource.&lt;/li&gt;
&lt;li&gt;💥 &lt;strong&gt;CI/CD Friendly&lt;/strong&gt; — Easily integrate into pipelines to prevent policy regressions.&lt;/li&gt;
&lt;li&gt;🛠️ &lt;strong&gt;Developer-First&lt;/strong&gt; — CLI-only experience, blazing-fast, fully written in TypeScript.&lt;/li&gt;
&lt;/ul&gt;




&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;📸 Demo Output&lt;/h2&gt;
&lt;/div&gt;

&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;$ npm start
  ____                            ____ _               _    
 &lt;span class="pl-k"&gt;|&lt;/span&gt;  _ &lt;span class="pl-cce"&gt;\ &lt;/span&gt;___ _ __ _ __ ___        / ___&lt;span class="pl-k"&gt;|&lt;/span&gt; &lt;span class="pl-k"&gt;|&lt;/span&gt;__   ___  ___&lt;span class="pl-k"&gt;|&lt;/span&gt; &lt;span class="pl-k"&gt;|&lt;/span&gt; __
 &lt;/pre&gt;…
&lt;/div&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/Yordaniss/permission-testing-toolkit" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;The README walks you through setup, usage, &lt;code&gt;.env&lt;/code&gt; configuration, live schema fetching, and creating your own test cases.&lt;br&gt;&lt;br&gt;
You can even install the CLI globally using &lt;code&gt;npm install -g .&lt;/code&gt; to run &lt;code&gt;perm-check&lt;/code&gt; from anywhere.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  My Journey
&lt;/h2&gt;

&lt;p&gt;When I started, my goal was to &lt;em&gt;not just use Permit.io for auth&lt;/em&gt;, but to &lt;strong&gt;test and trust my auth&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Highlights:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Built a CLI using &lt;code&gt;commander&lt;/code&gt; + &lt;code&gt;chalk&lt;/code&gt; for clean UX.&lt;/li&gt;
&lt;li&gt;Added support for:

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;.json&lt;/code&gt; config file tests (great for version control)&lt;/li&gt;
&lt;li&gt;Live schema inspection via &lt;code&gt;@permit.io/sdk&lt;/code&gt; (dynamic users/actions/resources)&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Created a readable, colorful terminal test report 📊&lt;/li&gt;

&lt;li&gt;Packaged everything into a globally installable CLI&lt;/li&gt;

&lt;/ul&gt;

&lt;h3&gt;
  
  
  Challenges &amp;amp; Lessons:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Learned how the Permit.io API &amp;amp; SDK expose actions/resources&lt;/li&gt;
&lt;li&gt;Discovered the value of “failing fast” in access control testing&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Using Permit.io for Authorization
&lt;/h2&gt;

&lt;p&gt;This CLI interacts with &lt;strong&gt;Permit.io&lt;/strong&gt; in two major ways:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Static Testing&lt;/strong&gt;:&lt;br&gt;&lt;br&gt;
Load test cases from a &lt;code&gt;.json&lt;/code&gt; config and check &lt;code&gt;allow/deny&lt;/code&gt; against Permit.io’s PDP (Policy Decision Point) via REST.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Dynamic Schema Testing&lt;/strong&gt;:&lt;br&gt;&lt;br&gt;
Use the SDK to fetch all defined &lt;code&gt;users&lt;/code&gt;, &lt;code&gt;resources&lt;/code&gt;, and &lt;code&gt;actions&lt;/code&gt; in your Permit.io project. Then simulate permission checks across the board.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;📦 Future Potential&lt;br&gt;
This project is not just a utility — it’s the foundation for a permission validation library that could:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Be published as an NPM package&lt;/li&gt;
&lt;li&gt;Integrate into CI pipelines (e.g., GitHub Actions)&lt;/li&gt;
&lt;li&gt;Visualize permission coverage&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;🙌 Team or Solo&lt;br&gt;
This was a solo project.&lt;/p&gt;

&lt;p&gt;Huge thanks to Permit.io and DEV.to for organizing this challenge and providing excellent documentation and tooling.&lt;br&gt;
This experience was both rewarding and empowering — it not only deepened my understanding of modern authorization workflows but also inspired me to build something perhaps useful for the developer community.&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>permitchallenge</category>
      <category>webdev</category>
      <category>security</category>
    </item>
    <item>
      <title>From idea to gift: 🎁 Wish list application with KendoReact 🤺, KI 🤖 &amp; Firebase 💾</title>
      <dc:creator>Dmytro Werner</dc:creator>
      <pubDate>Thu, 20 Mar 2025 18:58:42 +0000</pubDate>
      <link>https://dev.to/york/from-idea-to-gift-wish-list-application-with-kendoreact-ki-firebase-35ge</link>
      <guid>https://dev.to/york/from-idea-to-gift-wish-list-application-with-kendoreact-ki-firebase-35ge</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/kendoreact"&gt;KendoReact Free Components Challenge&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

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

&lt;p&gt;I built a Wishlist App that allows users to:&lt;br&gt;
✅ Create and manage wishlists.&lt;br&gt;
✅ Add, edit, and remove wishlist items.&lt;br&gt;
✅ Mark items as favorites ❤️.&lt;br&gt;
✅ Share their wishlist via a unique link.&lt;br&gt;
✅ Reserve items from shared wishlists.&lt;br&gt;
✅ Get AI-powered gift recommendations 🎯.&lt;/p&gt;

&lt;h3&gt;
  
  
  Demo
&lt;/h3&gt;

&lt;h2&gt;
  
  
  Start page
&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%2F9qp4mi5tmjatuo97fqz5.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%2F9qp4mi5tmjatuo97fqz5.png" alt="Start page" width="800" height="396"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Wishlist
&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%2Fhoh2hzx45x6ny0mkuxgr.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%2Fhoh2hzx45x6ny0mkuxgr.png" alt="Start page" width="800" height="396"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Get AI Recommendations
&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%2F5jy2vz92dolag22kpxp4.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%2F5jy2vz92dolag22kpxp4.png" alt="Get AI Recommendations" width="637" height="153"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Wishlist with AI Response
&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%2Fimxu0re40ofui7kood01.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%2Fimxu0re40ofui7kood01.png" alt="Wish list" width="648" height="640"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Share link
&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%2F1watjad4vn1cbf6f9bif.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%2F1watjad4vn1cbf6f9bif.png" alt="share link" width="189" height="95"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Shared wishlist for guests
&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%2Flaf6aqv2s62vvhw2bc5z.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%2Flaf6aqv2s62vvhw2bc5z.png" alt="Shared wishlist" width="800" height="399"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The code app is under this link: &lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.dev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/Yordaniss" rel="noopener noreferrer"&gt;
        Yordaniss
      &lt;/a&gt; / &lt;a href="https://github.com/Yordaniss/wishlist-ai" rel="noopener noreferrer"&gt;
        wishlist-ai
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;📌 KendoReact Free Components Challenge Submission&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;This is a submission for the KendoReact Free Components Challenge.&lt;/p&gt;
&lt;p&gt;What I Built 🎁
I built a feature-rich Wishlist App that allows users to:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;✅ Create and manage wishlists.&lt;/li&gt;
&lt;li&gt;✅ Add, edit, and remove wishlist items.&lt;/li&gt;
&lt;li&gt;✅ Mark items as favorites ❤️.&lt;/li&gt;
&lt;li&gt;✅ Share their wishlist via a unique link.&lt;/li&gt;
&lt;li&gt;✅ Reserve items from shared wishlists.&lt;/li&gt;
&lt;li&gt;✅ Get AI-powered gift recommendations 🎯.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This project is designed to help users organize gift ideas for birthdays, holidays, and special occasions while enhancing collaboration with friends and family.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Running the Project Locally&lt;/h1&gt;
&lt;/div&gt;
&lt;ol&gt;
&lt;li&gt;1️⃣ Clone the Repository&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="snippet-clipboard-content notranslate position-relative overflow-auto"&gt;&lt;pre class="notranslate"&gt;&lt;code&gt;git clone https://github.com/YOUR_USERNAME/YOUR_REPO.git
cd YOUR_REPO
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ol start="2"&gt;
&lt;li&gt;2️⃣ Setup the Environment Variables&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;Frontend
Rename .env.example to .env and fill in your Firebase credentials:&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="snippet-clipboard-content notranslate position-relative overflow-auto"&gt;&lt;pre class="notranslate"&gt;&lt;code&gt;REACT_APP_FIREBASE_API_KEY=your_api_key
REACT_APP_FIREBASE_APP_DOMAIN=your_app_domain
REACT_APP_FIREBASE_PROJECT_NAME=your_project_name
REACT_APP_FIREBASE_STORAGE_BUCKET=your_storage_bucket
REACT_APP_FIREBASE_MESSAGING_SENDER_ID=your_messaging_sender_id
REACT_APP_FIREBASE_APP_ID=your_app_id
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;Backend:
Rename .env.example to .env and add your Cloudflare credentials:&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="snippet-clipboard-content notranslate position-relative overflow-auto"&gt;&lt;pre class="notranslate"&gt;&lt;code&gt;CLOUDFLARE_ACCOUNT=your_account_id
CLOUDFLARE_TOKEN=your_api_token
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ol start="3"&gt;
&lt;li&gt;Install Dependencies&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;Frontend:&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="snippet-clipboard-content notranslate position-relative overflow-auto"&gt;&lt;pre class="notranslate"&gt;&lt;code&gt;cd frontend
npm install
npm start
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;Backend:&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="snippet-clipboard-content notranslate position-relative overflow-auto"&gt;
&lt;pre class="notranslate"&gt;&lt;code&gt;cd backend&lt;/code&gt;&lt;/pre&gt;…&lt;/div&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/Yordaniss/wishlist-ai" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;/h2&gt;

&lt;h2&gt;
  
  
  Running the Project Locally
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;1️⃣ Clone the Repository
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git clone https://github.com/YOUR_USERNAME/YOUR_REPO.git
cd YOUR_REPO
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;2️⃣ Setup the Environment Variables&lt;/li&gt;
&lt;li&gt;Frontend:
Rename .env.example to .env and fill in your Firebase credentials:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;REACT_APP_FIREBASE_API_KEY=your_api_key
REACT_APP_FIREBASE_APP_DOMAIN=your_app_domain
REACT_APP_FIREBASE_PROJECT_NAME=your_project_name
REACT_APP_FIREBASE_STORAGE_BUCKET=your_storage_bucket
REACT_APP_FIREBASE_MESSAGING_SENDER_ID=your_messaging_sender_id
REACT_APP_FIREBASE_APP_ID=your_app_id
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Backend:
Rename .env.example to .env and add your Cloudflare credentials:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CLOUDFLARE_ACCOUNT=your_account_id
CLOUDFLARE_TOKEN=your_api_token
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt; Install Dependencies&lt;/li&gt;
&lt;li&gt;Frontend:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cd frontend
npm install
npm start
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Backend:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cd backend
npm install
npm start
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your app should now be running! 🎉&lt;/p&gt;

&lt;h2&gt;
  
  
  KendoReact Experience
&lt;/h2&gt;

&lt;p&gt;KendoReact played a major role in making this wishlist app functional. I used:&lt;/p&gt;

&lt;p&gt;✔ KendoReact Buttons: Stylish buttons for adding, sharing, and reserving wishlist items.&lt;br&gt;
✔ KendoReact Inputs: Clean form controls for entering item details.&lt;br&gt;
✔ KendoReact Checkbox: Used for category selection &lt;br&gt;
✔ KendoReact TextArea: Entering some additional text. &lt;br&gt;
✔ KendoReact DropDownList: Easy item categorization.&lt;br&gt;
✔ KendoReact Avatar: Enhancing UI with user-friendly elements.&lt;br&gt;
✔ KendoReact Chip: UI Component for favorite icon&lt;br&gt;
✔ KendoReact Notification: Displaying alerts and updates.&lt;br&gt;
✔ KendoReact ProgressBar: Showing AI recommendation loading state.&lt;br&gt;
✔ KendoReact Animation: Smooth transitions for adding/removing items.&lt;/p&gt;

&lt;p&gt;And also some icons in navigation:&lt;br&gt;
✔ KendoReact homeIcon&lt;br&gt;
✔ KendoReact SvgIcon&lt;/p&gt;

&lt;h3&gt;
  
  
  AIm to Impress
&lt;/h3&gt;

&lt;p&gt;This app integrates AI-powered recommendations 🎯 using Cloudflare API to suggest personalized gift ideas based on the wishlist contents.&lt;/p&gt;

&lt;p&gt;🛠 How it works:&lt;br&gt;
1️⃣ The user clicks "Get AI Recommendations."&lt;br&gt;
2️⃣ The app sends wishlist data to the AI-powered API.&lt;br&gt;
3️⃣ The AI analyzes preferences and suggests new gift ideas.&lt;br&gt;
4️⃣ The recommendations appear in a KendoReact Notification panel.&lt;/p&gt;

&lt;p&gt;🔍 This feature leverages AI to enhance user experience by providing smart, tailored gift suggestions.&lt;/p&gt;

&lt;h3&gt;
  
  
  Team Submissions
&lt;/h3&gt;

&lt;p&gt;Worked alone during this project.&lt;/p&gt;

&lt;p&gt;🚀 Final Thoughts&lt;br&gt;
🎉 This project showcases how KendoReact Free Components can be used to build a fully functional, AI-powered wishlist.&lt;/p&gt;

&lt;p&gt;Big thanks to KendoReact for this challenge! Looking forward to exploring more KendoReact features in future projects. 🚀&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>kendoreactchallenge</category>
      <category>react</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Patient Management and Recommendation System with AssemlyAI and CloudflareAI 🏥👩‍⚕️👨‍⚕️</title>
      <dc:creator>Dmytro Werner</dc:creator>
      <pubDate>Fri, 22 Nov 2024 18:52:10 +0000</pubDate>
      <link>https://dev.to/york/patient-management-and-recommendation-system-with-assemlyai-and-cloudflareai-59m9</link>
      <guid>https://dev.to/york/patient-management-and-recommendation-system-with-assemlyai-and-cloudflareai-59m9</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/assemblyai"&gt;AssemblyAI Challenge &lt;/a&gt;: Sophisticated Speech-to-Text.&lt;/em&gt;&lt;/p&gt;

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

&lt;p&gt;I built a Patient Management and Recommendation System that streamlines medical data collection and provides tailored health recommendations based on patients' symptoms. The application allows users to upload audio recordings of patient details and symptoms, which are transcribed into structured text using AssemblyAI’s advanced Speech-to-Text API. The system then parses this information, categorizes the symptoms, and displays personalized recommendations for treatment using CloudflareAI.&lt;/p&gt;

&lt;p&gt;Key features:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;1. Audio-to-text transcription using AssemblyAI.&lt;/li&gt;
&lt;li&gt;2. Symptom analysis and tailored treatment recommendations using CloudflareAI Worker.&lt;/li&gt;
&lt;li&gt;3. Clean and intuitive user interface for managing patient data.&lt;/li&gt;
&lt;li&gt;4. Hosted in a Dockerized environment with a PostgreSQL database for persistent storage.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;The code app is under this link: &lt;/p&gt;
&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.dev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/Yordaniss" rel="noopener noreferrer"&gt;
        Yordaniss
      &lt;/a&gt; / &lt;a href="https://github.com/Yordaniss/healthcare" rel="noopener noreferrer"&gt;
        healthcare
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Patient Management System&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;This project is a &lt;strong&gt;Patient Management System&lt;/strong&gt; designed to handle patient records, process audio inputs for medical transcription, and provide symptom-based treatment recommendations. The application leverages modern React components for the frontend and integrates APIs for intelligent analysis.&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Features&lt;/h2&gt;
&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;Core Functionality&lt;/h3&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Patient List View&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Displays a list of all patients with their summaries in a responsive, card-based layout.&lt;/li&gt;
&lt;li&gt;Allows users to browse and view patient details.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Patient Details View&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Displays comprehensive information about a patient, including:
&lt;ul&gt;
&lt;li&gt;Name&lt;/li&gt;
&lt;li&gt;Age&lt;/li&gt;
&lt;li&gt;Recorded symptoms&lt;/li&gt;
&lt;li&gt;Date of consultation&lt;/li&gt;
&lt;li&gt;Transcription and parsed medical recommendations.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;File Upload&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Accepts audio files for transcription.&lt;/li&gt;
&lt;li&gt;Automatically updates the patient list with new data upon successful file upload.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;Intelligent AI and Audio Processing&lt;/h3&gt;

&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;AssemblyAI Integration&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Converts audio files into text using the AssemblyAI transcription service.&lt;/li&gt;
&lt;li&gt;Extracts meaningful details such as
&lt;ul&gt;
&lt;li&gt;Patient name&lt;/li&gt;
&lt;li&gt;Age&lt;/li&gt;
&lt;li&gt;Symptoms&lt;/li&gt;
&lt;li&gt;Consultation date&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Cloudflare AI Integration&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Processes symptoms via Cloudflare…&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/Yordaniss/healthcare" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;Patient list including audio upload:&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%2F1h0l6uv8djui4vkvn3w9.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%2F1h0l6uv8djui4vkvn3w9.PNG" alt="Patient list" width="800" height="348"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Patient details:&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%2Fh1zrccn5hgajlbzbvx6l.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%2Fh1zrccn5hgajlbzbvx6l.PNG" alt="Patient details" width="800" height="283"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Journey
&lt;/h2&gt;

&lt;p&gt;This project was designed to simplify managing patient records and generating personalized health recommendations. The goal was to streamline the workload for healthcare professionals by enabling them to record audio notes about patients and extract key information automatically. For example, a doctor seeing multiple patients in a day can simply upload an audio file, and the application will process it to extract critical data like the patient's name, age, symptoms, and recommended treatments—saving time and ensuring accuracy in record-keeping.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How AssemblyAI Was Used&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Audio-to-Text Transcription&lt;/em&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Audio-to-Text Transcription:&lt;br&gt;
Using AssemblyAI’s API, uploaded audio files containing patient details (e.g., "Patient Jane Smith, age 29, reporting fatigue and fever") are transcribed into text. The API seamlessly converts diverse medical terms and patient notes with remarkable accuracy.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Data Parsing:&lt;br&gt;
After transcription, key details such as the patient’s name, age, symptoms, and date are extracted using regular expressions and integrated into the database.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Recommendations Engine:&lt;br&gt;
Based on the parsed symptoms, the app provides structured recommendations (e.g., "Rest and hydration," "Over-the-counter medications") using CloudflareAI. These are presented in a clear and accessible format to help users take action.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;AssemblyAI Challenge Prompts:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Sophisticated Speech-to-Text Application: Built an end-to-end system that goes beyond transcription to include actionable insights and a user-friendly interface.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Intelligent AI and Audio Processing&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;AssemblyAI Integration:&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Converts audio files into text using the AssemblyAI transcription service.&lt;/li&gt;
&lt;li&gt;Extracts meaningful details such as:&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;  Patient name&lt;/li&gt;
&lt;li&gt;  Age&lt;/li&gt;
&lt;li&gt;  Symptoms&lt;/li&gt;
&lt;li&gt;  Consultation date&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;em&gt;Cloudflare AI Integration:&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Processes symptoms via Cloudflare AI to generate recommendations.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Tools and Technologies&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;AssemblyAI for transcription.&lt;/li&gt;
&lt;li&gt;CloudflareAI for recommendations.&lt;/li&gt;
&lt;li&gt;React for the front-end.&lt;/li&gt;
&lt;li&gt;Node.js and Express for the back-end API.&lt;/li&gt;
&lt;li&gt;PostgreSQL (via Docker) for database management.&lt;/li&gt;
&lt;li&gt;CSS for styling the user interface.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Thanks for the opportunity to showcase this project! 😊&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>assemblyaichallenge</category>
      <category>ai</category>
      <category>api</category>
    </item>
    <item>
      <title>AI Interview Prep Helper with PostgreSQL, Ollama, and Open-Source Vector Extensions 🚀</title>
      <dc:creator>Dmytro Werner</dc:creator>
      <pubDate>Wed, 06 Nov 2024 21:05:17 +0000</pubDate>
      <link>https://dev.to/york/ai-interview-prep-helper-with-postgresql-ollama-and-open-source-vector-extensions-2l8b</link>
      <guid>https://dev.to/york/ai-interview-prep-helper-with-postgresql-ollama-and-open-source-vector-extensions-2l8b</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/pgai"&gt;Open Source AI Challenge with pgai and Ollama &lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

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

&lt;p&gt;I built an AI-powered job skills recommendation application that leverages PostgreSQL and open-source vector extensions to recommend interview questions based on a job description. The application extracts key skills from job descriptions, embeds them as vectors, and stores them in PostgreSQL, allowing for efficient similarity searches. It also provides feedback on user-submitted answers to help applicants improve their responses based on specific feedback criteria.&lt;/p&gt;

&lt;p&gt;This project combines text analysis, vector similarity searches, and AI feedback generation, creating a tool that aids job seekers in better preparing for interviews with relevant questions and real-time feedback.&lt;/p&gt;

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

&lt;p&gt;The code app is under this link: &lt;/p&gt;
&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.dev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/Yordaniss" rel="noopener noreferrer"&gt;
        Yordaniss
      &lt;/a&gt; / &lt;a href="https://github.com/Yordaniss/interview-prep-helper" rel="noopener noreferrer"&gt;
        interview-prep-helper
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;AI Interview Prep Helper with PostgreSQL, Ollama and Open-Source Vector Extensions 🚀&lt;/h1&gt;
&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Project Overview&lt;/h2&gt;
&lt;/div&gt;
&lt;p&gt;This project demonstrates a lightweight AI application that leverages open-source tools, using PostgreSQL as the vector database with AI extensions. By embedding job descriptions and questions into vector format, this application can identify relevant questions based on job requirements, offer tailored question recommendations, and provide AI-generated feedback on responses.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;The key tools used in this project include:&lt;/h2&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;PostgreSQL with pgvector for storing and querying vector embeddings.&lt;/li&gt;
&lt;li&gt;pgAI for processing and retrieving feedback on user answers.&lt;/li&gt;
&lt;li&gt;Ollama as an AI tool for embedding and generating text responses.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Project Components&lt;/h2&gt;

&lt;/div&gt;
&lt;p&gt;The application has three primary parts:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Job Description Parsing and Question Recommendation: Given a job description, the application extracts key skills and identifies relevant questions from the database.&lt;/li&gt;
&lt;li&gt;AI-Driven Answer Feedback: Upon submitting an answer to a question, the application leverages AI feedback based on correctness, efficiency, code…&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/Yordaniss/interview-prep-helper" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;Please follow the instructions to run this locally.&lt;/p&gt;

&lt;h2&gt;
  
  
  Screenshots:
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Job Description Input&lt;/li&gt;
&lt;/ul&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%2F45mfpcx8v5nrleapbs8m.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%2F45mfpcx8v5nrleapbs8m.PNG" alt="Job Description Input" width="719" height="553"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Recommended Questions&lt;/li&gt;
&lt;/ul&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%2F98awxqlwuh10har30nnd.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%2F98awxqlwuh10har30nnd.PNG" alt="Recommended Questions" width="638" height="372"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt; Feedback on Answer&lt;/li&gt;
&lt;/ul&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%2Fzk8j6syiqreilsagkgw3.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%2Fzk8j6syiqreilsagkgw3.PNG" alt="Feedback on Answer" width="624" height="358"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Additional endpoints to store questions&lt;/li&gt;
&lt;/ul&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%2Fi9ko8asy9etcllrht0jp.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%2Fi9ko8asy9etcllrht0jp.PNG" alt="store questions" width="800" height="161"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;and get recommended &lt;/li&gt;
&lt;/ul&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%2Fkzra9dbw5p0x0ihgxhv8.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%2Fkzra9dbw5p0x0ihgxhv8.PNG" alt="get recommended questions" width="800" height="365"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Tools Used
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;pgvector&lt;br&gt;
pgvector stores the embeddings for job descriptions and questions, allowing us to query and compare them using similarity searches.&lt;br&gt;
It supports storing high-dimensional vectors and facilitates similarity-based searches within PostgreSQL, enabling the core recommendation functionality of this application.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;pgAI&lt;br&gt;
pgAI integrates AI-powered feedback directly within PostgreSQL.&lt;br&gt;
By embedding the feedback process into PostgreSQL queries, pgAI allows our application to evaluate and provide insights on user-submitted answers, scoring them on aspects like correctness, efficiency, and clarity.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Ollama&lt;br&gt;
Ollama is used to generate embeddings and feedback responses.&lt;br&gt;
It processes user queries, generates embeddings for job descriptions and questions, and helps in extracting relevant skills and evaluating answers with custom feedback prompts.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;This project demonstrates the power of combining PostgreSQL with its AI extensions to build a vector-based recommendation and feedback system without needing an additional vector database. Integrating pgvector, pgvectorscale, and pgAI made it possible to create an efficient, fully open-source AI application with minimal setup.&lt;/p&gt;

&lt;p&gt;Prize Categories:&lt;/p&gt;

&lt;p&gt;Open-source Models from Ollama&lt;/p&gt;

&lt;h2&gt;
  
  
  Thanks you! ❤️
&lt;/h2&gt;

&lt;p&gt;Thanks for considering this project, and I hope you enjoy exploring its functionality as much as I enjoyed building it!  🙏&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>pgaichallenge</category>
      <category>database</category>
      <category>ai</category>
    </item>
    <item>
      <title>Nylas Mailbox AI Assistant 🤖</title>
      <dc:creator>Dmytro Werner</dc:creator>
      <pubDate>Wed, 28 Aug 2024 20:19:07 +0000</pubDate>
      <link>https://dev.to/york/nylas-mailbox-ai-assistant-16g</link>
      <guid>https://dev.to/york/nylas-mailbox-ai-assistant-16g</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/nylas"&gt;Nylas Challenge&lt;/a&gt;: AI Expedition.&lt;/em&gt;&lt;/p&gt;

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

&lt;p&gt;Hello everyone 🙂&lt;br&gt;
Using Nylas-API and Cloudflare-AI I have build Mailbox AI Assistant to help:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;organize your emails 💻&lt;/li&gt;
&lt;li&gt;send congratulations to your contacts if they have birthday 🥳&lt;/li&gt;
&lt;li&gt;get your next events 🎊&lt;/li&gt;
&lt;li&gt;automatically summarize content from email and send the answer to emails, that were not read 📖 🤖&lt;/li&gt;
&lt;li&gt;get information, how much emails I have got this week 🗓&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Main idea was to automatize minor things, that you could forget, like congratulations or get information about your email and calendar.&lt;/p&gt;
&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;p&gt;First of all we could get information about emails of the current week. For this one I have used ´queryParams´ from Nylas API:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const messages = await nylas.messages.list({
      identifier,
      queryParams: {
        received_after: Math.floor(startOfWeek.getTime() / 1000)
      }
    });
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;a href="https://media.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%2F916i5zvtkmfpmu5xzpzn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2F916i5zvtkmfpmu5xzpzn.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Second feature is to get contacts and they birthday days. If it is today, add button with functionality to send congratulations according to personal information from your contact, like name and age. This one we get from contacts using Nylas API.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const contacts = await nylas.contacts.list({
      identifier,
      queryParams: {},
    });
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;a href="https://media.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%2F98ti90ox39s66rkuo3yu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2F98ti90ox39s66rkuo3yu.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next one is to get events.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   const calendars = await nylas.calendars.find({
      identifier,
      calendarId: "primary",
    });
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;a href="https://media.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%2Fi2v8qkoov13fgidcgytw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fi2v8qkoov13fgidcgytw.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And now main content with most of codes. So we have emails, that are you did not read.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    const messages = await nylas.messages.list({
      identifier,
      queryParams: {
        unread: true,
      },
    });
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;a href="https://media.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%2Fxd2cpb6pinb4r3gbo8yu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fxd2cpb6pinb4r3gbo8yu.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can summarize email content using cloudflare model &lt;code&gt;cf/facebook/bart-large-cnn&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fhjiy8a8b64exb1uzdlie.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fhjiy8a8b64exb1uzdlie.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the next step you can generate the answer using other cloudflare model &lt;code&gt;cf/openchat/openchat-3.5-0106&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fuz4qclr2r7l8ree0jfw5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fuz4qclr2r7l8ree0jfw5.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you click send email, generated email will be send to person, that wrote this one.&lt;/p&gt;
&lt;h2&gt;
  
  
  Code
&lt;/h2&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/Yordaniss" rel="noopener noreferrer"&gt;
        Yordaniss
      &lt;/a&gt; / &lt;a href="https://github.com/Yordaniss/mailbox-assistant" rel="noopener noreferrer"&gt;
        mailbox-assistant
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;p&gt;Submitting for Nylas AI and Communications Challenge&lt;/p&gt;
&lt;p&gt;Using Nylas-API and Cloudflare-AI I have build Mailbox AI Assistant to help:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;organize your emails 💻&lt;/li&gt;
&lt;li&gt;send congratulations to your contacts if they have birthday 🥳&lt;/li&gt;
&lt;li&gt;get your next events 🎊&lt;/li&gt;
&lt;li&gt;automatically summarize content from email and send the answer to emails, that were not read 📖 🤖&lt;/li&gt;
&lt;li&gt;get information, how much emails I have got this week 🗓&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;

  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/Yordaniss/mailbox-assistant" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;



&lt;h2&gt;
  
  
  Your Journey
&lt;/h2&gt;

&lt;p&gt;That was really interesting to use nylas api to get information from my mail account. Best part of this, that you can write directly in your request the &lt;code&gt;queryParams&lt;/code&gt; with some conditions, that I have used for getting emails for current week. &lt;/p&gt;

&lt;p&gt;Im most proud of finishing the main features of this project and integrating AI text generating with key features of Nylas API. &lt;/p&gt;

&lt;p&gt;Most challenging was to create the concept and implement the logic for using AI to summarize and generate response of text. The solution for this was to create generating step by step with possibility to send response if thats ok or regenerate response.&lt;/p&gt;

&lt;p&gt;I found documentation of Nylas very good structured and prepared. Very useful was the page with endpoints:&lt;br&gt;
&lt;a href="https://developer.nylas.com/docs/api/v3/ecc/#overview--query-parameters" rel="noopener noreferrer"&gt;Documentation Nylas&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;List of models of cloudflare you can find under: &lt;br&gt;
&lt;a href="https://developers.cloudflare.com/workers-ai/models/" rel="noopener noreferrer"&gt;Cloudflare Models&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Thanks a lot for organization this challenge. Made me happy to work on this one 🤗&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fvly5v84wjl5vgipcie4b.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fvly5v84wjl5vgipcie4b.gif" alt="Thanks"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>nylaschallenge</category>
      <category>api</category>
      <category>ai</category>
    </item>
    <item>
      <title>GitHub + DEV 2023 Hackathon! - Github Commit Message Translator 📖</title>
      <dc:creator>Dmytro Werner</dc:creator>
      <pubDate>Thu, 11 May 2023 21:15:19 +0000</pubDate>
      <link>https://dev.to/york/github-dev-2023-hackathon-github-commit-message-translator-nk3</link>
      <guid>https://dev.to/york/github-dev-2023-hackathon-github-commit-message-translator-nk3</guid>
      <description>&lt;h2&gt;
  
  
  What I built
&lt;/h2&gt;

&lt;p&gt;I built GitHub action, that automatically translate commit message and pushes the message into GitHub pages using Jekyll for creating documentation or changelog.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/oFPiPgqwof4Pe/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/oFPiPgqwof4Pe/giphy.gif" alt="Read" width="360" height="202"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Category Submission:
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Maintainer Must-Haves&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  App Link
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://yordaniss.github.io/documentation/"&gt;GithubPage&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Screenshots
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ECCiT5Iz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/iuvo54ke1r811jcz3j3q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ECCiT5Iz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/iuvo54ke1r811jcz3j3q.png" alt="Image description" width="800" height="404"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--AwbZeqFa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zvacuyknq42fzd2ie32h.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--AwbZeqFa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zvacuyknq42fzd2ie32h.png" alt="Image description" width="800" height="403"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--sS5u4xdm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nj9td9yozm0z66vobp2m.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--sS5u4xdm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nj9td9yozm0z66vobp2m.png" alt="Image description" width="800" height="213"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Description
&lt;/h3&gt;

&lt;p&gt;After each commit, the message, that was written will be translated using Translator-API from mymemory.net. In .yml file, you can define target and source languages. After message was translated, the message will be sent to gh-pages, that is used as "documentation branch". I used Jekyll to create static webpage, that used markdown files for building pages. En voilà, at the end we have translated messages as documentation. &lt;/p&gt;

&lt;h3&gt;
  
  
  Link to Source Code
&lt;/h3&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--A9-wwsHG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/Yordaniss"&gt;
        Yordaniss
      &lt;/a&gt; / &lt;a href="https://github.com/Yordaniss/documentation"&gt;
        documentation
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;h1&gt;
Github translated commits into gh-pages for documentation/changelog 📖
&lt;/h1&gt;
&lt;p&gt;The project was created to generate translation for commit messages for supporting open source maintainers and repository owners to make it easier to write commit messages in other languages.&lt;/p&gt;
&lt;h3&gt;
Key Technologies&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;GitHub Pages&lt;/li&gt;
&lt;li&gt;GitHub Action&lt;/li&gt;
&lt;li&gt;MyMemory API (for translation)&lt;/li&gt;
&lt;li&gt;Jekyll&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;There are two option for languages (source and target language), other information will be got automatically from workflow. The .yml file look like: &lt;/p&gt;
&lt;div class="highlight highlight-source-yaml notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;&lt;span class="pl-ent"&gt;name&lt;/span&gt;: &lt;span class="pl-s"&gt;Translate commit message&lt;/span&gt;
&lt;span class="pl-ent"&gt;on&lt;/span&gt;: &lt;span class="pl-s"&gt;[push]&lt;/span&gt;
&lt;span class="pl-ent"&gt;jobs&lt;/span&gt;
  &lt;span class="pl-ent"&gt;run-script&lt;/span&gt;:
    &lt;span class="pl-ent"&gt;runs-on&lt;/span&gt;: &lt;span class="pl-s"&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class="pl-ent"&gt;steps&lt;/span&gt;:
      - &lt;span class="pl-ent"&gt;name&lt;/span&gt;: &lt;span class="pl-s"&gt;Checkout code&lt;/span&gt;
        &lt;span class="pl-ent"&gt;uses&lt;/span&gt;: &lt;span class="pl-s"&gt;actions/checkout@v2&lt;/span&gt;
      - &lt;span class="pl-ent"&gt;name&lt;/span&gt;: &lt;span class="pl-s"&gt;Install Node.js&lt;/span&gt;
        &lt;span class="pl-ent"&gt;uses&lt;/span&gt;: &lt;span class="pl-s"&gt;actions/setup-node@v2&lt;/span&gt;
        &lt;span class="pl-ent"&gt;with&lt;/span&gt;:
          &lt;span class="pl-ent"&gt;node-version&lt;/span&gt;: &lt;span class="pl-s"&gt;&lt;span class="pl-pds"&gt;"&lt;/span&gt;18.x&lt;span class="pl-pds"&gt;"&lt;/span&gt;&lt;/span&gt;
      - &lt;span class="pl-ent"&gt;name&lt;/span&gt;: &lt;span class="pl-s"&gt;Install dependencies&lt;/span&gt;
        &lt;span class="pl-ent"&gt;run&lt;/span&gt;: &lt;span class="pl-s"&gt;npm install&lt;/span&gt;
      - &lt;span class="pl-ent"&gt;name&lt;/span&gt;: &lt;span class="pl-s"&gt;Get Commit Message&lt;/span&gt;
        &lt;span class="pl-ent"&gt;id&lt;/span&gt;: &lt;span class="pl-s"&gt;commit_message&lt;/span&gt;
        &lt;span class="pl-ent"&gt;run&lt;/span&gt;: &lt;span class="pl-s"&gt;echo "::set-output name=message::$(cat $GITHUB_EVENT_PATH | jq -r '.commits[0].message')"&lt;/span&gt;
      - &lt;span class="pl-ent"&gt;name&lt;/span&gt;: &lt;span class="pl-s"&gt;Run Script&lt;/span&gt;
        &lt;span class="pl-ent"&gt;run&lt;/span&gt;: &lt;span class="pl-s"&gt;node action/index.js&lt;/span&gt;
        &lt;span class="pl-ent"&gt;env&lt;/span&gt;:
          &lt;/pre&gt;…
&lt;/div&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/Yordaniss/documentation"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;h3&gt;
  
  
  Permissive License
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/Yordaniss/documentation/blob/main/LICENSE"&gt;MIT&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Background (What made you decide to build this particular app? What inspired you?)
&lt;/h2&gt;

&lt;p&gt;I was thinking, the main idea of open source is to connect people from all around the corner, to build some cool projects. But there are so many languages, so it's sometimes difficult, to describe, what did you do in your commit. In other side this is also important for repository-owner, to get important information about workflow. In the best case as documentation.&lt;/p&gt;

&lt;h3&gt;
  
  
  How I built it (How did you utilize GitHub Actions or GitHub Codespaces? Did you learn something new along the way? Pick up a new skill?)
&lt;/h3&gt;

&lt;p&gt;I did learn a lot about GitHub Actions and GitHub Pages. For me, it was fascinating to create workflow, that automatically create new content for me. Functionality of "gh-pages" was for also something new to know, especially how does it work with Jekyll integration. I used all this information and of course the functionality of GitHub Actions to build it all in one tool. The information about workflow is also available in README file in my repository.&lt;/p&gt;

&lt;h3&gt;
  
  
  Additional Resources/Info
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://pages.github.com/"&gt;GithubPages&lt;/a&gt;&lt;br&gt;
&lt;a href="https://docs.github.com/de/pages/setting-up-a-github-pages-site-with-jekyll"&gt;GithubJekyll&lt;/a&gt;&lt;/p&gt;

</description>
      <category>githubhack23</category>
      <category>github</category>
      <category>githubactions</category>
    </item>
    <item>
      <title>Searching in JAVA: Elasticsearch vs MySQL vs Hibernate</title>
      <dc:creator>Dmytro Werner</dc:creator>
      <pubDate>Wed, 28 Sep 2022 05:57:14 +0000</pubDate>
      <link>https://dev.to/york/searching-in-java-elasticsearch-vs-mysql-vs-hibernate-5daa</link>
      <guid>https://dev.to/york/searching-in-java-elasticsearch-vs-mysql-vs-hibernate-5daa</guid>
      <description>&lt;p&gt;Hello folks :)&lt;/p&gt;

&lt;p&gt;I was thinking lately: if I have logic for searching data in frontend and JAVA for backend, which technology should be used to find data? In this case some search engine would be a good idea. But is it easy to implement? I wanted to try a couple things and compare, which option is the best.&lt;br&gt;
Learning by doing I understood how it works and I´d like to share this experience.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fbngtp4n2ijt4s3ee6eg7.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fbngtp4n2ijt4s3ee6eg7.gif" alt="LetUsBegin"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  JAVA
&lt;/h2&gt;

&lt;p&gt;First of all we need to create our JAVA application. I used the "Initializr" from Spring to get basic configuration for my project. &lt;a href="https://start.spring.io" rel="noopener noreferrer"&gt;Spring Initializr&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Spoiler!:-D &lt;br&gt;
My end configuration looks like this (Java version 18):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;?xml version="1.0" encoding="UTF-8"?&amp;gt;
&amp;lt;project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"&amp;gt;
    &amp;lt;modelVersion&amp;gt;4.0.0&amp;lt;/modelVersion&amp;gt;
    &amp;lt;parent&amp;gt;
        &amp;lt;groupId&amp;gt;org.springframework.boot&amp;lt;/groupId&amp;gt;
        &amp;lt;artifactId&amp;gt;spring-boot-starter-parent&amp;lt;/artifactId&amp;gt;
        &amp;lt;version&amp;gt;2.7.3&amp;lt;/version&amp;gt;
        &amp;lt;relativePath/&amp;gt; &amp;lt;!-- lookup parent from repository --&amp;gt;
    &amp;lt;/parent&amp;gt;
    &amp;lt;groupId&amp;gt;com.tutorial&amp;lt;/groupId&amp;gt;
    &amp;lt;artifactId&amp;gt;search&amp;lt;/artifactId&amp;gt;
    &amp;lt;version&amp;gt;0.0.1-SNAPSHOT&amp;lt;/version&amp;gt;
    &amp;lt;name&amp;gt;search&amp;lt;/name&amp;gt;
    &amp;lt;description&amp;gt;Tutorial project for search engine&amp;lt;/description&amp;gt;
    &amp;lt;properties&amp;gt;
        &amp;lt;java.version&amp;gt;18&amp;lt;/java.version&amp;gt;
    &amp;lt;/properties&amp;gt;
    &amp;lt;dependencies&amp;gt;
        &amp;lt;dependency&amp;gt;
            &amp;lt;groupId&amp;gt;org.springframework.boot&amp;lt;/groupId&amp;gt;
            &amp;lt;artifactId&amp;gt;spring-boot-starter-data-jpa&amp;lt;/artifactId&amp;gt;
        &amp;lt;/dependency&amp;gt;
        &amp;lt;dependency&amp;gt;
            &amp;lt;groupId&amp;gt;org.springframework.boot&amp;lt;/groupId&amp;gt;
            &amp;lt;artifactId&amp;gt;spring-boot-starter-web&amp;lt;/artifactId&amp;gt;
        &amp;lt;/dependency&amp;gt;

        &amp;lt;dependency&amp;gt;
            &amp;lt;groupId&amp;gt;org.hibernate.search&amp;lt;/groupId&amp;gt;
            &amp;lt;artifactId&amp;gt;hibernate-search-mapper-orm&amp;lt;/artifactId&amp;gt;
            &amp;lt;version&amp;gt;6.1.1.Final&amp;lt;/version&amp;gt;
        &amp;lt;/dependency&amp;gt;
        &amp;lt;dependency&amp;gt;
            &amp;lt;groupId&amp;gt;org.hibernate.search&amp;lt;/groupId&amp;gt;
            &amp;lt;artifactId&amp;gt;hibernate-search-backend-lucene&amp;lt;/artifactId&amp;gt;
            &amp;lt;version&amp;gt;6.1.1.Final&amp;lt;/version&amp;gt;
        &amp;lt;/dependency&amp;gt;

        &amp;lt;dependency&amp;gt;
            &amp;lt;groupId&amp;gt;org.springframework.data&amp;lt;/groupId&amp;gt;
            &amp;lt;artifactId&amp;gt;spring-data-elasticsearch&amp;lt;/artifactId&amp;gt;
            &amp;lt;version&amp;gt;4.0.0.RELEASE&amp;lt;/version&amp;gt;
        &amp;lt;/dependency&amp;gt;
        &amp;lt;dependency&amp;gt;
            &amp;lt;groupId&amp;gt;co.elastic.clients&amp;lt;/groupId&amp;gt;
            &amp;lt;artifactId&amp;gt;elasticsearch-java&amp;lt;/artifactId&amp;gt;
            &amp;lt;version&amp;gt;8.3.1&amp;lt;/version&amp;gt;
        &amp;lt;/dependency&amp;gt;

        &amp;lt;dependency&amp;gt;
            &amp;lt;groupId&amp;gt;com.fasterxml.jackson.core&amp;lt;/groupId&amp;gt;
            &amp;lt;artifactId&amp;gt;jackson-databind&amp;lt;/artifactId&amp;gt;
            &amp;lt;version&amp;gt;2.12.3&amp;lt;/version&amp;gt;
        &amp;lt;/dependency&amp;gt;

        &amp;lt;dependency&amp;gt;
            &amp;lt;groupId&amp;gt;jakarta.json&amp;lt;/groupId&amp;gt;
            &amp;lt;artifactId&amp;gt;jakarta.json-api&amp;lt;/artifactId&amp;gt;
            &amp;lt;version&amp;gt;2.0.1&amp;lt;/version&amp;gt;
        &amp;lt;/dependency&amp;gt;

        &amp;lt;dependency&amp;gt;
            &amp;lt;groupId&amp;gt;com.h2database&amp;lt;/groupId&amp;gt;
            &amp;lt;artifactId&amp;gt;h2&amp;lt;/artifactId&amp;gt;
            &amp;lt;scope&amp;gt;runtime&amp;lt;/scope&amp;gt;
        &amp;lt;/dependency&amp;gt;
        &amp;lt;dependency&amp;gt;
            &amp;lt;groupId&amp;gt;mysql&amp;lt;/groupId&amp;gt;
            &amp;lt;artifactId&amp;gt;mysql-connector-java&amp;lt;/artifactId&amp;gt;
            &amp;lt;scope&amp;gt;runtime&amp;lt;/scope&amp;gt;
        &amp;lt;/dependency&amp;gt;
        &amp;lt;dependency&amp;gt;
            &amp;lt;groupId&amp;gt;org.springframework.boot&amp;lt;/groupId&amp;gt;
            &amp;lt;artifactId&amp;gt;spring-boot-starter-test&amp;lt;/artifactId&amp;gt;
            &amp;lt;scope&amp;gt;test&amp;lt;/scope&amp;gt;
        &amp;lt;/dependency&amp;gt;
    &amp;lt;/dependencies&amp;gt;

    &amp;lt;build&amp;gt;
        &amp;lt;plugins&amp;gt;
            &amp;lt;plugin&amp;gt;
                &amp;lt;groupId&amp;gt;org.springframework.boot&amp;lt;/groupId&amp;gt;
                &amp;lt;artifactId&amp;gt;spring-boot-maven-plugin&amp;lt;/artifactId&amp;gt;
            &amp;lt;/plugin&amp;gt;
        &amp;lt;/plugins&amp;gt;
    &amp;lt;/build&amp;gt;

&amp;lt;/project&amp;gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Then just install all dependencies and we are good to move forward.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;mvn install&lt;/code&gt; or &lt;code&gt;mvn package&lt;/code&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  MySQL
&lt;/h2&gt;

&lt;p&gt;Ok, now we need our database and some data. To fetch data we need to have/install mysql to local machine. To make it easier, we could install &lt;a href="https://www.mysql.com/products/workbench/" rel="noopener noreferrer"&gt;Workbench&lt;/a&gt;&lt;br&gt;
to get also GUI. We need to put information about database(username, password, database url) in &lt;em&gt;application.properties&lt;/em&gt; as well.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;spring.datasource.url={url_path}
spring.datasource.username={database_username}
spring.datasource.password={database_password}
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Now just type &lt;em&gt;Book&lt;/em&gt; model. I also added the annotations we need for our search engines.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/24akSucLOFwwoZamdr/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/24akSucLOFwwoZamdr/giphy.gif" alt="LetUsBegin"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;
  
  
  Important
&lt;/h4&gt;

&lt;p&gt;A table named &lt;em&gt;book&lt;/em&gt; should exist in your database and should include some data for test.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Entity
@Indexed
@Table(name = "book")
@Document(indexName = "books", type = "book")
public class Book {
    @Id
    private int id;

    @FullTextField
    @Field(type = FieldType.Text, name = "name")
    private String name;


    @FullTextField
    @Field(type = FieldType.Text, name = "isbn")
    private String isbn;

    public int getId() {
        return id;
    }

    public String getIsbn() {
        return isbn;
    }

    public String getName() {
        return name;
    }

    public void setIsbn(String isbn) {
        this.isbn = isbn;
    }

    public void setName(String name) {
        this.name = name;
    }
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Now to get response from request we need &lt;em&gt;Repository&lt;/em&gt; class.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public interface BookRepository extends PagingAndSortingRepository&amp;lt;Book, Integer&amp;gt;
{
    List&amp;lt;Book&amp;gt; findByName(String name);    
    List&amp;lt;Book&amp;gt; findByIsbn(String isbn);    
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;And now to get data from url we need a controller. I keep it very simple just to get response and check if data was loaded.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@RestController
@RequestMapping(value = "book")
public class BookController {    
    @Autowired
    BookRepository bookRepository;

    @GetMapping("/database")
    ResponseEntity&amp;lt;Iterable&amp;lt;Book&amp;gt;&amp;gt; getBooksFromDatabase(@RequestParam("query") String query)
    {
        Iterable&amp;lt;Book&amp;gt; booksFromDatabase = bookRepository.findByIsbn(query);

        return ResponseEntity.ok(booksFromDatabase);
    }
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Ok, it seems to be done with database. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fkvadccz2how6hzbopxh8.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fkvadccz2how6hzbopxh8.gif" alt="Easy"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Was not so hard, but this is not most flexible option to interact with a searching flow.&lt;/p&gt;

&lt;p&gt;Let´s take a look at the searching engines. We will start with very powerful technology in JAVA.&lt;/p&gt;
&lt;h2&gt;
  
  
  Hibernate
&lt;/h2&gt;

&lt;p&gt;First we need to create configuration file.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Component
public class BookIndexConfiguration implements CommandLineRunner
{
    @PersistenceContext
    EntityManager entityManager;

    @Override
    @Transactional(readOnly = true)
    public void run(String ...args) throws Exception
    {
        SearchSession searchSession = Search.session(entityManager);
        MassIndexer indexer = searchSession.massIndexer(Book.class);
        indexer.startAndWait();
    }
} 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Over here the &lt;em&gt;indexer&lt;/em&gt; from hibernate will create index with data from our model once the application was started. To explore books in index we also need &lt;em&gt;service&lt;/em&gt; class. Ok, let's create one.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Service
public class BookSearchService {
    @PersistenceContext
    EntityManager entityManager;

    @Transactional(readOnly = true)
    public Iterable&amp;lt;Book&amp;gt; search(Pageable pageable, String query)
    {
        SearchSession session = Search.session(entityManager);

        SearchResult&amp;lt;Book&amp;gt; result = session.search(Book.class)
            .where(
                    f -&amp;gt; f.match().
                    fields("name", "isbn").
                    matching(query)
                )
            .fetch((int) pageable.getOffset(), pageable.getPageSize())
        ;
        return result.hits();
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;We have &lt;em&gt;search&lt;/em&gt; function that loads a current session and checks in index, if the query matches to the &lt;em&gt;name&lt;/em&gt; or &lt;em&gt;isbn&lt;/em&gt;. If some objects were found, it will be returned as &lt;em&gt;Iterable&lt;/em&gt; of &lt;em&gt;Book&lt;/em&gt; objects&lt;/p&gt;

&lt;p&gt;And thats it! Was it even easier that typical database call?&lt;/p&gt;

&lt;p&gt;Now we need to configure a different search engine.&lt;/p&gt;
&lt;h2&gt;
  
  
  Elasticsearch
&lt;/h2&gt;

&lt;p&gt;Ok, now we need a little bit more configuration &lt;del&gt;or maybe not&lt;/del&gt;. Just like in the case with MySQL, we should install Elasticsearch. I will use &lt;a href="https://hub.docker.com/_/elasticsearch" rel="noopener noreferrer"&gt;Docker image&lt;/a&gt; to get the client. Alternatively you can use one of the methods under the following link &lt;a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/install-elasticsearch.html" rel="noopener noreferrer"&gt;Elasticsearch install&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;version: '3.7'

services:
  elasticsearch:
    image: docker.elastic.co/elasticsearch/elasticsearch:8.3.2
    container_name: elasticsearch
    environment:
      - xpack.security.enabled=false
      - discovery.type=single-node
    ports:
      - 9200:9200
      - 9300:9300
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;Important&lt;/strong&gt;&lt;br&gt;
For testing purposes I disabled the security mode. You should not do this if you deploy your application into the live system.&lt;/p&gt;

&lt;p&gt;After Elasticsearch has been installed and started, we can create one more configuration file with &lt;em&gt;Client&lt;/em&gt;.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public class BookElasticsearchClient {
    private ElasticsearchClient client;

    public ElasticsearchClient getClient()
    {
        if (client == null) {
            initClient();
        }

        return client;
    }

    private void initClient()
    {
        RestClient restClient = RestClient.builder(new HttpHost("localhost", 9200)).build();

        ElasticsearchTransport transport = new RestClientTransport(restClient, new JacksonJsonpMapper());

        client = new ElasticsearchClient(transport);
    }
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;If you use authentication with username and password, you need to configure these as well. The information on how to do this, is under the following link: &lt;a href="https://www.elastic.co/guide/en/elasticsearch/client/java-api-client/master/_basic_authentication.html" rel="noopener noreferrer"&gt;Authentication&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Aaaand now &lt;em&gt;service&lt;/em&gt; class for searching.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
@Configuration
public class BookElasticsearchService {
    BookElasticsearchClient client = new BookElasticsearchClient();

    private static final String BOOK_INDEX = "books";

    public void createBooksIndexBulk(final List&amp;lt;Book&amp;gt; books)
    {
        BulkRequest.Builder builder = new BulkRequest.Builder();

        for (Book book : books)
        {
            builder.operations(op -&amp;gt; op
                .index(index -&amp;gt; index
                    .index(BOOK_INDEX)
                    .id(String.valueOf(book.getId()))
                    .document(book)
                )
            );

            try {
                client.getClient().bulk(builder.build());
            } catch (ElasticsearchException exception) {
                exception.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public List&amp;lt;Book&amp;gt; findBookByIsbn(String query)
    {
        List&amp;lt;Book&amp;gt; books = new ArrayList&amp;lt;&amp;gt;();

        try {
            SearchResponse&amp;lt;Book&amp;gt; search = client.getClient().search(s -&amp;gt; s
                .index(BOOK_INDEX)
                .query(q -&amp;gt; q
                    .match(t -&amp;gt; t
                        .field("isbn")
                        .query(query))),
                Book.class);

            List&amp;lt;Hit&amp;lt;Book&amp;gt;&amp;gt; hits = search.hits().hits();
            for (Hit&amp;lt;Book&amp;gt; hit: hits) {
                books.add(hit.source());
            }

            return books;
        } catch (ElasticsearchException exception) {
            exception.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return null;
    }
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;These are two very important functions. One of them is to create an index and put data into a document, another one have been used to get information about book from &lt;em&gt;isbn&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;And last but not least, we need a repository class for Elasticsearch.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public interface BookElasticsearchRepository extends ElasticsearchRepository&amp;lt;Book, String&amp;gt; {}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;In the end we need to complete our controller to send requests.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@RestController
@RequestMapping(value = "book")
public class BookController {    
    @Autowired
    BookSearchService searchService;

    @Autowired
    BookRepository bookRepository;

    @Autowired
    BookElasticsearchService bookElasticsearchService;

    @GetMapping("/database")
    ResponseEntity&amp;lt;Iterable&amp;lt;Book&amp;gt;&amp;gt; getBooksFromDatabase(@RequestParam("query") String query)
    {
        Iterable&amp;lt;Book&amp;gt; booksFromDatabase = bookRepository.findByIsbn(query);

        return ResponseEntity.ok(booksFromDatabase);
    }

    @GetMapping("/hibernate")
    ResponseEntity&amp;lt;Iterable&amp;lt;Book&amp;gt;&amp;gt; getBooksFromHibernate(Pageable pageable, @RequestParam("query") String query)
    {
        Iterable&amp;lt;Book&amp;gt; booksFromHibernate = searchService.search(pageable, query);

        return ResponseEntity.ok(booksFromHibernate);
    }

    @GetMapping("/elasticsearch")
    ResponseEntity&amp;lt;Iterable&amp;lt;Book&amp;gt;&amp;gt; getBooksFromElasticsearch(@RequestParam("query") String query)
    {
        Iterable&amp;lt;Book&amp;gt; booksFromElasticSearch = bookElasticsearchService.findBookByIsbn(query);

        return ResponseEntity.ok(booksFromElasticSearch);
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;One more important thing before starting the application:&lt;br&gt;
we need to add the annotations(see below) in the main &lt;em&gt;ApplicationClass&lt;/em&gt;, to make it work with multiple search engine technologies in one application.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@EnableElasticsearchRepositories(basePackageClasses = BookElasticsearchRepository.class)
@EnableJpaRepositories(excludeFilters = @ComponentScan.Filter(
    type = FilterType.ASSIGNABLE_TYPE, value = BookElasticsearchRepository.class
))
@SpringBootApplication
public class SearchApplication {

    public static void main(String[] args) {
        SpringApplication.run(SearchApplication.class, args);
    }

}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Let´s test all the things together.&lt;/p&gt;

&lt;p&gt;I also had to create an index in my very first time. I called the function &lt;em&gt;createBooksIndexBulk&lt;/em&gt; from &lt;em&gt;BookElasticsearchService&lt;/em&gt;. There is also an option to call index directly in Elasticsearch console. How to do this is described here: &lt;a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-bulk.html" rel="noopener noreferrer"&gt;Bulk Api&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I send couple requests (in my database i have an &lt;em&gt;isbn=123test&lt;/em&gt;):&lt;/p&gt;

&lt;p&gt;&lt;code&gt;http://localhost:8080/book/hibernate?query=123test&lt;/code&gt; &lt;br&gt;
&lt;code&gt;http://localhost:8080/book/database?query=123test&lt;/code&gt; &lt;br&gt;
&lt;code&gt;http://localhost:8080/book/elasticsearch?query=123test&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;For each request I got a right response. Mission completed.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fstyyoo1x94fxws51yxp0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fstyyoo1x94fxws51yxp0.png" alt="MySQL"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2F5nln932qsf80gqfq9jxh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2F5nln932qsf80gqfq9jxh.png" alt="Hibernate"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fujvy0xukp1p74e3px5em.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fujvy0xukp1p74e3px5em.png" alt="Elasticsearch"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Flgcpbutytaqjmr0nb6io.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Flgcpbutytaqjmr0nb6io.gif" alt="ItsWorking"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Thanks a lot for reading. &lt;/p&gt;

&lt;p&gt;Additional resources that I used:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.elastic.co/guide/en/elasticsearch/client/java-api-client/current/index.html" rel="noopener noreferrer"&gt;JAVA Client for Elasticsearch&lt;/a&gt; &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://hibernate.org/search/" rel="noopener noreferrer"&gt;Hibernate Search&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can also check my Github to get the whole code&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/Yordaniss" rel="noopener noreferrer"&gt;
        Yordaniss
      &lt;/a&gt; / &lt;a href="https://github.com/Yordaniss/compare-search-engine" rel="noopener noreferrer"&gt;
        compare-search-engine
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Repository to compare search engines for java application
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;p&gt;&lt;strong&gt;Compare search engine for JAVA&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;This repository was created to test implementation of popular search engines with directly MySQL loading for JAVA Spring application.&lt;/p&gt;
&lt;p&gt;Sources for data loading:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Hibernate Search&lt;/li&gt;
&lt;li&gt;Elasticsearch&lt;/li&gt;
&lt;li&gt;MySQL&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;

  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/Yordaniss/compare-search-engine" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;



</description>
      <category>java</category>
      <category>elasticsearch</category>
      <category>mysql</category>
      <category>hibernate</category>
    </item>
    <item>
      <title>Github commit searcher</title>
      <dc:creator>Dmytro Werner</dc:creator>
      <pubDate>Sat, 27 Aug 2022 07:29:00 +0000</pubDate>
      <link>https://dev.to/york/commit-searcher-372b</link>
      <guid>https://dev.to/york/commit-searcher-372b</guid>
      <description>&lt;h3&gt;
  
  
  Overview of My Submission
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;What?&lt;/strong&gt; &lt;br&gt;
This is basic project to find messages in your commit history.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why?&lt;/strong&gt;&lt;br&gt;
I was thinking to create app to get information from my commits if i want to find some important message that was wrote before.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How?&lt;/strong&gt;&lt;br&gt;
To get information was used Github-API and to run Redis locally was used Docker.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Improvement ideas&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;use GitHub Actions to update information automatically&lt;/li&gt;
&lt;li&gt;save more dat and filter this data in frontend&lt;/li&gt;
&lt;li&gt;use advance caching from Redis to increase performance&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Submission Category:
&lt;/h3&gt;

&lt;p&gt;&lt;del&gt;MERN&lt;/del&gt;/RERN(Redis,Express,React,Node) Mavericks&lt;/p&gt;
&lt;h3&gt;
  
  
  Language Used
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;JavaScript&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Tech-Stack
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Redis to store data (database)&lt;/li&gt;
&lt;li&gt;Redis to search data (search engine)&lt;/li&gt;
&lt;li&gt;Node with express (backend)&lt;/li&gt;
&lt;li&gt;React (frontend)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Link to Code
&lt;/h3&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--566lAguM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/Yordaniss"&gt;
        Yordaniss
      &lt;/a&gt; / &lt;a href="https://github.com/Yordaniss/commit-searcher"&gt;
        commit-searcher
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;h1&gt;
Commit-Searcher&lt;/h1&gt;
&lt;p&gt;Small project to search commits from your repository.&lt;/p&gt;
&lt;h1&gt;
Example&lt;/h1&gt;
&lt;p&gt;&lt;a rel="noopener noreferrer" href="https://github.com/Yordaniss/commit-searcher/blob/master/example.png?raw=true"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--1xdq75Dh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://github.com/Yordaniss/commit-searcher/raw/master/example.png%3Fraw%3Dtrue" alt="alt text"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
How it works&lt;/h2&gt;
&lt;h3&gt;
How the data is stored:&lt;/h3&gt;
&lt;p&gt;After server was loaded data will be stored to Redis database from api endpoint.&lt;/p&gt;
&lt;p&gt;There are several steps to:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;create Schema like this:&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="snippet-clipboard-content notranslate position-relative overflow-auto"&gt;&lt;pre class="notranslate"&gt;&lt;code&gt;const commitSchema = new Schema(Commit, {

    message: { type: 'text' },

    author: { type: 'string' },

    url: { type: 'string' }

})
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;get data from your repository:&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="snippet-clipboard-content notranslate position-relative overflow-auto"&gt;&lt;pre class="notranslate"&gt;&lt;code&gt;const response = octokit.request('GET https://api.github.com/repos/{owner}/{repo}/commits', {

    owner: process.env.GITHUB_OWNER,

    repo: process.env.GITHUB_REPO

});
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;save data to Redis&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="snippet-clipboard-content notranslate position-relative overflow-auto"&gt;&lt;pre class="notranslate"&gt;&lt;code&gt;response.then(function(result) {

    result.data.map((commit) =&amp;gt; {

        saveDataToRedis(

            commit.commit.message,

            commit.commit.author.name,

            commit.html_url,

        )

    })

})
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;create index in Redis:&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="snippet-clipboard-content notranslate position-relative overflow-auto"&gt;&lt;pre class="notranslate"&gt;&lt;code&gt;await  commitRepository.createIndex()
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;
How the data is accessed:&lt;/h3&gt;
&lt;p&gt;Data will be loaded from server via endpoints to frontend. There you can see all commits and search for data.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Get all data (used &lt;strong&gt;search()&lt;/strong&gt; function from Redis repository)&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="snippet-clipboard-content notranslate position-relative overflow-auto"&gt;&lt;pre class="notranslate"&gt;&lt;code&gt;app.get('/commits', async (req, res) =&amp;gt; {

    const commits = await commitRepository.search().return.all();

    res.json(commits)

})
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ol start="2"&gt;
&lt;li&gt;Search messages…&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/Yordaniss/commit-searcher"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;Licence: MIT&lt;/p&gt;

&lt;h3&gt;
  
  
  Additional Resources / Info
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://docs.github.com/en/rest"&gt;Github-Api&lt;/a&gt;&lt;br&gt;
&lt;a href="https://hub.docker.com/_/redis"&gt;Docker-Image&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Collaborators
&lt;/h3&gt;

&lt;p&gt;Solo project&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Check out &lt;a href="https://redis.io/docs/stack/get-started/clients/#high-level-client-libraries"&gt;Redis OM&lt;/a&gt;, client libraries for working with Redis as a multi-model database.&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Use &lt;a href="https://redis.info/redisinsight"&gt;RedisInsight&lt;/a&gt; to visualize your data in Redis.&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Sign up for a &lt;a href="https://redis.info/try-free-dev-to"&gt;free Redis database&lt;/a&gt;.&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>redishackathon</category>
    </item>
  </channel>
</rss>
