We will be undergoing planned maintenance on January 16th, 2026 at 1:00pm UTC. Please make sure to save your work.

OpenAsk - AI-Powered Q&A Platform for Developers 🚀

💡 Inspiration

The inspiration for OpenAsk came from observing the challenges developers face when seeking help:

  • Stack Overflow can be intimidating for beginners due to strict posting rules and sometimes harsh feedback
  • Discord/Slack communities provide quick help but answers get lost in chat history
  • Traditional forums lack modern features like AI-assisted responses and real-time collaboration

I envisioned a platform that combines the best of all worlds: community-driven Q&A with instant AI-generated draft answers to kickstart discussions, wrapped in a modern, friendly interface.


🎯 What It Does

OpenAsk is a full-stack Q&A platform that:

  1. Instant AI Assistance: When you post a question, Google's Gemini AI generates a draft answer immediately to get you started
  2. Community Engagement: Upvote/downvote questions and answers, fostering quality content through community moderation
  3. Smart Search & Tags: Find relevant questions quickly with full-text search and tag-based filtering
  4. Secure Authentication: Auth0-powered login with social providers (Google, GitHub) for seamless access
  5. Real-Time Updates: See vote counts and new answers instantly as the community engages
  6. Markdown Support: Rich text formatting for code snippets, lists, and formatted answers

Core Features:

  • ✅ Ask questions with tags and receive AI-generated draft answers
  • ✅ Browse, search, and filter questions by tags or votes
  • ✅ Vote on questions and answers to surface quality content
  • ✅ Edit your own questions and answers
  • ✅ User profiles showing contribution history
  • ✅ Trending tags sidebar for topic discovery

🛠️ How We Built It

Architecture

OpenAsk is built as a TypeScript monorepo using modern best practices:

openask/
├── apps/
│   ├── web/          # React + Vite + TypeScript frontend
│   └── api/          # Express + MongoDB backend
├── packages/
│   ├── sdk/          # Typed API client library
│   ├── ui/           # Reusable React components
│   └── config/       # Shared TypeScript/ESLint configs

Why Monorepo?

  • Shared TypeScript types between frontend and backend prevent API contract mismatches
  • Reusable component library ensures UI consistency
  • Single source of truth for coding standards (ESLint, Prettier)

Technology Stack

Frontend (apps/web)

  • React 18 with TypeScript for type-safe component development
  • Vite for lightning-fast dev server and optimized production builds
  • TailwindCSS for utility-first styling with custom design system
  • Auth0 React SDK for secure authentication flows
  • React Hook Form + Zod for form validation with type inference
  • React Router v6 for client-side routing
  • React Markdown for safe rendering of user-generated content

Backend (apps/api)

  • Express.js with TypeScript for robust API development
  • MongoDB + Mongoose for flexible document storage with schema validation
  • Auth0 JWT middleware for stateless authentication
  • Google Gemini AI (gemini-2.0-flash-exp) for generating draft answers
  • Pino for structured JSON logging
  • Helmet for security headers
  • Express Rate Limit to prevent abuse (100 requests/15min)

Infrastructure & DevOps

  • pnpm workspaces for efficient monorepo management
  • Docker support for containerized deployment
  • GitHub Actions CI/CD pipeline (lint, typecheck, test, build)
  • Husky pre-commit hooks to enforce code quality
  • Conventional Commits for semantic versioning

Key Implementation Details

1. Authentication Flow

// Frontend: Auth0 provider wraps app
<Auth0Provider domain={...} clientId={...} authorizationParams={{ audience: "https://openask-api" }}>
  <App />
</Auth0Provider>

// SDK: Automatic token injection
const token = await getAccessTokenSilently({ cacheMode: 'off' });
fetch(url, { headers: { Authorization: `Bearer ${token}` } });

// Backend: JWT verification middleware
app.use('/api/v1', checkJwt); // Validates Auth0 JWT

2. AI Integration

// Gemini service with fallback
async function generateDraftAnswer({ title, body }) {
  if (!GEMINI_API_KEY) return mockDraftAnswer(); // Deterministic mock

  const model = genAI.getGenerativeModel({ model: "gemini-2.0-flash-exp" });
  const result = await model.generateContent(prompt);
  return result.response.text();
}

3. Vote System

// MongoDB compound unique index prevents duplicate votes
VoteSchema.index({ targetType: 1, targetId: 1, userId: 1 }, { unique: true });

// Atomic vote updates
await Vote.findOneAndUpdate(
  { targetType, targetId, userId },
  { value }, // 1 or -1
  { upsert: true }
);

4. Full-Text Search

// MongoDB text index on question title/body
QuestionSchema.index({ title: 'text', body: 'text' });

// Search query
Question.find({ $text: { $search: query } })
  .sort({ score: { $meta: 'textScore' } });

🧗 Challenges We Faced

1. Monorepo Configuration Complexity

Problem: Getting pnpm workspaces to work across TypeScript projects with shared dependencies was initially confusing.

Solution:

  • Created packages/config with shared tsconfig.base.json
  • Used "workspace:*" protocol for internal dependencies
  • Set up proper references in each workspace's tsconfig.json

Lesson: Spend time upfront on project structure—it pays dividends later.


2. Auth0 Token Audience Mismatch

Problem: Frontend was authenticated, but API returned 401 Unauthorized when posting questions.

Solution:

  • Discovered token was issued for Auth0 Management API, not our custom API
  • Created Auth0 API with identifier https://openask-api
  • Updated frontend to pass audience in getAccessTokenSilently()

Code Fix:

// Before (wrong)
const token = await getAccessTokenSilently();

// After (correct)
const token = await getAccessTokenSilently({ 
  audience: "https://openask-api",
  cacheMode: 'off' // Force fresh token
});

Lesson: Auth0 requires explicit API audience—generic tokens won't work for custom APIs.


3. API Response Shape Mismatch

Problem: Frontend showed "No questions found" despite API returning data. Network tab showed {items: [...]} but SDK expected {questions: [...]}.

Solution:

  • Traced through pagination helper (createPaginationResult) returning wrong shape
  • Updated API routes to return SDK-compatible format: ```typescript // Changed from: return res.json(createPaginationResult(items, page, limit, total));

// To: return res.json({ questions: items, total, page, limit, totalPages: Math.ceil(total / limit) });


**Lesson**: Type-safe SDK prevents runtime errors—ensure API contracts match TypeScript interfaces.

---

### **4. Mongoose Validation Error on User Creation**
**Problem**: Creating questions failed with "User validation failed: email: Path `email` is required."

**Root Cause**: Auth0 JWT `sub` field doesn't include email by default.

**Solution**:
```typescript
// Made email optional in User schema
email: { 
  type: String, 
  required: false, // Changed from true
  unique: true,
  sparse: true // Allow multiple null emails
}

Lesson: Don't assume OAuth providers include all fields—make optional fields explicit.


5. Vote Route Conflict

Problem: Voting on answers returned "Question not found" error.

Root Cause: Both question and answer vote routes used same path /:id/vote, causing Express to always match question route first.

Solution: Consolidated into single smart route:

router.post('/:id/vote', async (req, res) => {
  const isAnswer = req.baseUrl.includes('/answers');
  const Model = isAnswer ? Answer : Question;
  const targetType = isAnswer ? 'answer' : 'question';
  // ... rest of vote logic
});

Lesson: Express matches routes in order—consolidate similar routes or use middleware to distinguish.


6. Vercel Deployment: pnpm Version Mismatch

Problem: Vercel used pnpm 6.35.1 but project required >=8.0.0.

Solution Attempts:

  1. ❌ Added .npmrc with use-node-version → Vercel rejected
  2. ❌ Tried Corepack → Still used old pnpm
  3. Final fix: Custom install command: json { "installCommand": "npm install -g pnpm@9.15.0 && cd ../.. && pnpm install --no-frozen-lockfile" }

Lesson: Vercel's Node.js environment has quirks—sometimes you need creative workarounds.


7. Gemini API Model Deprecation

Problem: AI draft answers failed with 404 errors.

Solution: Updated from deprecated gemini-1.5-flash to gemini-2.0-flash-exp:

const model = genAI.getGenerativeModel({ 
  model: "gemini-2.0-flash-exp" // Was: gemini-1.5-flash
});

Lesson: Always check API documentation for latest model versions, especially in beta/preview stages.


📚 What We Learned

Technical Skills

  1. Monorepo Management: pnpm workspaces, TypeScript project references, shared configs
  2. OAuth2/OIDC: Deep understanding of JWT audience claims, token refresh, Auth0 configuration
  3. API Design: RESTful conventions, pagination strategies, error handling patterns
  4. Database Indexing: Text search indexes, compound unique indexes for data integrity
  5. AI Integration: Prompt engineering, fallback strategies, rate limiting AI requests
  6. DevOps: Docker multi-stage builds, CI/CD pipelines, deployment platform tradeoffs

Soft Skills

  1. Debugging Methodology: Read error messages carefully, use logging strategically, verify assumptions
  2. Documentation: Write for your future self—good docs save hours later
  3. Incremental Development: Build small, test often, commit frequently
  4. Resilience: When one approach fails (Corepack), try another (npm global install)

Best Practices Adopted

  • Spec-first development: ProjectScope.txt as single source of truth
  • Type safety everywhere: No any types, strict TypeScript config
  • Separation of concerns: SDK abstracts API, UI package shares components
  • Security by default: Rate limiting, CORS, Helmet, input sanitization
  • Fail gracefully: Mock fallbacks for external services (Gemini AI)

🎓 Key Takeaways

For Future Hackathons

  1. Start with architecture: Spend 20% of time planning structure—saves 80% debugging later
  2. Use proven tools: Don't introduce too many new technologies at once
  3. Document as you go: README updates = progress checkpoints
  4. Test auth early: Authentication bugs are time sinks—verify flow before building features
  5. Deploy early: Don't wait until last minute—infrastructure surprises happen

Technical Insights

  • Monorepos shine for full-stack projects with shared types
  • JWT audience claims are critical for multi-API architectures
  • Defensive programming (optional fields, fallbacks) prevents runtime errors
  • Index your queries: MongoDB text indexes = 10x faster search
  • Rate limiting is essential for AI API endpoints (cost control)

🚀 What's Next for OpenAsk

Immediate Improvements

  • [ ] Real-time updates via WebSockets for live vote counts
  • [ ] Notification system for answers to your questions
  • [ ] Email digests of trending questions in followed tags
  • [ ] Code syntax highlighting in markdown answers

Advanced Features

  • [ ] AI-powered duplicate question detection
  • [ ] Reputation system with badges (like Stack Overflow)
  • [ ] Question bounties to incentivize answers
  • [ ] Multi-language support (i18n)
  • [ ] Advanced moderation tools (flag inappropriate content)

Technical Debt

  • [ ] Add E2E tests (Playwright/Cypress)
  • [ ] Implement caching layer (Redis) for hot questions
  • [ ] GraphQL API for more efficient data fetching
  • [ ] Performance monitoring (Sentry, DataDog)

🏆 Hackathon Accomplishments

We're proud to have built a production-ready platform with:

  • 100% TypeScript - Type-safe from database to UI
  • Comprehensive docs - README, CONTRIBUTING, CODE_OF_CONDUCT, SECURITY
  • CI/CD pipeline - Automated testing and deployment
  • Modern architecture - Monorepo, microservices-ready
  • Security-first - Auth0, rate limiting, input sanitization, CORS
  • Accessibility - Semantic HTML, keyboard navigation, ARIA labels
  • Responsive design - Mobile-first, works on all devices
  • Real AI integration - Not just a mock, actual Gemini API calls

Lines of Code: ~15,000+ (excluding dependencies)
Commits: 50+
Time Invested: 72 hours (3 days intensive development)


🙏 Acknowledgments

  • Auth0 for excellent authentication documentation
  • Google Gemini AI for powerful language model API
  • Vercel & Railway for developer-friendly deployment platforms
  • MongoDB for flexible document database
  • Open Source Community for amazing tools (React, Express, Vite, etc.)

📖 Try It Out


💻 Run It Locally

# Clone the repo
git clone https://github.com/9jaDevo/OpenAsk.git
cd OpenAsk

# Install dependencies
pnpm install

# Set up environment variables (see .env.example files)
cp apps/api/.env.example apps/api/.env
cp apps/web/.env.example apps/web/.env

# Start MongoDB (Docker)
docker-compose up -d

# Seed demo data
pnpm --filter api seed

# Run dev servers
pnpm dev

# Frontend: http://localhost:5173
# API: http://localhost:3001

📄 License

MIT © 2025 OpenAsk Contributors


Built with ❤️ during Opensource Hacfest 2025

"Empowering developers to help each other, one question at a time."

Built With

Share this project:

Updates