Skip to content
ejackson-vpPublic

About

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

Doc Q&A

An AI-powered document analysis system that transforms your documents into an intelligent Q&A interface. Upload PDFs, contracts, papers, and more, then ask questions to get instant AI-powered answers. Built with Next.js 15, TypeScript, and Material UI, integrated with Voltage Park AI Factory.

Next.js React TypeScript Material UI

Features

  • 📄 Document Upload - Support for PDF, DOC, DOCX, and TXT files
  • 🤖 AI-Powered Q&A - Ask questions and get intelligent answers from your documents
  • 🎨 Modern UI - Sleek Material UI design with dark/light mode and green accent colors
  • 📱 Fully Responsive - Optimized for all devices
  • ⚡ Real-time Processing - Live document indexing and vector embedding
  • 🔍 Semantic Search - Intelligent retrieval of relevant document chunks
  • 🌐 Unified Architecture - Single Next.js app with API routes and frontend
  • 📊 Multi-Document Collections - Organize documents into docsets for topic-specific Q&A

Quick Start

Prerequisites

Installation

# 1. Clone the repository
git clone <your-repo-url>
cd doc-qa

# 2. Install dependencies
npm install

# 3. Set up environment variables
cp .env.example .env.local
# Edit .env.local with your Voltage Park credentials

# 4. Run the development server
npm run dev

# 5. Open http://localhost:3000

Environment Variables

Create a .env.local file in the root directory:

DOCSETS_API_URL=https://060de239.voltagepark.studio
DOCSETS_BEARER_TOKEN=your-bearer-token

# Optional: Concurrency control (defaults shown)
MAX_CONCURRENT_INGESTIONS=3
MAX_CONCURRENT_GENERATIONS=5

Get your credentials from Voltage Park.

Concurrency Control

The application includes built-in concurrency limiting to prevent server overload:

  • MAX_CONCURRENT_INGESTIONS (default: 3) - Maximum number of simultaneous document uploads/processing
  • MAX_CONCURRENT_GENERATIONS (default: 5) - Maximum number of simultaneous answer generations

When limits are reached, requests are automatically queued and processed as capacity becomes available. This ensures fair processing without rejecting requests. Adjust these values based on your server capacity and Voltage Park API rate limits.

Usage

1. Create a Document Collection (Docset)

Give your collection a name and optional description:

  • "Research Papers"
  • "Legal Documents"
  • "User Manuals"

2. Upload Documents

Upload one or more documents (PDF, DOC, DOCX, TXT). The system will:

  • Extract text content
  • Chunk the document into semantic sections
  • Create vector embeddings for semantic search
  • Index for fast retrieval

3. Ask Questions

Ask natural language questions about your documents:

  • "What are the main findings?"
  • "Summarize the key points"
  • "What does section 3 say about...?"
  • "Explain the methodology used"

The AI will retrieve relevant context and generate comprehensive answers.

Technology Stack

Project Structure

doc-qa/
├── app/
│   ├── api/
│   │   ├── docsets/
│   │   │   ├── route.ts                    # POST - Create docset, GET - List docsets
│   │   │   └── [id]/
│   │   │       ├── route.ts                # GET - Get docset details
│   │   │       ├── ingest/route.ts         # POST - Upload document
│   │   │       └── generate/route.ts       # POST - Generate answer
│   │   └── health/route.ts                 # Health check
│   ├── components/
│   │   ├── AnswerCard.tsx                  # Answer display component
│   │   ├── DocumentUpload.tsx              # Document upload component
│   │   ├── Header.tsx                      # App header with branding
│   │   ├── Banner.tsx                      # Voltage Park banner
│   │   ├── Footer.tsx                      # App footer
│   │   ├── ClientLayout.tsx                # Layout wrapper
│   │   └── ThemeRegistry.tsx               # Theme provider
│   ├── lib/
│   │   ├── theme.ts                        # Material UI theme (green accents)
│   │   └── docsets-store.ts                # State management
│   ├── layout.tsx                          # Root layout
│   └── page.tsx                            # Home page with stepper interface
├── public/
│   └── favicon.svg
├── .env.example                            # Environment template
├── next.config.js                          # Next.js config
├── tsconfig.json                           # TypeScript config
└── package.json

API Endpoints

POST /api/docsets

Create a new document collection.

Request:

{
  "name": "Research Papers",
  "description": "Analysis of attention-is-all-you-need paper",
  "factory_id": "default",
  "user_id": "anonymous"
}

Response:

{
  "docset_id": "3da8233a-b11b-4c89-a000-95a97735a512",
  "name": "Research Papers",
  "status": "created"
}

GET /api/docsets

List all document collections.

Response:

{
  "docsets": [
    {
      "docset_id": "3da8233a-b11b-4c89-a000-95a97735a512",
      "name": "Research Papers",
      "description": "Analysis of attention-is-all-you-need paper",
      "status": "ready",
      "document_count": 1,
      "created_at": "2025-11-01T14:20:47.000848"
    }
  ],
  "count": 1
}

POST /api/docsets/:id/ingest

Upload and process a document.

Request: (multipart/form-data)

  • file: Document file (PDF, DOC, DOCX, TXT)
  • source_type: Document type (default: "document")
  • factory_id: Factory ID (default: "default")
  • doc_tags: Comma-separated tags (optional)

Response:

{
  "doc_id": "878f4019-9a1b-4c93-b1a0-4958212a8786",
  "status": "processed",
  "chunks": 35,
  "vectors": 35,
  "processing_time_ms": 48234
}

POST /api/docsets/:id/generate

Generate an answer to a question about the documents.

Request:

{
  "content_prompt": "What is this paper about?",
  "format_prompt": "Provide a detailed explanation with bullet points",
  "section_label": "Paper Summary",
  "top_k": 8
}

Response:

{
  "docset_id": "3da8233a-b11b-4c89-a000-95a97735a512",
  "generation_id": "1adbcfc0-e5d6-40c6-a11b-e674f183bad6",
  "section_label": "Paper Summary",
  "content": "## Summary\n\nThis paper introduces...",
  "word_count": 339,
  "status": "completed",
  "processing_time_ms": 20931,
  "created_at": "2025-11-01T14:20:47.000848"
}

GET /api/health

Health check endpoint.

Response:

{
  "status": "ok",
  "timestamp": "2025-11-01T...",
  "docsets": 3
}

GET /api/concurrency

Get current concurrency limiter statistics for document ingestion and answer generation.

Response:

{
  "timestamp": "2025-11-02T...",
  "ingestion": {
    "name": "Ingest",
    "maxConcurrent": 3,
    "activeCount": 1,
    "queuedCount": 0,
    "availableSlots": 2,
    "utilizationPercent": 33
  },
  "generation": {
    "name": "Generate",
    "maxConcurrent": 5,
    "activeCount": 2,
    "queuedCount": 1,
    "availableSlots": 3,
    "utilizationPercent": 40
  }
}

Development

# Start development server
npm run dev

# Build for production
npm run build

# Start production server
npm start

# Run linter
npm run lint

Deployment

Deploy to Vercel (recommended):

npm install -g vercel
vercel

Or deploy to:

Important: Set environment variables (DOCSETS_API_URL and DOCSETS_BEARER_TOKEN) in your hosting platform's dashboard.

Production Notes

The application is designed with a stateless architecture:

Server-Side (Stateless)

  • Concurrency limiting only - Server only maintains in-memory concurrency queues
  • Pure API proxy - All requests are forwarded to Voltage Park API
  • Horizontal scaling - Multiple server instances work independently
  • No data loss on restart - Client state persists across server restarts

Client-Side State Management

  • Docsets - Stored in browser memory during session
  • Generations - Q&A history maintained in React state
  • Persistence - Consider adding localStorage for session recovery

Additional Production Considerations

  1. Client State Persistence - Add localStorage/IndexedDB for persistent client state
  2. User Authentication - Add login/signup with backend user session management
  3. Rate Limiting - Implement per-user or per-IP rate limits
  4. Monitoring - Add logging and error tracking (e.g., Sentry)
  5. CDN - Deploy static assets to CDN for better performance
  6. Redis (Optional) - For distributed concurrency limiting across multiple servers

API Integration Example

Using the Voltage Park API directly (via curl):

# 1. Create a docset
curl -X POST "https://060de239.voltagepark.studio/docsets/" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "factory_id": "default",
    "name": "Attention Paper Analysis",
    "metadata": {
      "user_id": "user123",
      "description": "Analysis of attention-is-all-you-need paper"
    }
  }'

# 2. Upload a document
curl -X POST "https://060de239.voltagepark.studio/docsets/DOCSET_ID/ingest" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -F "file=@paper.pdf" \
  -F "source_type=contract" \
  -F "factory_id=default" \
  -F "doc_tags=paper,attention,nlp"

# 3. Ask a question
curl -X POST "https://060de239.voltagepark.studio/docsets/DOCSET_ID/generate?factory_id=default" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "content_prompt": "What is this paper about?",
    "top_k": 8
  }'

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

License

MIT License - see LICENSE file for details

Acknowledgments


Questions or issues? Open an issue on GitHub or contact the maintainers.

About

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages