Skip to content

Repository files navigation

PulseNote — Full-Stack AI Meeting Notes App

Turn any lecture or meeting into clean notes and clear tasks in seconds.

A production-ready, zero-dependency full-stack web application built with Python (stdlib only) + SQLite. No Node.js, no npm, no external frameworks required — just Python 3.6+.


✨ Features

Frontend (Landing Page)

  • 🎨 Ultra-modern dark UI with 3D Three.js particle background + wireframe animations
  • 🖱️ Custom animated cursor with lag-behind ring effect
  • 📜 Scroll-reveal animations (fade, slide, scale)
  • 🔢 Animated stat counters (10K+, 98%, 30+)
  • 📣 Hero with floating 3D dashboard mockup
  • ✅ Problem/Solution, How It Works, Features (6 cards with mouse-tracking glow)
  • 🧪 Interactive Demo (paste transcript → AI-parsed summary + action items)
  • 💰 Pricing (3 tiers, monthly/yearly toggle)
  • 💬 Testimonials with 3D tilt effect
  • ❓ FAQ accordion
  • 📧 Early Access lead capture form (wired to real backend)
  • 📝 Legal pages: /privacy, /terms (realistic content)
  • 📬 Contact page (/contact) with real backend support ticket creation

Backend (Python stdlib only)

  • 🗄️ SQLite database (via db/pulsenote.db)
  • 🔒 Admin auth with session tokens (HttpOnly cookies + Bearer token)
  • ⚡ Rate limiting (in-memory, per-IP, per-endpoint)
  • 🐝 Honeypot bot protection on all public forms
  • 🔏 Input sanitization against injection attacks
  • 🔐 IP hashing (SHA-256, privacy-friendly)
  • 📊 Admin dashboard with real-time stats, charts, leads table, tickets

API Endpoints

Method Endpoint Auth Description
GET /api/health No Health check
POST /api/leads No Capture early access lead
POST /api/support No Create support ticket
POST /api/events No Track analytics events
POST /api/admin/login No Admin login
POST /api/admin/logout Yes Admin logout
GET /api/admin/stats Yes Dashboard stats
GET /api/admin/leads Yes Leads list (paginated)
GET /api/admin/leads/csv Yes Export leads as CSV
GET /api/admin/tickets Yes Support tickets list
PATCH /api/admin/tickets/:id Yes Update ticket status

Pages

Route Description
/ Landing page
/privacy Privacy policy
/terms Terms of service
/contact Contact form
/admin Admin dashboard (protected)
/admin/login Admin login

🚀 Quick Start

Prerequisites

  • Python 3.6+ (no other dependencies!)

1. Run Locally

cd pulsenote
python3 server.py

Open:

2. Configuration via Environment Variables

PORT=8080              # Default: 8000
SECRET_KEY=your-secret # For session token signing
ADMIN_USER=achraf     # Default: admin
ADMIN_PASS=achraf123456  # Default: PulseNote2024!

Example:

SECRET_KEY=super-secret-key-change-me ADMIN_PASS=MyS3cureP@ss python3 server.py

📁 Project Structure

pulsenote/
├── server.py              # Main server (all backend logic, ~750 lines)
├── db/
│   └── pulsenote.db       # SQLite database (auto-created)
├── templates/
│   ├── index.html         # Landing page (3D + scroll animations)
│   ├── admin_dashboard.html  # Admin dashboard
│   ├── admin_login.html   # Admin login
│   ├── contact.html       # Contact form page
│   ├── privacy.html       # Privacy policy
│   └── terms.html         # Terms of service
├── static/                # Static assets (CSS, images, etc.)
└── README.md

🗄️ Database Schema

-- Lead capture
CREATE TABLE leads (
  id         TEXT PRIMARY KEY,
  email      TEXT NOT NULL UNIQUE,
  name       TEXT,
  role       TEXT DEFAULT 'other',     -- student/team/freelancer/other
  source     TEXT DEFAULT 'unknown',   -- hero/cta/footer/demo/pricing
  ip_hash    TEXT,                     -- SHA-256 hash (privacy-safe)
  created_at TEXT NOT NULL
);

-- Support tickets
CREATE TABLE support_tickets (
  id         TEXT PRIMARY KEY,
  email      TEXT NOT NULL,
  subject    TEXT NOT NULL,
  message    TEXT NOT NULL,
  status     TEXT DEFAULT 'open',      -- open/closed
  created_at TEXT NOT NULL
);

-- Analytics events
CREATE TABLE events (
  id         TEXT PRIMARY KEY,
  type       TEXT NOT NULL,            -- page_view/cta_click/demo_used/etc.
  path       TEXT,
  metadata   TEXT,                     -- JSON blob
  ip_hash    TEXT,
  created_at TEXT NOT NULL
);

-- Admin sessions
CREATE TABLE admin_sessions (
  token      TEXT PRIMARY KEY,
  created_at TEXT NOT NULL,
  expires_at TEXT NOT NULL             -- 8-hour sessions
);

🔐 Security Features

  1. Rate Limiting — In-memory sliding window per IP:

    • /api/leads: 5 requests / 60s
    • /api/support: 3 requests / 60s
    • /api/events: 30 requests / 60s
  2. Honeypot — Hidden _hp field in all public forms; bots silently accepted but not stored

  3. IP Hashing — Raw IPs never stored; SHA-256 HMAC with secret key

  4. Input Sanitization — Strips <>"' characters, max-length enforced

  5. Constant-Time Comparison — Admin credentials compared with hmac.compare_digest

  6. HttpOnly Cookies — Session tokens set with HttpOnly; SameSite=Strict

  7. Admin Auth on all /api/admin/* routes — 401 if no valid session


🚢 Deployment

Option 1: Fly.io (Recommended)

# Install flyctl, then:
fly launch
fly secrets set SECRET_KEY=your-production-key ADMIN_PASS=StrongPassword123!
fly deploy

Option 2: Railway

# Connect GitHub repo, Railway auto-detects Python
# Set environment variables in Railway dashboard

Option 3: VPS (Ubuntu)

# Install and configure systemd service
sudo cp pulsenote.service /etc/systemd/system/
sudo systemctl enable pulsenote
sudo systemctl start pulsenote
# Then configure nginx as reverse proxy

Option 4: Docker

FROM python:3.11-slim
WORKDIR /app
COPY . .
EXPOSE 8000
CMD ["python3", "server.py"]
docker build -t pulsenote .
docker run -p 8000:8000 -e SECRET_KEY=secret -e ADMIN_PASS=pass pulsenote

🧪 Testing

# Test all endpoints
curl http://localhost:8000/api/health
curl -X POST http://localhost:8000/api/leads \
  -H "Content-Type: application/json" \
  -d '{"email":"test@example.com","role":"student","source":"hero"}'
curl -X POST http://localhost:8000/api/events \
  -H "Content-Type: application/json" \
  -d '{"type":"page_view","path":"/"}'

📧 Extending with Email (Optional)

To enable real email notifications, add to server.py:

import smtplib
from email.mime.text import MIMEText

SMTP_HOST = os.environ.get("SMTP_HOST", "")
SMTP_PORT = int(os.environ.get("SMTP_PORT", 587))
SMTP_USER = os.environ.get("SMTP_USER", "")
SMTP_PASS = os.environ.get("SMTP_PASS", "")
ADMIN_EMAIL = os.environ.get("ADMIN_EMAIL", "admin@pulsente.ai")

def send_email(to, subject, body):
    if not SMTP_HOST: return  # Skip if not configured
    msg = MIMEText(body, 'html')
    msg['Subject'] = subject
    msg['From'] = SMTP_USER
    msg['To'] = to
    with smtplib.SMTP(SMTP_HOST, SMTP_PORT) as s:
        s.starttls()
        s.login(SMTP_USER, SMTP_PASS)
        s.send_message(msg)

Works with Gmail, SendGrid, Resend SMTP, Mailgun, etc.


📊 Admin Dashboard

Access at http://localhost:8000/admin after logging in.

Features:

  • 📈 Real-time stats (total leads, 7-day growth, open tickets, demo uses)
  • 📊 Bar charts for daily leads and events (last 30 days)
  • 🎯 Top sources breakdown with progress bars
  • 👥 Role breakdown (student / team / freelancer / other)
  • 📋 Paginated leads table with search + filter by source
  • 🎫 Support tickets list with open/closed filtering
  • 🔄 Update ticket status (open ↔ closed)
  • 📥 Export all leads as CSV

📄 License

MIT License — free to use, modify, and deploy.

Built with ❤️ for students and teams worldwide.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages