<?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: Sourabh Kumar Dubey</title>
    <description>The latest articles on DEV Community by Sourabh Kumar Dubey (@ab_33).</description>
    <link>https://dev.to/ab_33</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4153118%2F32eb64a4-51a8-418b-b524-b76d1549730c.png</url>
      <title>DEV Community: Sourabh Kumar Dubey</title>
      <link>https://dev.to/ab_33</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ab_33"/>
    <language>en</language>
    <item>
      <title>BuildFolio: From Arduino Builds to Shareable Portfolios</title>
      <dc:creator>Sourabh Kumar Dubey</dc:creator>
      <pubDate>Sun, 04 Oct 2026 22:28:18 +0000</pubDate>
      <link>https://dev.to/ab_33/buildfolio-from-arduino-builds-to-shareable-portfolios-1h0j</link>
      <guid>https://dev.to/ab_33/buildfolio-from-arduino-builds-to-shareable-portfolios-1h0j</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/hacktoberfest-weekend-2026-10-01"&gt;Hacktoberfest Weekend Challenge: Build for a Friend&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

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

&lt;p&gt;&lt;strong&gt;BuildFolio&lt;/strong&gt; helps you build, track, understand and showcase technical projects.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Give BuildFolio your project information → AI understands it → it generates an editable portfolio → you publish it as a shareable link.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  The friend and the problem
&lt;/h3&gt;

&lt;p&gt;I built this for a friend who makes Arduino projects. Every project has code, wiring, photos and demo videos. When he tried to share his work, GitHub didn't fit: it's good for code, but awkward for showing a build with images and video. He needed a proper website for his projects, and building and maintaining one by hand for every project is slow.&lt;/p&gt;

&lt;h3&gt;
  
  
  What it does for him
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Project workspace:&lt;/strong&gt; he records each project's description, status, technologies, deadline, budget and links (GitHub, KiCad, Fusion 360, Arduino, docs, demo).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Task tracking:&lt;/strong&gt; tasks move through &lt;code&gt;Pending&lt;/code&gt;, &lt;code&gt;In Progress&lt;/code&gt; and &lt;code&gt;Completed&lt;/code&gt;, and overall progress is calculated automatically.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Components / BOM:&lt;/strong&gt; parts with quantity and unit price, with automatic totals, remaining budget and an over-budget warning.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AI-drafted portfolio:&lt;/strong&gt; a local model reads the project data and drafts these sections: Summary, Problem, Solution, Hardware, Software, Architecture, Challenges and Future Improvements.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Full editing:&lt;/strong&gt; he can edit any section, add, remove or reorder sections, and attach media URLs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Publish:&lt;/strong&gt; one toggle makes the portfolio public at a unique (or custom) slug. Anyone can open it without an account.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Design decisions I care about
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The tracker is the source of truth, and AI only reads it.&lt;/strong&gt; Generating a portfolio never changes the underlying project, task or component data.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Every AI-written fact is tagged&lt;/strong&gt; &lt;code&gt;confirmed&lt;/code&gt;, &lt;code&gt;inferred&lt;/code&gt; or &lt;code&gt;unknown&lt;/code&gt;, so the author knows what to verify before publishing.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The model never writes HTML.&lt;/strong&gt; It returns structured data and React handles all rendering.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Current limitation
&lt;/h3&gt;

&lt;p&gt;The AI works from &lt;strong&gt;text only&lt;/strong&gt;. It can't look at photos or videos, and media is attached as URLs rather than uploaded. For an Arduino builder, that's the biggest gap. I had limited time for this challenge, so I built the core pipeline first. The plan for closing the gap is in "What's Next".&lt;/p&gt;

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

&lt;p&gt;🎥 &lt;strong&gt;Demo video:&lt;/strong&gt; &lt;a href="https://drive.google.com/file/d/1J1rTq3zL7wLleuO3bpQsb5aTdoxqSgfs/view?usp=sharing" rel="noopener noreferrer"&gt;https://drive.google.com/file/d/1J1rTq3zL7wLleuO3bpQsb5aTdoxqSgfs/view?usp=sharing&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;🚀 &lt;strong&gt;Live app:&lt;/strong&gt; &lt;a href="https://projectpulse-1-mjqh.onrender.com" rel="noopener noreferrer"&gt;https://projectpulse-1-mjqh.onrender.com&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The live deployment has everything except AI generation: project workspace, tasks, components, portfolio editor and public portfolio pages. Ollama doesn't run on Render, so the generate endpoint returns a service-unavailable error there. The video shows generation running locally.&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://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/skd-33" rel="noopener noreferrer"&gt;
        skd-33
      &lt;/a&gt; / &lt;a href="https://github.com/skd-33/BuildFolio" rel="noopener noreferrer"&gt;
        BuildFolio
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      AI-powered workspace to build, track, understand, and showcase technical projects
    &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;BuildFolio&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;BuildFolio helps you build, track, understand, and showcase technical projects.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Give BuildFolio your project information → AI understands it → generates an editable portfolio → publish it as a shareable link.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href="https://projectpulse-1-mjqh.onrender.com" rel="nofollow noopener noreferrer"&gt;🚀 Live Demo&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;div class="markdown-alert markdown-alert-important"&gt;
&lt;p class="markdown-alert-title"&gt;Important&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;AI portfolio generation runs locally using Ollama.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The public Render deployment provides the full application — project workspace, task tracking, component management, portfolio editor, and public portfolio experience — but Ollama is &lt;strong&gt;not&lt;/strong&gt; running on Render.&lt;/p&gt;
&lt;p&gt;To use the AI generation feature, run Ollama on the same machine as the BuildFolio backend and pull the model before starting. See &lt;a href="https://github.com/skd-33/BuildFolio#7-ai-setup" rel="noopener noreferrer"&gt;AI Setup&lt;/a&gt; for details.&lt;/p&gt;
&lt;/div&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Table of Contents&lt;/h2&gt;
&lt;/div&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href="https://github.com/skd-33/BuildFolio#1-overview" rel="noopener noreferrer"&gt;Overview&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/skd-33/BuildFolio#2-features" rel="noopener noreferrer"&gt;Features&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/skd-33/BuildFolio#3-how-it-works" rel="noopener noreferrer"&gt;How It Works&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/skd-33/BuildFolio#4-architecture" rel="noopener noreferrer"&gt;Architecture&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/skd-33/BuildFolio#5-tech-stack" rel="noopener noreferrer"&gt;Tech Stack&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/skd-33/BuildFolio#6-local-setup" rel="noopener noreferrer"&gt;Local Setup&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/skd-33/BuildFolio#7-ai-setup" rel="noopener noreferrer"&gt;AI Setup&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/skd-33/BuildFolio#8-using-buildfolio" rel="noopener noreferrer"&gt;Using BuildFolio&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/skd-33/BuildFolio#9-project-structure" rel="noopener noreferrer"&gt;Project Structure&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/skd-33/BuildFolio#10-deployment" rel="noopener noreferrer"&gt;Deployment&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/skd-33/BuildFolio#11-testing" rel="noopener noreferrer"&gt;Testing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/skd-33/BuildFolio#12-contributing" rel="noopener noreferrer"&gt;Contributing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/skd-33/BuildFolio#13-future-ideas" rel="noopener noreferrer"&gt;Future Ideas&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/skd-33/BuildFolio#14-license" rel="noopener noreferrer"&gt;License&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;1. Overview&lt;/h2&gt;
&lt;/div&gt;
&lt;p&gt;BuildFolio combines four things that engineers typically manage in separate tools:&lt;/p&gt;
&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Layer&lt;/th&gt;
&lt;th&gt;What it does&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Project tracker&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Source of truth for your actual engineering&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&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/skd-33/BuildFolio" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;Quick start (details in the README):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# backend (from repo root, after creating a venv and installing requirements)&lt;/span&gt;
&lt;span class="nv"&gt;AI_PROVIDER&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;ollama &lt;span class="nv"&gt;AI_MODEL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;gemma3:1b python &lt;span class="nt"&gt;-m&lt;/span&gt; uvicorn backend.main:app &lt;span class="nt"&gt;--reload&lt;/span&gt; &lt;span class="nt"&gt;--port&lt;/span&gt; 8000

&lt;span class="c"&gt;# frontend&lt;/span&gt;
&lt;span class="nb"&gt;cd &lt;/span&gt;frontend &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; npm run dev

&lt;span class="c"&gt;# model&lt;/span&gt;
ollama pull gemma3:1b
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  How I Built It
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Stack
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Layer&lt;/th&gt;
&lt;th&gt;Technology&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Frontend&lt;/td&gt;
&lt;td&gt;React 19, Vite, React Router v7, Lucide icons&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Backend&lt;/td&gt;
&lt;td&gt;FastAPI (Python), SQLAlchemy 2, Pydantic v2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Auth&lt;/td&gt;
&lt;td&gt;JWT in &lt;code&gt;httpOnly&lt;/code&gt; cookies&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Database&lt;/td&gt;
&lt;td&gt;SQLite locally, PostgreSQL in production&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AI runtime&lt;/td&gt;
&lt;td&gt;Ollama&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Open model&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;gemma3:1b&lt;/code&gt; (configurable via &lt;code&gt;AI_MODEL&lt;/code&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Hosting&lt;/td&gt;
&lt;td&gt;Render&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  The AI pipeline
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Project data (description, tasks, components, notes)
   ↓  FastAPI assembles a context string
AI service → provider abstraction → Ollama (localhost:11434)
   ↓  gemma3:1b
Structured JSON (ProjectKnowledge)
   ↓  validated by Pydantic
Portfolio sections saved to the database
   ↓  user edits and publishes
Public portfolio page at a shareable URL
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Making a small model dependable
&lt;/h3&gt;

&lt;p&gt;A 1B model doesn't always follow instructions, so the pipeline doesn't trust it blindly:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Schema-constrained output:&lt;/strong&gt; the model must return JSON matching a &lt;code&gt;ProjectKnowledge&lt;/code&gt; schema, which Pydantic validates.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Retries:&lt;/strong&gt; invalid or empty output is retried up to 3 times.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Confidence tagging:&lt;/strong&gt; each fact is marked &lt;code&gt;confirmed&lt;/code&gt;, &lt;code&gt;inferred&lt;/code&gt; or &lt;code&gt;unknown&lt;/code&gt;, so weak output is visible, not hidden.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Human in the loop:&lt;/strong&gt; the result is a draft the user reviews and edits before anything is published.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Provider abstraction
&lt;/h3&gt;

&lt;p&gt;The inference layer lives in its own module (&lt;code&gt;backend/ai/providers.py&lt;/code&gt;). Ollama is the tested setup. The layer also accepts an OpenAI-compatible endpoint through &lt;code&gt;AI_BASE_URL&lt;/code&gt; and &lt;code&gt;AI_API_KEY&lt;/code&gt;, but I haven't tested that path.&lt;/p&gt;

&lt;h3&gt;
  
  
  Testing
&lt;/h3&gt;

&lt;p&gt;There's an end-to-end backend API test covering auth, projects, tasks and progress, components and costs, portfolio editing and publishing, sections and media, and unauthenticated public access. The frontend has a build check.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Does Open Innovation Matter?
&lt;/h2&gt;

&lt;p&gt;An open-weight model I can run myself gave me things a closed API wouldn't:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Local inference.&lt;/strong&gt; &lt;code&gt;gemma3:1b&lt;/code&gt; runs through Ollama on my own CPU-only machine, so project text is never sent to an external AI provider during generation. To be precise, the deployed app still stores projects on its own server and database. Only the AI step stays local.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No per-call cost.&lt;/strong&gt; I can regenerate drafts as often as I like, with no API key or billing. That matters for a student project and for a friend who just wants to try it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Control.&lt;/strong&gt; I can swap models with one env var and constrain the output to a schema I validate.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Room to grow.&lt;/strong&gt; Moving to a vision-capable open model for photos is a configuration and pipeline change, not a vendor decision.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;ul&gt;
&lt;li&gt;Direct image and video uploads&lt;/li&gt;
&lt;li&gt;A vision model that reads photos of hardware builds&lt;/li&gt;
&lt;li&gt;Pulling context straight from a GitHub repo or README&lt;/li&gt;
&lt;li&gt;Document ingestion for project docs&lt;/li&gt;
&lt;li&gt;Project-specific AI Q&amp;amp;A&lt;/li&gt;
&lt;li&gt;Themes and drag-and-drop section ordering&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Prize Categories
&lt;/h2&gt;

&lt;h3&gt;
  
  
  🟣 Best Use of Render
&lt;/h3&gt;

&lt;p&gt;BuildFolio's whole production stack runs on Render:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Frontend:&lt;/strong&gt; the React + Vite app is built and served as a static site.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Backend:&lt;/strong&gt; the FastAPI service runs as a Render web service.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Database:&lt;/strong&gt; production uses a managed PostgreSQL database through the &lt;code&gt;DATABASE_URL&lt;/code&gt; environment variable. Local development uses SQLite, so nothing changes in the code between the two.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Configuration:&lt;/strong&gt; &lt;code&gt;SECRET_KEY&lt;/code&gt;, &lt;code&gt;CORS_ORIGINS&lt;/code&gt; and &lt;code&gt;COOKIE_SECURE&lt;/code&gt; are set as Render environment variables, so auth cookies are HTTPS-only and the CORS allow-list is locked down.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Public sharing:&lt;/strong&gt; published portfolios are served from Render without login, which is what lets my friend send a link to anyone.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Live app: &lt;a href="https://projectpulse-1-mjqh.onrender.com" rel="noopener noreferrer"&gt;https://projectpulse-1-mjqh.onrender.com&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Render gave me a full-stack deployment with a database in one place, which mattered with a weekend deadline.&lt;/p&gt;

&lt;h3&gt;
  
  
  🔷 Best Use of Gemma
&lt;/h3&gt;

&lt;p&gt;Gemma is the model behind portfolio generation:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Model:&lt;/strong&gt; &lt;code&gt;gemma3:1b&lt;/code&gt;, run locally through Ollama and configured with &lt;code&gt;AI_MODEL&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Job:&lt;/strong&gt; it reads a project's description, tasks, components and notes, and returns a structured &lt;code&gt;ProjectKnowledge&lt;/code&gt; JSON object. The backend validates it and maps it to portfolio sections.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Making a 1B model dependable:&lt;/strong&gt; schema-validated output, up to 3 automatic retries on invalid or empty responses, and a &lt;code&gt;confirmed&lt;/code&gt; / &lt;code&gt;inferred&lt;/code&gt; / &lt;code&gt;unknown&lt;/code&gt; tag on every fact, so the author can see what to verify.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Why a small model:&lt;/strong&gt; it runs on my CPU-only machine with no API key and no per-call cost.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Gemma runs locally and is not part of the Render deployment. The demo video shows generation working end to end.&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>weekendchallenge</category>
      <category>hf26challenge</category>
    </item>
  </channel>
</rss>
