DEV Community

Sourabh Kumar Dubey
Sourabh Kumar Dubey

Posted on

BuildFolio: From Arduino Builds to Shareable Portfolios

Hacktoberfest Weekend Challenge: Build for a Friend Submission 🤝

This is a submission for the Hacktoberfest Weekend Challenge: Build for a Friend

What I Built

BuildFolio helps you build, track, understand and showcase technical projects.

Give BuildFolio your project information → AI understands it → it generates an editable portfolio → you publish it as a shareable link.

The friend and the problem

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.

What it does for him

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

Design decisions I care about

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

Current limitation

The AI works from text only. 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".

Demo

🎥 Demo video: https://drive.google.com/file/d/1J1rTq3zL7wLleuO3bpQsb5aTdoxqSgfs/view?usp=sharing

🚀 Live app: https://projectpulse-1-mjqh.onrender.com

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.

Code

GitHub logo skd-33 / BuildFolio

AI-powered workspace to build, track, understand, and showcase technical projects

BuildFolio

BuildFolio helps you build, track, understand, and showcase technical projects.

Give BuildFolio your project information → AI understands it → generates an editable portfolio → publish it as a shareable link.

🚀 Live Demo

Important

AI portfolio generation runs locally using Ollama.

The public Render deployment provides the full application — project workspace, task tracking, component management, portfolio editor, and public portfolio experience — but Ollama is not running on Render.

To use the AI generation feature, run Ollama on the same machine as the BuildFolio backend and pull the model before starting. See AI Setup for details.


Table of Contents

  1. Overview
  2. Features
  3. How It Works
  4. Architecture
  5. Tech Stack
  6. Local Setup
  7. AI Setup
  8. Using BuildFolio
  9. Project Structure
  10. Deployment
  11. Testing
  12. Contributing
  13. Future Ideas
  14. License

1. Overview

BuildFolio combines four things that engineers typically manage in separate tools:

Layer What it does
Project tracker Source of truth for your actual engineering
…

Quick start (details in the README):

# backend (from repo root, after creating a venv and installing requirements)
AI_PROVIDER=ollama AI_MODEL=gemma3:1b python -m uvicorn backend.main:app --reload --port 8000

# frontend
cd frontend && npm install && npm run dev

# model
ollama pull gemma3:1b
Enter fullscreen mode Exit fullscreen mode

How I Built It

Stack

Layer Technology
Frontend React 19, Vite, React Router v7, Lucide icons
Backend FastAPI (Python), SQLAlchemy 2, Pydantic v2
Auth JWT in httpOnly cookies
Database SQLite locally, PostgreSQL in production
AI runtime Ollama
Open model gemma3:1b (configurable via AI_MODEL)
Hosting Render

The AI pipeline

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
Enter fullscreen mode Exit fullscreen mode

Making a small model dependable

A 1B model doesn't always follow instructions, so the pipeline doesn't trust it blindly:

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

Provider abstraction

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

Testing

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.

Why Does Open Innovation Matter?

An open-weight model I can run myself gave me things a closed API wouldn't:

  • Local inference. gemma3:1b 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.
  • No per-call cost. 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.
  • Control. I can swap models with one env var and constrain the output to a schema I validate.
  • Room to grow. Moving to a vision-capable open model for photos is a configuration and pipeline change, not a vendor decision.

What's Next

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

Prize Categories

🟣 Best Use of Render

BuildFolio's whole production stack runs on Render:

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

Live app: https://projectpulse-1-mjqh.onrender.com

Render gave me a full-stack deployment with a database in one place, which mattered with a weekend deadline.

🔷 Best Use of Gemma

Gemma is the model behind portfolio generation:

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

Gemma runs locally and is not part of the Render deployment. The demo video shows generation working end to end.

Top comments (0)