Skip to content

Repository files navigation

InsightPulse

InsightPulse is a Ruby on Rails portfolio project for an AI-assisted survey research platform. The goal is to build a small but credible internal tool where a project manager can create surveys, publish them, collect responses, and later generate LLM-based summaries from open-ended answers.

Current Status

The project currently includes:

  • Rails 8 app setup with PostgreSQL
  • built-in authentication flow
  • dashboard for signed-in users
  • survey CRUD
  • survey status handling for draft, published, and closed
  • nested question builder with multiple choice, scale, and text question types
  • AI-assisted question wording: an "Enhance with AI" button rewrites a rough draft question and suggests further improvements, backed by OpenAI with an automatic offline fallback (see "Question Enhancement" below)
  • public response flow without login
  • results dashboard with per-question summaries
  • CSV export of survey responses (see "Export CSV" on the survey show page)
  • AI-generated report summaries, backed by Anthropic's API with an automatic offline fallback (see "AI Summary Provider" below), generated asynchronously with a live-updating UI (no manual refresh needed — see "Async AI Report Generation" below)
  • seed data for local demoing

Local Setup

Requirements:

  • Ruby 3.3.11
  • PostgreSQL 16
  • Bundler

Start PostgreSQL if it is not already running:

brew services start postgresql@16

Install gems:

bundle install

Prepare the database:

bin/rails db:create db:migrate db:seed

Copy the env template and fill in whichever AI provider keys you have (both are optional — see below):

cp .env.example .env

Start the app:

bin/dev

Then open http://localhost:3000.

How local secrets are loaded

Local secrets live in a gitignored .env file, loaded automatically by the dotenv-rails gem (development and test only — never in production, which should get real env vars from the hosting platform). .env.example is the committed, secret-free template.

.env.test is also committed on purpose: it blanks out both AI provider keys for the test environment specifically, so the test suite always exercises the deterministic heuristic fallbacks and never makes a real, billed API call — regardless of what's in a developer's local .env.

AI Summary Provider

Survey open-text answers are summarized by AiReportGenerator, which tries a real LLM first and always has a working fallback:

  • If ANTHROPIC_API_KEY is set, reports are generated by Anthropic's Messages API (AiSummary::AnthropicProvider). The model defaults to claude-3-5-haiku-latest and can be overridden with ANTHROPIC_MODEL.
  • If the key is absent, or the API call fails for any reason, generation falls back to a deterministic local heuristic (AiSummary::HeuristicProvider) so the feature never breaks a demo.

Set ANTHROPIC_API_KEY in your local .env to enable it.

The generated AiReport#provider_model shows which provider actually produced a given report.

Async AI Report Generation

Clicking "Generate AI summary" no longer blocks the request on the LLM call. Instead:

  1. AiReportsController#create creates the AiReport immediately with status: pending (fast, no external call) and redirects right away — the page shows a "being generated" placeholder instantly.
  2. GenerateAiReportJob (run via Active Job, :async adapter in development — an in-process thread pool, no separate worker needed) does the slow part: it calls AiReportGenerator, which runs the LLM (or heuristic fallback) and updates the report to completed or failed.
  3. AiReport broadcasts that update over Turbo Streams (after_update_commit) to a channel scoped to the survey. The survey show page subscribes via turbo_stream_from @survey and replaces the #ai_summary section live — no polling, no manual refresh.

This is why the project now has a JS pipeline (importmap-rails + turbo-rails, app/javascript/application.js, config/importmap.rb) and an Action Cable route (mount ActionCable.server => "/cable" in config/routes.rb) — neither existed before; the Gemfile had the gems but the app was 100% server-rendered with zero client-side JS. Action Cable uses the async adapter locally (see config/cable.yml), so no Redis is required for local dev.

Question Enhancement

The "Enhance with AI" button on the question form (new/edit) rewrites a rough draft question into a clearer one, and suggests further improvements, via QuestionEnhancer:

  • If OPENAI_API_KEY is set, enhancement is done by OpenAI's Chat Completions API (QuestionEnhancement::OpenAiProvider). The model defaults to gpt-4o-mini and can be overridden with OPENAI_MODEL. Besides rewriting the question, it returns 1-3 short "Ideas to make it even better" suggestions (e.g. switching to multiple choice, adding a follow-up question) shown under the field.
  • If the key is absent, or the API call fails for any reason, it falls back to a deterministic local heuristic (QuestionEnhancement::HeuristicProvider) that just capitalizes the draft and ensures it ends with a question mark, with no suggestions (that needs a real LLM to be meaningful).

Set OPENAI_API_KEY in your local .env to enable it.

Note this is a separate provider/key from the AI Summary feature above — survey summaries still use Anthropic, question enhancement uses OpenAI. Both env vars can be set at once with no conflict.

Demo Login

  • Email: demo@example.com
  • Password: password123

Near-Term Build Plan

Done: CSV export of survey responses, AI question enhancement with suggestions, async/live-updating AI report generation.

The next slices are:

  1. a report history view for AiReport
  2. fix a pre-existing UX bug: when a multiple-choice question fails to save (no options given), the re-rendered form loses whatever the user typed in the options field
  3. additional product polish (empty states, publish/closed copy)

Project Structure

Core domain models:

  • User
  • Survey
  • Question
  • QuestionOption
  • ResponseSession
  • Answer
  • AiReport

Supporting planning docs:

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages