LaunchPad is an AI-powered business development and investor-matching platform built for MorganHacks 2026. It gives entrepreneurs a single workspace to build a business profile using conversational AI, generate branding, analyze their market, find investors, negotiate equity deals, and process payments — all without leaving the app.
- Features
- Tech Stack Overview
- In-Depth Tech Stack
- How It All Fits Together
- Project Structure
- Environment Variables
- Running Locally
- AI Business Advisor — Conversational chatbot that interviews you and fills in your business profile automatically. Supports PDF/DOCX business plan upload for field extraction. Advisory mode uses ElevenLabs TTS for voice responses.
- Profile Builder — 70+ field business profile across identity, financials, market, competition, marketing, operations, and goals. Inline autosave with completeness scoring.
- Branding Suite — AI logo generation (DALL-E), business name suggestions, and advertising tactic generation.
- Market Research — Market saturation analysis, competitor research, marketing tactic generation, product management.
- Planning Tools — SWOT analysis, 4-dimension risk scoring, prioritized action roadmap (pre-launch + growth phases), and AI-curated investment resource lists (grants, loans, VCs, accelerators).
- Equity Listings — Business owners set equity % and asking price; AI suggests a valuation range based on financials and sector multiples.
- Investor Discovery — Funders browse verified businesses with 7 filters (sector, stage, revenue band, size, geography, seeking funding, full-text search). Boosted profiles appear first.
- Sector Leaders — Composite-scored leaderboard (revenue 35%, completeness 20%, products 15%, funding 15%, stage 15%) per sector, with AI-generated market narratives. Cached 7 days.
- Negotiation System — Investors make offers (equity %, price); business owners accept, decline, or counter. Accepted offers flow into Stripe checkout.
- Payments — Stripe Checkout for equity investments and 7-day profile boosts. Solana Pay integration (experimental). Webhook handler marks investments as paid and records them.
- News Feed — Real-time sector news via NewsAPI, cached per business.
| Layer | Technology |
|---|---|
| Backend | Python 3.12, Flask 3.x |
| Database | MongoDB, MongoEngine ODM |
| AI (primary) | Google Gemini 2.0 Flash |
| AI (secondary) | Anthropic Claude (claude-sonnet-4-6) |
| AI (fallback) | HuggingFace Router (Qwen2.5-7B via Novita/Nscale/etc.) |
| Payments | Stripe Checkout, Solana Pay |
| TTS | ElevenLabs |
| Storage | AWS S3 / Backblaze B2 |
| Auth | Flask-Login (email + password) |
| Frontend | Jinja2, Tailwind CSS (CDN), Material Symbols |
| News | NewsAPI |
| Images | Unsplash API |
| Maps / Research | Google Places API |
Flask serves as the application framework. The app is organized into 10 blueprints, each owning a feature domain:
auth → Login, signup, logout, onboarding
businesses → Business CRUD, AI chatbot, news feed
branding → Logo gen, business naming, advertising
equity → Equity listing, AI valuation
funder → Investor dashboard, discover, investments, sector leaders
negotiation → Offer inbox, counter-offer, accept/decline
payments → Stripe/Solana checkout, webhook handler
planning → SWOT, risk, action items, investment resources
profile → User profile, socials, photo
research → Marketing, saturation, products, networking
Each blueprint maps a URL prefix (/funder, /planning, etc.) to a routes.py file. Business logic lives in app/services/ — routes are kept thin and delegate immediately to service functions.
Key Flask extensions used:
flask-mongoengine— MongoDB integrationflask-login— session management,@login_requireddecoratorflask-wtf/WTForms— CSRF protection on all formsAPScheduler— background jobs (weekly news refresh, monthly investment resource cache refresh)
MongoDB is used as a document store. MongoEngine provides a Django-ORM-style Python interface with schema enforcement at the application layer.
Core documents:
| Document | Purpose |
|---|---|
User |
Accounts for both entrepreneurs and investors. is_funder flag separates the two roles. is_verified controls visibility in investor discover. |
Business |
70+ field entrepreneur profile. Tracks a data_completeness_score (0–100) used for search ranking. Has a profile_dirty flag so risk/SWOT know when to suggest regeneration. |
BusinessSector |
43+ sectors seeded at startup (Tech, Healthcare, Agriculture, etc.). Used as references on Business and FunderProfile. |
FunderProfile |
Investor identity: org name, type (angel/vc/accelerator/bank/grant/other), sector interests, investment range, investment types offered. |
FunderInvestment |
Records a completed or in-progress investment: amount, equity %, type, status (active/exited/written_off/pending). |
FunderWatchlist |
M2M between FunderProfile and Business. |
Negotiation |
An offer from funder to business: equity %, offered price, counter price, status (pending → countered → accepted → paid / declined). |
SwotAnalysis |
Per-business SWOT with AI suggestion cache. |
RiskAnalysis |
4-dimension risk snapshot (competition, proximity, feasibility, ROI progress). Multiple per business, newest used. |
ActionItem |
Prioritized pre-launch and growth tasks, generated in batches. |
InvestmentResource |
AI-generated funding resources (grants, loans, VCs, etc.), cached 30 days per sector. |
SectorLeadersCache |
Top-10 scored businesses per sector + AI narrative. Cached 7 days. |
NetworkingProfile |
Controls whether a business is visible in the investor discover portal (is_visible flag). |
ChatbotConversation |
Per-business conversation history. Stores messages with extracted field metadata. |
Why MongoDB? Business profiles have a highly variable field set and the schema evolves quickly during a hackathon. MongoDB's flexible documents mean adding a new field doesn't require a migration.
All AI calls go through a single entry point: app/services/ai_client.py → call_ai(). This function tries providers in order and falls back automatically:
1. Google Gemini 2.0 Flash (primary — fast, cheap, 15 RPM free tier)
↓ rate limit / error
2. Anthropic Claude Sonnet (secondary — requires paid credits)
↓ error / disabled
3. HuggingFace Router (fallback — Qwen2.5-7B:cheapest via Novita/Nscale/etc.)
↓ all fail
RuntimeError propagates → flash "Generation failed"
Why this design?
A single cascade means no service has to know which AI provider is active. Any service calls call_ai(prompt, max_tokens=N, expect_json=True) and gets back a parsed Python dict/list. The cascade handles retries, rate limits, and JSON extraction from messy model outputs automatically.
JSON extraction (expect_json=True):
The function appends a strict JSON instruction to the prompt, then parses the raw response through _extract_json_object(). This function strips markdown code fences, and if json.loads fails, it scans forward to the first { or [ and uses json.JSONDecoder.raw_decode() to extract the first valid JSON object from models that prepend commentary.
Services that use AI:
| Service | What it generates |
|---|---|
chatbot_service.py |
Field values from conversation, strategic advice, document extraction |
planning_service.py |
SWOT suggestions, risk scores, action items, investment resources |
funder_service.py |
2-sentence sector narrative for Sector Leaders |
equity_service.py |
Valuation range (low/high + reasoning) |
naming_service.py |
Business name options |
business_autofill.py |
Full AI profile autofill from baseline data |
research_service.py |
Marketing tactics, saturation analysis |
Stripe Checkout handles two payment flows:
-
Equity investment — When a negotiation is accepted, the investor is redirected to a Stripe Checkout session priced at the agreed amount. On success, a webhook (
POST /payments/webhook) receivescheckout.session.completed, marks the negotiation aspaid, and records aFunderInvestment. -
Profile boost — A business can pay for a 7-day visibility boost. Boosted businesses appear first in the investor discover sort order (
-boosted_until, -data_completeness_score).
The webhook is CSRF-exempt and verified with stripe.Webhook.construct_event() using the STRIPE_WEBHOOK_SECRET.
Solana Pay routes exist as an experimental alternative payment path. A Solana reference is generated per negotiation and the client polls /payments/solana/.../poll until the on-chain transaction confirms.
| API | Where used |
|---|---|
| NewsAPI | news_service.py — fetches sector-relevant articles. Cached per business, refreshed weekly via APScheduler or on-demand. |
| Google Places API | research_service.py — competitor proximity and location research. |
| Unsplash API | image_client.py — stock photos for business profiles and branding previews. |
| ElevenLabs | chatbot_service.py — text-to-speech in chatbot "advisor mode". Converts AI responses to audio streamed back to the browser. |
| AWS S3 / Backblaze B2 | s3_client.py — file uploads (logos, profile photos, documents). S3_ENDPOINT_URL is blank for AWS; set it for Backblaze. |
Templates live in app/templates/ and use Jinja2 for server-side rendering. There is no SPA framework — pages are full HTML responses with small JavaScript enhancements.
Styling: Tailwind CSS loaded from CDN with a custom theme.extend config defining Material Design 3 color tokens (primary, on-primary, surface-container, outline-variant, etc.). This gives the UI a consistent Material-style design system.
Icons: Google Material Symbols font (outlined + filled variants via font-variation-settings).
JavaScript patterns used:
- Inline
fetch()calls for AJAX form saves (inline field save, chatbot messages, SWOT save, watchlist toggle) EventSource/ polling for the Solana payment status check- Local
selectRole()for the onboarding card UI
Here is the end-to-end flow for the two core user journeys:
Sign up (is_funder=false, is_verified=true)
→ Create business (is_public=true by default)
→ AI Chatbot interviews you → fills 70+ profile fields
→ Upload business plan PDF → extract fields automatically
→ Run Planning tools: SWOT → Risk → Action Items → Investment Resources
→ Browse AI-generated funding resources (grants, VCs, accelerators)
→ Set equity listing (% + price, AI suggests valuation range)
→ Receive offers in Negotiation Inbox
→ Accept / counter offer
→ Investor completes Stripe checkout → FunderInvestment recorded
Sign up (is_funder=true)
→ Complete Investor Profile (type, sectors, investment range)
→ Discover Businesses (7 filters, boosted profiles first)
→ View business profile → Add to Watchlist
→ Make Offer (equity %, price)
→ Business owner responds (accept / counter / decline)
→ On accept → Stripe Checkout → investment marked paid
→ Track portfolio in Investments dashboard
→ Explore Sector Leaders leaderboard with AI market narrative
Browser POST /planning/investment/generate
→ investment_generate() route
→ generate_investment_resources(biz)
→ call_ai(prompt, max_tokens=3000, expect_json=True)
→ _call_gemini() ← rate limited → retry 1x → fail
→ _call_anthropic() ← no credits → fail
→ _call_backup_llm() ← HuggingFace Router → Qwen2.5-7B → success
→ parse JSON array of 8 resource dicts
→ save each as InvestmentResource(business, sector, ...)
→ return list
→ flash "Found 8 funding resources"
→ redirect GET /planning/investment → render resources grid
app/
├── blueprints/
│ ├── auth/ Login, signup, logout, onboarding
│ ├── businesses/ Business CRUD, AI chatbot, news
│ ├── branding/ Logo gen, naming, advertising
│ ├── equity/ Equity listing + AI valuation
│ ├── funder/ Investor dashboard, discover, investments, sector leaders
│ ├── negotiation/ Offer inbox, counter-offer, accept/decline
│ ├── payments/ Stripe/Solana checkout, webhook handler
│ ├── planning/ SWOT, risk, action items, investment resources
│ ├── profile/ User profile, socials, photo
│ └── research/ Marketing, saturation, products, networking
├── models/ MongoEngine documents (13 total)
├── services/ Business logic — AI, payments, chatbot, equity, etc.
├── static/ CSS, JS, images, logos
├── templates/ Jinja2 HTML templates (40+)
├── config.py Environment-driven configuration
├── extensions.py Flask extension instances
└── helpers.py Auth decorators, shared utilities
manage.py CLI admin commands (verify-user, seed-sectors, etc.)
run.py App entry point
seed.py Demo data seeder
SECRET_KEY=
MONGO_URI=mongodb://localhost:27017/launchpad_db
# AI — primary
GEMINI_API_KEY=
GEMINI_MODEL=gemini-2.0-flash
# AI — secondary (optional, requires paid credits)
ANTHROPIC_ENABLED=false
ANTHROPIC_API_KEY=
# AI — fallback via HuggingFace Router
# Token: https://huggingface.co/settings/tokens (Read scope)
# Enable providers at: https://huggingface.co/settings/inference-providers
HUGGINGFACE_API_KEY=
AI_FALLBACK_ENABLED=true
BACKUP_AI_PROVIDER=huggingface
BACKUP_AI_BASE_URL=https://router.huggingface.co/v1
BACKUP_AI_MODEL=Qwen/Qwen2.5-7B-Instruct:cheapest
BACKUP_AI_TIMEOUT_SECONDS=120
# TTS
ELEVENLABS_API_KEY=
ELEVENLABS_VOICE_ID=
# Payments
STRIPE_PUBLISHABLE_KEY=
STRIPE_SECRET_KEY=
STRIPE_WEBHOOK_SECRET=
# News / Maps / Images
NEWS_API_KEY=
GOOGLE_PLACES_API_KEY=
UNSPLASH_ACCESS_KEY=
# Storage
S3_BUCKET_NAME=launchpad-media
S3_REGION=us-east-1
S3_ACCESS_KEY=
S3_SECRET_KEY=
S3_ENDPOINT_URL= # blank for AWS; set for Backblaze B2
# Solana (experimental)
SOLANA_RPC_URL=https://api.mainnet-beta.solana.com
SOLANA_WALLET_ADDRESS=Never commit
.envto git.
# 1. Clone and set up environment
git clone <repo>
cd MorganHacks2026
python -m venv bbvenv
bbvenv\Scripts\activate # Windows
pip install -r requirements.txt
# 2. Start MongoDB
mongod --dbpath ./data
# 3. Configure environment
cp .env.example .env
# Fill in at minimum: SECRET_KEY, MONGO_URI, GEMINI_API_KEY or HUGGINGFACE_API_KEY
# 4. Seed sectors (run once)
python manage.py seed-sectors
# 5. Run the app
flask run
# 6. (Optional) Forward Stripe webhooks for local payment testing
stripe listen --forward-to localhost:5000/payments/webhookAdmin commands:
python manage.py verify-user --email user@example.com # Verify a business owner
python manage.py seed-sectors # Seed all 43 business sectors