Skip to content

nimish-23/openbuild

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 

History

26 Commits
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

OpenBuild - Flask Backend with Production AI Integration

A production-ready Flask backend demonstrating AI/LLM integration patterns, RESTful API design, and relational database architecture

Python Flask SQLAlchemy Ollama License


๐ŸŽฏ Project Overview

OpenBuild is a developer portfolio platform that allows users to document their project journeys through timeline-based updates. The platform demonstrates production-grade backend engineering with integrated AI capabilities for automated project summarization.

What makes this project stand out:

  • Production AI integration with proper error handling and fallback strategies
  • Modular Flask architecture using application factory pattern
  • Engineered data pipeline: Relational DB โ†’ Structured JSON โ†’ LLM prompt โ†’ Validated response
  • Complete backend implementation with authentication, authorization, and data management

Built to showcase: Backend development skills, AI integration understanding, production reliability patterns, and full-stack thinking.


โœจ Key Features

Backend Architecture

  • โœ… Flask Application Factory Pattern - Modular, testable application structure
  • โœ… Blueprint-Based Routing - Separated concerns across auth, projects, posts, and home modules
  • โœ… SQLAlchemy ORM - Normalized 3-table schema with proper relationships
  • โœ… Database Migrations - Version-controlled schema changes with Flask-Migrate (Alembic)
  • โœ… RESTful API Design - 14 endpoints across 4 blueprints

Authentication & Security

  • โœ… Session-Based Authentication - Flask-Login with user session management
  • โœ… Password Security - Bcrypt hashing with salt
  • โœ… CSRF Protection - Flask-WTF token validation on all forms
  • โœ… Authorization Checks - User-owned resource verification
  • โœ… SQL Injection Prevention - Parameterized queries via SQLAlchemy

AI Integration (The Differentiator)

  • โœ… Production Reliability Patterns - Timeout handling, fallback logic, response validation
  • โœ… Data Export Pipeline - Structured JSON serialization from relational database
  • โœ… Engineered Prompts - Context-aware, factual prompt templates (not generic "summarize this")
  • โœ… LLM as External Service - Treats Ollama API as unreliable dependency with proper error handling
  • โœ… Schema Versioning - JSON export format versioning (v1.2.0) for consistency

Full-Stack Implementation

  • โœ… Image Upload Handling - Pillow-based image processing with validation
  • โœ… Markdown Rendering - Rich text support for developer content
  • โœ… Infinite Scroll - HTMX-powered feed pagination
  • โœ… Server-Side Rendering - Jinja2 templates with custom filters

๐Ÿ— Architecture Highlights

System Architecture

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚   Browser   โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”˜
       โ”‚ HTTP Requests
       โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚         Flask Application               โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”    โ”‚
โ”‚  โ”‚      Blueprints Layer          โ”‚    โ”‚
โ”‚  โ”‚  โ€ข auth    โ€ข home              โ”‚    โ”‚
โ”‚  โ”‚  โ€ข project โ€ข post              โ”‚    โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜    โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”    โ”‚
โ”‚  โ”‚     Middleware Layer           โ”‚    โ”‚
โ”‚  โ”‚  โ€ข Flask-Login (auth)          โ”‚    โ”‚
โ”‚  โ”‚  โ€ข Flask-WTF (CSRF)            โ”‚    โ”‚
โ”‚  โ”‚  โ€ข Session Management          โ”‚    โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜    โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”    โ”‚
โ”‚  โ”‚    Business Logic Layer        โ”‚    โ”‚
โ”‚  โ”‚  โ€ข WTForms Validation          โ”‚    โ”‚
โ”‚  โ”‚  โ€ข File Upload Handler         โ”‚    โ”‚
โ”‚  โ”‚  โ€ข AI Summary Service          โ”‚โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  โ”‚  โ€ข Export Service              โ”‚    โ”‚      โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜    โ”‚      โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”    โ”‚      โ”‚
โ”‚  โ”‚      Data Layer (ORM)          โ”‚    โ”‚      โ”‚
โ”‚  โ”‚  โ€ข Users    โ€ข Projects         โ”‚    โ”‚      โ”‚
โ”‚  โ”‚  โ€ข Posts                       โ”‚    โ”‚      โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜    โ”‚      โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜      โ”‚
              โ”‚                                  โ”‚
              โ–ผ                                  โ–ผ
      โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”               โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
      โ”‚    SQLite    โ”‚               โ”‚  Ollama LLM API  โ”‚
      โ”‚   Database   โ”‚               โ”‚  (localhost:11434) โ”‚
      โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜               โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Request Flow (AI Summary Generation)

User Request
    โ”‚
    โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ 1. Export Project Data (Relational DB โ†’ JSON)      โ”‚
โ”‚    โ€ข Query Users, Projects, Posts tables           โ”‚
โ”‚    โ€ข Transform to structured schema (v1.2.0)       โ”‚
โ”‚    โ€ข Calculate metrics (duration, post types)      โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                  โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ 2. Generate Rule-Based Summary (Fallback)          โ”‚
โ”‚    โ€ข Deterministic summary from data               โ”‚
โ”‚    โ€ข Always available (no external dependency)     โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                  โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ 3. Engineer Factual Prompt                         โ”‚
โ”‚    โ€ข Include complete project context              โ”‚
โ”‚    โ€ข Structured instructions for LLM               โ”‚
โ”‚    โ€ข Prompt versioning for iteration               โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                  โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ 4. Call Ollama API (with reliability patterns)     โ”‚
โ”‚    โ€ข 60-second timeout                             โ”‚
โ”‚    โ€ข Connection error handling                     โ”‚
โ”‚    โ€ข HTTP error handling                           โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                  โ–ผ
          โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
          โ”‚  LLM Response โ”‚
          โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                  โ”‚
        โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
        โ”‚  Response Valid?   โ”‚
        โ”‚  (length โ‰ฅ 20)     โ”‚
        โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                  โ”‚
         โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
         โ”‚                 โ”‚
        Yes               No
         โ”‚                 โ”‚
         โ–ผ                 โ–ผ
   โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”      โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
   โ”‚ Use LLM  โ”‚      โ”‚   Use    โ”‚
   โ”‚ Response โ”‚      โ”‚ Fallback โ”‚
   โ””โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”˜      โ””โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”˜
        โ”‚                 โ”‚
        โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                 โ–ผ
        โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
        โ”‚ Save to Database โ”‚
        โ”‚ (projects table) โ”‚
        โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                 โ–ผ
        โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
        โ”‚ Display to User  โ”‚
        โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

๐Ÿ›  Tech Stack

Backend Framework

  • Flask 3.0.3 - Lightweight WSGI web application framework
  • SQLAlchemy 3.1.1 - Python SQL toolkit and ORM
  • Flask-Migrate 4.0.7 - Database migration handling (Alembic wrapper)
  • Flask-Login 0.6.3 - User session management
  • Flask-Bcrypt 1.0.1 - Password hashing (Bcrypt algorithm)
  • Flask-WTF 1.2.1 - Form handling and CSRF protection

AI/LLM Integration

  • Ollama - Local LLM server (llama3.2 model)
  • Requests 2.32.3 - HTTP client for API communication
  • Custom prompt engineering module
  • JSON-based data export pipeline

Frontend & Rendering

  • Jinja2 - Server-side templating engine
  • HTMX - Dynamic content loading (infinite scroll)
  • Markdown 3.10 - Markdown to HTML rendering
  • Vanilla CSS - Custom styling (no framework dependencies)

Media Processing

  • Pillow 10.4.0 - Image processing and validation
  • MoviePy 1.0.3 - Video processing (future feature)

Configuration & Utilities

  • Python-dotenv 1.0.1 - Environment variable management
  • Email-validator 2.2.0 - Email format validation

Database

  • SQLite (Development) - File-based relational database
  • PostgreSQL-ready - SQLAlchemy abstraction allows easy migration

๐Ÿ’พ Database Schema

Entity-Relationship Design

erDiagram
    Users ||--o{ Projects : owns
    Users ||--o{ Posts : authors
    Projects ||--o{ Posts : contains

    Users {
        int id PK
        string username UK
        string email UK
        string password_hash
        datetime created_at
    }

    Projects {
        int id PK
        int user_id FK
        string title
        text description
        string status "enum: ideation, in_progress, beta, launched"
        datetime start_date
        datetime created_at
        datetime updated_at
        string tech_stack "comma-separated"
        string repo_url
        text ai_summary "LLM-generated summary"
        string ai_summary_version "schema version"
        datetime ai_summary_generated_at
    }

    Posts {
        int id PK
        int user_id FK
        int project_id FK
        string title
        text content "markdown format"
        string post_type "enum: init, update, feature, fix, decision, learning, milestone"
        datetime created_at
        string image_file "filename in uploads/"
    }
Loading

Relationships & Constraints

Users โ†’ Projects (One-to-Many)

  • Cascade delete: Deleting a user removes all their projects
  • Foreign key: projects.user_id โ†’ users.id

Projects โ†’ Posts (One-to-Many)

  • Cascade delete: Deleting a project removes all its posts
  • Foreign key: posts.project_id โ†’ projects.id

Users โ†’ Posts (One-to-Many)

  • Foreign key for attribution: posts.user_id โ†’ users.id
  • Maintains author reference even if project changes

Enumerations

Project Status:

  • ideation - Idea/planning phase
  • in_progress - Active development
  • beta - Testing phase
  • launched - Production/live

Post Types:

  • init - Project initialization
  • update - General progress update
  • feature - New feature implementation
  • fix - Bug fix
  • decision - Architectural decision
  • learning - Lesson learned
  • milestone - Major achievement
  • reflection - Project reflection

๐Ÿค– AI Integration Architecture

The Problem

How do you integrate LLMs into production backends when they're unreliable external services?

LLMs introduce unique challenges:

  • Unpredictable response times (can exceed 30+ seconds)
  • Non-deterministic outputs
  • API failures (connection, timeout, rate limits)
  • Cost considerations (API vs. local hosting)

The Solution: Production Reliability Patterns

1. Data Pipeline Design

Transform relational data into LLM-consumable format:

# export.py - Data Export Pipeline
def export_project_data(project_id):
    """
    Export structured project data from relational database.
    Schema versioning ensures prompt consistency.
    """
    project = Projects.query.get(project_id)
    posts = Posts.query.filter_by(project_id=project.id).all()

    # Schema v1.2.0 - Versioned for prompt evolution
    return {
        'schema_version': '1.2.0',
        'enums': {'post_types': POST_TYPES},
        'meta': {
            'id': project.id,
            'title': project.title,
            'tech_stack': [t.strip() for t in project.tech_stack.split(",")],
            'status': project.status,
            'start_date': project.start_date.isoformat(),
            # ... metadata
        },
        'journey': {
            'total_steps': len(posts),
            'logs': [
                {
                    'step': i + 1,
                    'title': post.title,
                    'content': post.content,
                    'post_type': post.post_type,
                    'post_intent': infer_journey_intent(post.post_type, i+1),
                    'created_at': post.created_at.isoformat()
                }
                for i, post in enumerate(posts)
            ]
        }
    }

Why this matters:

  • โœ… Structured, consistent input for LLM
  • โœ… Complete project context in one payload
  • โœ… Schema versioning allows prompt iteration
  • โœ… Decouples database from AI service

2. Prompt Engineering

Factual, structured prompts with full context:

# app/ai/prompt.py
def build_summary_prompt(project_json, rule_based_summary):
    """
    Engineer prompts with explicit constraints.
    Includes rule-based summary as ground truth.
    """
    return f"""
You are a technical writing assistant for developers.

Your task:
Rewrite the provided project summary into a clear, concise,
recruiter-friendly paragraph suitable for a portfolio.

Strict rules:
- Do NOT add new information.
- Do NOT invent features or outcomes.
- Do NOT change technical facts.
- Do NOT use marketing language.

Post-type awareness:
- Use `post_type` to adjust tone (milestone vs update).

Technology usage requirement:
- When technologies are mentioned, briefly state their use.
- Each technology should have a concise, functional purpose.

Input context:
Project data (structured):
{project_json}

Rule-based summary (ground truth):
{rule_based_summary}

Output requirements:
- 1 short paragraph (2 max if necessary)
- No bullet points, emojis, or filler
- Focus on clarity and real development work

Return ONLY the rewritten summary text.
"""

Why this matters:

  • โœ… Constrains LLM behavior with explicit rules
  • โœ… Provides "ground truth" fallback as reference
  • โœ… Prevents hallucination by limiting creative freedom
  • โœ… Versioned prompts enable A/B testing

3. Reliability Patterns

Never trust external services - always have a fallback:

# app/ai/summary.py
def generate_ai_summary(project_json):
    """
    Try LLM API, fallback to rule-based summary on any failure.
    This ensures the feature always works, even if AI fails.
    """
    # 1. Generate deterministic fallback (no external dependencies)
    rule_based_summary = generate_rule_based_fallback(project_json)

    # 2. Try LLM with comprehensive error handling
    try:
        prompt = build_summary_prompt(project_json, rule_based_summary)

        # 3. Call with timeout (LLMs can hang)
        ai_output = run_llm(prompt)

        # 4. Validate response quality
        if not ai_output or len(ai_output.strip()) < 20:
            print("[WARN] LLM response too short, using fallback")
            return rule_based_summary

        return ai_output.strip()

    except ConnectionError as e:
        print(f"[ERROR] Ollama server not reachable: {e}")
        return rule_based_summary

    except TimeoutError as e:
        print(f"[ERROR] LLM request timed out: {e}")
        return rule_based_summary

    except Exception as e:
        print(f"[ERROR] Unexpected AI error: {e}")
        return rule_based_summary


# app/ai/llm.py
def run_llm(prompt: str) -> str:
    """
    Call Ollama LLM API with proper timeout and error handling.
    Raises specific exceptions for different failure modes.
    """
    try:
        response = requests.post(
            OLLAMA_URL,  # http://localhost:11434/api/generate
            json={
                "model": MODEL_NAME,  # llama3.2
                "prompt": prompt,
                "stream": False
            },
            timeout=60  # Hard timeout to prevent hanging
        )

        response.raise_for_status()  # Raise HTTPError for 4xx/5xx

        data = response.json()
        if "response" not in data:
            raise ValueError("Invalid response format")

        return data["response"]

    except requests.exceptions.ConnectionError as e:
        raise ConnectionError(f"Ollama server not reachable: {e}")

    except requests.exceptions.Timeout as e:
        raise TimeoutError(f"LLM request timeout: {e}")

    except requests.exceptions.HTTPError as e:
        raise

Why this matters:

  • โœ… Graceful degradation - Feature works even if AI fails
  • โœ… Timeout protection - Prevents hanging requests
  • โœ… Specific error handling - Different failures handled differently
  • โœ… Logging - Failures are visible for monitoring
  • โœ… Always returns a result - Never breaks user experience

4. System Integration

AI as a feature, not the core product:

# app/routes/project.py
@project_bp.route('/project/<int:project_id>/ai-summary/generate', methods=['POST'])
@login_required
def ai_summary_generate_ready(project_id):
    """
    AI summary is an optional feature, not a requirement.
    Project functionality works without it.
    """
    project = Projects.query.get_or_404(project_id)

    # Authorization check
    if project.user_id != current_user.id:
        abort(403)

    try:
        # Export data (works independently of AI)
        project_data = export_project_data(project_id)

        # Generate summary (always succeeds due to fallback)
        summary = generate_ai_summary(project_data)

        # Save to database
        project.ai_summary = summary
        project.ai_summary_version = "1.2.0"
        project.ai_summary_generated_at = datetime.now(timezone.utc)
        db.session.commit()

        flash("AI summary generated successfully!", "success")

    except Exception as e:
        # Even if everything fails, user gets feedback
        flash(f"Could not generate summary: {str(e)}", "danger")

    return redirect(url_for('project.ai_summary', project_id=project_id))

Production Considerations

Current Implementation:

  • โœ… Local LLM (Ollama) - Zero API costs
  • โœ… Synchronous processing - Simple, predictable
  • โœ… Manual trigger - User-initiated
  • โœ… Versioned outputs - Stored in database with metadata

What I'd do differently at scale:

  1. Async Processing

    • Move LLM calls to background jobs (Celery/RQ)
    • Add job status tracking (pending/processing/complete)
    • Implement webhook notifications
  2. Caching Strategy

    • Cache summaries by project hash (detect changes)
    • Invalidate on new posts
    • Reduce redundant LLM calls
  3. Cost Optimization

    • Monitor token usage
    • Implement rate limiting per user
    • Add cost budget tracking
  4. Monitoring & Observability

    • Track LLM response times
    • Log failure rates
    • Alert on degraded performance
  5. A/B Testing

    • Test prompt variations
    • Measure summary quality (user feedback)
    • Iterate on prompt engineering

๐Ÿ“ Project Structure

openbuild/
โ”‚
โ”œโ”€โ”€ app/                          # Main application package
โ”‚   โ”œโ”€โ”€ __init__.py              # Flask app factory (create_app)
โ”‚   โ”œโ”€โ”€ models.py                # SQLAlchemy models (Users, Projects, Posts)
โ”‚   โ”œโ”€โ”€ form.py                  # WTForms definitions
โ”‚   โ”œโ”€โ”€ constants.py             # App-wide constants (enums, mappings)
โ”‚   โ”‚
โ”‚   โ”œโ”€โ”€ routes/                  # Blueprint modules
โ”‚   โ”‚   โ”œโ”€โ”€ auth.py             # Authentication (register, login, logout)
โ”‚   โ”‚   โ”œโ”€โ”€ home.py             # Home/feed (infinite scroll with HTMX)
โ”‚   โ”‚   โ”œโ”€โ”€ project.py          # Project CRUD + AI summary endpoints
โ”‚   โ”‚   โ””โ”€โ”€ post.py             # Post CRUD (updates, images)
โ”‚   โ”‚
โ”‚   โ”œโ”€โ”€ ai/                      # AI integration layer
โ”‚   โ”‚   โ”œโ”€โ”€ llm.py              # Ollama API client (timeout, error handling)
โ”‚   โ”‚   โ”œโ”€โ”€ prompt.py           # Prompt engineering templates
โ”‚   โ”‚   โ”œโ”€โ”€ summary.py          # AI summary generator (LLM + fallback)
โ”‚   โ”‚   โ””โ”€โ”€ ai_summary_service.py  # Service orchestration
โ”‚   โ”‚
โ”‚   โ”œโ”€โ”€ static/                  # Static assets
โ”‚   โ”‚   โ”œโ”€โ”€ css/                # Stylesheets
โ”‚   โ”‚   โ”‚   โ””โ”€โ”€ style.css       # Main CSS file
โ”‚   โ”‚   โ””โ”€โ”€ uploads/            # User-uploaded images (posts)
โ”‚   โ”‚
โ”‚   โ””โ”€โ”€ templates/               # Jinja2 templates
โ”‚       โ”œโ”€โ”€ base.html           # Base layout (nav, flash messages)
โ”‚       โ”œโ”€โ”€ home.html           # Landing page + community feed
โ”‚       โ”œโ”€โ”€ register.html       # User registration form
โ”‚       โ”œโ”€โ”€ login.html          # Login form
โ”‚       โ”œโ”€โ”€ projects.html       # User's project list
โ”‚       โ”œโ”€โ”€ project_detail.html # Project timeline (all posts)
โ”‚       โ”œโ”€โ”€ project_edit.html   # Edit project metadata
โ”‚       โ”œโ”€โ”€ post_new.html       # Create new post/update
โ”‚       โ”œโ”€โ”€ ai_summary.html     # AI summary display
โ”‚       โ””โ”€โ”€ partials/           # HTMX partials
โ”‚           โ””โ”€โ”€ _feed_items.html # Feed item template (infinite scroll)
โ”‚
โ”œโ”€โ”€ migrations/                  # Alembic database migrations
โ”‚   โ”œโ”€โ”€ alembic.ini             # Alembic configuration
โ”‚   โ”œโ”€โ”€ env.py                  # Migration environment
โ”‚   โ””โ”€โ”€ versions/               # Migration version scripts
โ”‚
โ”œโ”€โ”€ exports/                     # JSON export storage
โ”‚   โ””โ”€โ”€ project_*.json          # Exported project data for LLM
โ”‚
โ”œโ”€โ”€ instance/                    # Instance-specific files (gitignored)
โ”‚   โ””โ”€โ”€ app.db                  # SQLite database
โ”‚
โ”œโ”€โ”€ export.py                   # Standalone export utility (CLI)
โ”œโ”€โ”€ run.py                      # Application entry point
โ”œโ”€โ”€ requirements.txt            # Python dependencies
โ”œโ”€โ”€ .env                        # Environment variables (SECRET_KEY, DB_URL)
โ”œโ”€โ”€ .gitignore                  # Git ignore rules
โ”œโ”€โ”€ LICENSE                     # MIT License
โ””โ”€โ”€ README.md                   # This file

Key Files Explained:

File Purpose Lines of Code
app/__init__.py Flask app factory, blueprint registration ~60
app/models.py Database models (Users, Projects, Posts) ~90
app/routes/project.py Project CRUD + AI integration endpoints ~180
app/ai/llm.py Ollama API client with error handling ~50
app/ai/summary.py AI summary logic + fallback ~90
app/ai/prompt.py Prompt engineering templates ~60
export.py Data export pipeline (DB โ†’ JSON) ~125

๐Ÿ›ฃ API Routes

Authentication Routes

Method Endpoint Handler Auth Description
GET/POST /register auth.register() โŒ User registration with validation
GET/POST /login auth.login() โŒ Session-based login
GET /logout auth.logout() โœ… Session termination

Home Routes

Method Endpoint Handler Auth Description
GET / home.view_home() โŒ Landing page + community feed
GET /?page=N home.view_home() โŒ HTMX paginated feed (5 posts/page)

Project Routes

Method Endpoint Handler Auth Description
GET/POST /project/new project.new_project() โœ… Create new project
GET /project project.view_projects() โœ… List user's projects
GET /project/<id> project.project_details() โœ… View project timeline
GET/POST /project/<id>/edit project.project_edit() โœ… Edit project metadata
POST /project/<id>/delete project.project_delete() โœ… Delete project (cascade)
GET /project/<id>/ai-summary project.ai_summary() โœ… View AI-generated summary
POST /project/<id>/ai-summary/generate project.ai_summary_generate_ready() โœ… Trigger AI summary generation

Post Routes

Method Endpoint Handler Auth Description
GET/POST /project/<id>/post/new post.post_new() โœ… Create new post/update
GET/POST /post/<id>/edit post.post_edit() โœ… Edit existing post
POST /post/<id>/delete post.post_delete() โœ… Delete post

Total: 14 endpoints across 4 blueprints


๐Ÿš€ Setup & Installation

Prerequisites

Step 1: Clone Repository

git clone https://github.com/nimish-23/openbuild.git
cd openbuild

Step 2: Create Virtual Environment

# Windows
python -m venv env
env\Scripts\activate

# Linux/Mac
python3 -m venv env
source env/bin/activate

Step 3: Install Dependencies

pip install -r requirements.txt

Dependencies installed:

  • Flask ecosystem (Flask, SQLAlchemy, Migrate, Login, Bcrypt, WTF)
  • AI integration (requests for Ollama API)
  • Media processing (Pillow, MoviePy)
  • Utilities (python-dotenv, markdown, email-validator)

Step 4: Configure Environment Variables

Create a .env file in the project root:

SECRET_KEY=your-secret-key-here
DATABASE_URL=sqlite:///instance/app.db

Generate a secure secret key:

python -c "import secrets; print(secrets.token_hex(32))"

Step 5: Initialize Database

# Initialize migration repository (first time only)
flask db init

# Create initial migration
flask db migrate -m "Initial schema: Users, Projects, Posts"

# Apply migration to database
flask db upgrade

This creates the SQLite database at instance/app.db with all tables.

Step 6: Start Ollama (For AI Features)

Option 1: Local Installation

# Start Ollama server
ollama serve

# Pull llama3.2 model (in separate terminal)
ollama pull llama3.2

Option 2: Run Without AI The application works without Ollama - AI features will fall back to rule-based summaries.

Step 7: Run Application

python run.py

Application will start at: http://localhost:5000

Step 8: Create First User

  1. Navigate to http://localhost:5000/register
  2. Create an account
  3. Log in and start creating projects

๐Ÿ“Š Data Export (Optional)

Export project data to JSON for inspection or external processing:

# Export project with ID 1
python export.py 1

# Export saved to: exports/project_1.json

Export Format (Schema v1.2.0):

{
  "schema_version": "1.2.0",
  "enums": {
    "post_types": [
      "init",
      "update",
      "feature",
      "fix",
      "decision",
      "learning",
      "milestone"
    ]
  },
  "meta": {
    "id": 1,
    "title": "OpenBuild",
    "tech_stack": ["Python", "Flask", "SQLAlchemy", "Ollama"],
    "status": "in_progress",
    "start_date": "2026-01-01 00:00:00",
    "created_at": "2026-01-01 00:00:00"
  },
  "journey": {
    "total_steps": 5,
    "logs": [
      {
        "step": 1,
        "title": "Initial Setup",
        "content": "Set up Flask application with SQLAlchemy...",
        "post_type": "init",
        "post_intent": "foundation",
        "created_at": "2026-01-01T10:00:00"
      }
    ]
  }
}

๐Ÿญ Production Deployment Considerations

What Makes This Production-Ready?

โœ… Application Factory Pattern

  • Environment-based configuration
  • Testable architecture
  • Multiple instances supported

โœ… Database Migrations

  • Version-controlled schema changes
  • Rollback capability
  • Team collaboration support

โœ… Security Practices

  • Password hashing (Bcrypt)
  • CSRF protection
  • Session security
  • Input validation
  • SQL injection prevention (ORM)

โœ… Error Handling

  • Graceful AI service degradation
  • User-facing error messages
  • Logging for debugging

โœ… Modular Architecture

  • Blueprints for separation of concerns
  • Service layer for business logic
  • Easy to test and maintain

Production Deployment Checklist

Click to expand deployment guide

Environment Configuration:

  • Set strong SECRET_KEY (64+ characters)
  • Use PostgreSQL instead of SQLite
  • Set FLASK_ENV=production
  • Configure proper logging (file + monitoring)
  • Set up environment-specific .env files

Database:

  • Migrate to PostgreSQL/MySQL
  • Set up connection pooling
  • Configure automated backups
  • Set up read replicas (if scaling)

Web Server:

  • Deploy with Gunicorn (WSGI server)
  • Configure Nginx reverse proxy
  • Enable HTTPS (Let's Encrypt)
  • Set up static file serving (Nginx/CDN)

AI Service:

  • Host Ollama on separate server (resource intensive)
  • Configure Ollama service monitoring
  • Set up LLM request queuing
  • Implement rate limiting per user

Security:

  • Enable HTTPS only
  • Configure CORS policies
  • Set file upload limits
  • Implement rate limiting (Flask-Limiter)
  • Add security headers (helmet)

Monitoring & Logging:

  • Set up application logging (logging module)
  • Configure error tracking (Sentry)
  • Monitor AI service health
  • Track database performance
  • Set up uptime monitoring

Recommended Production Stack

Internet
    โ”‚
    โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚   Nginx     โ”‚ โ† SSL termination, static files, reverse proxy
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”˜
       โ”‚
       โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  Gunicorn   โ”‚ โ† WSGI server (4 workers)
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”˜
       โ”‚
       โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  Flask App  โ”‚ โ† Application
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”˜
       โ”‚
       โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
       โ”‚                    โ”‚
       โ–ผ                    โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”    โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ PostgreSQL  โ”‚    โ”‚   Ollama    โ”‚
โ”‚  Database   โ”‚    โ”‚ LLM Service โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜    โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Example Gunicorn Command:

gunicorn -w 4 -b 0.0.0.0:8000 --timeout 120 run:app

๐Ÿ”ฎ Future Enhancements

Planned Features

Based on what I'd build next to improve the platform:

Backend & Testing:

  • Unit Testing - pytest with fixtures for models, routes (targeting 80%+ coverage)
  • Integration Tests - Test AI pipeline end-to-end with mock LLM responses
  • API Documentation - Swagger/OpenAPI spec for all endpoints
  • Logging System - Structured logging with rotation for debugging and monitoring
  • Database Indexes - Add indexes on frequently queried fields (user_id, project_id, created_at)

AI/LLM Improvements:

  • Async Job Queue - Move AI generation to background with Celery + Redis (avoid blocking requests)
  • Summary Caching - Cache summaries by project content hash to reduce redundant LLM calls
  • Prompt Experiments - A/B test different prompt templates and measure quality
  • User Feedback Loop - Thumbs up/down on AI summaries to track improvement over time
  • Multiple Model Support - Allow switching between Ollama models (llama3.2, mistral, etc.)

Production Deployment:

  • PostgreSQL Migration - Move from SQLite to production-ready database
  • Docker Compose Setup - Containerize Flask app, database, and Ollama for easy deployment
  • GitHub Actions CI/CD - Automated testing and deployment pipeline
  • Rate Limiting - Prevent AI endpoint abuse (5 generations/hour per user)

User-Facing Features:

  • Public Project Pages - Share project timelines with recruiters via shareable link
  • GitHub Sync - Auto-create posts from commit messages (webhook integration)
  • Markdown Editor - Rich text editor with live preview for post content
  • Export to PDF - Generate portfolio-ready project documentation
  • Activity Analytics - Visualize posting frequency, project progress over time

๐Ÿค Contributing

Contributions are welcome! Please follow these guidelines:

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add amazing feature')
  4. Push to branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

Code Style:

  • Follow PEP 8 for Python code
  • Use type hints where applicable
  • Write docstrings for functions

๐Ÿ“„ License

This project is licensed under the MIT License - see the LICENSE file for details.


๐Ÿ‘จโ€๐Ÿ’ป Author

Nimish
GitHub: @nimish-23


๐Ÿ™ Acknowledgments

  • Flask Community - Excellent documentation and ecosystem
  • Ollama Team - Making local LLM deployment accessible
  • Meta AI - Llama model development
  • SQLAlchemy - Powerful and flexible ORM

Built to demonstrate production-ready backend engineering with AI integration

A portfolio project showcasing Flask, SQLAlchemy, AI/LLM integration, and production reliability patterns

About

"A platform for developers to build in public, share their coding journey, and grow together"

Resources

License

Stars

1 star

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors