Skip to content

Latest commit

 

History

History
317 lines (243 loc) · 8.24 KB

File metadata and controls

317 lines (243 loc) · 8.24 KB

Pluga Challenge - Snippets API

A full-stack application for creating and managing text snippets with AI-generated summaries. Built with Ruby on Rails (backend) and Next.js (frontend).

🚀 Features

  • Create Snippets: Paste text content and automatically generate AI-powered summaries
  • View Snippets: Browse all your saved snippets with their summaries
  • AI Integration: Supports both OpenAI and Google Gemini for summary generation
  • RESTful API: Clean, well-documented API endpoints
  • Modern UI: Beautiful, responsive interface built with Next.js

📋 Prerequisites

  • Docker and Docker Compose
  • (Optional) Ruby 3.3+ and Node.js 22+ for local development

🛠️ Setup

Using Docker (Recommended)

  1. Clone the repository

    git clone <repository-url>
    cd Pluga
  2. Configure environment variables

    Create a .env file in the root directory:

    # AI Provider Configuration
    # Options: 'openai' or 'gemini'
    AI_PROVIDER=openai
    
    # OpenAI Configuration (if using OpenAI)
    OPENAI_API_KEY=your_openai_api_key_here
    
    # Gemini Configuration (if using Gemini)
    GEMINI_API_KEY=your_gemini_api_key_here
  3. Get your AI API Key

    For OpenAI:

    • Visit OpenAI API Keys
    • Create a new API key
    • Copy the key and add it to your .env file as OPENAI_API_KEY

    For Gemini:

    • Visit Google AI Studio
    • Create a new API key
    • Copy the key and add it to your .env file as GEMINI_API_KEY
  4. Start the application

    docker compose up

    This will:

    • Start PostgreSQL database
    • Start Rails API on port 3000
    • Start Next.js frontend on port 4000
    • Run database migrations automatically
  5. Access the application

Local Development

Backend Setup

  1. Install dependencies

    cd backend
    bundle install
  2. Setup database

    # Make sure PostgreSQL is running
    bundle exec rails db:create
    bundle exec rails db:migrate
  3. Configure environment

    cp .env.example .env
    # Edit .env with your API keys
  4. Run the server

    bundle exec rails server

Frontend Setup

  1. Install dependencies

    cd frontend
    npm install
  2. Configure environment

    cp .env.example .env.local
    # Edit .env.local if needed (defaults to http://localhost:3000)
  3. Run the development server

    npm run dev

🧪 Testing

Backend Tests

cd backend
bundle exec rspec

Frontend Tests

cd frontend
npm test

Linting

Backend:

cd backend
bundle exec rubocop

Frontend:

cd frontend
npm run lint

📡 API Endpoints

Create Snippet

POST /snippets
Content-Type: application/json

{
  "text": "Your text content here..."
}

# Response (201 Created)
{
  "id": 1,
  "text": "Your text content here...",
  "summary": "AI-generated summary..."
}

Get Snippet

GET /snippets/:id

# Response (200 OK)
{
  "id": 1,
  "text": "Your text content here...",
  "summary": "AI-generated summary..."
}

List Snippets

GET /snippets

# Response (200 OK)
[
  {
    "id": 1,
    "text": "First snippet text...",
    "summary": "First summary..."
  },
  {
    "id": 2,
    "text": "Second snippet text...",
    "summary": "Second summary..."
  }
]

Example Requests

Using curl:

# Create a snippet
curl -X POST http://localhost:3000/snippets \
  -H "Content-Type: application/json" \
  -d '{
    "text": "Ruby on Rails is a web application framework written in Ruby. It follows the Model-View-Controller (MVC) architectural pattern and emphasizes convention over configuration."
  }'

# Get all snippets
curl http://localhost:3000/snippets

# Get a specific snippet
curl http://localhost:3000/snippets/1

🏗️ Project Structure

Pluga/
├── backend/              # Rails API
│   ├── app/
│   │   ├── controllers/  # API controllers
│   │   ├── models/       # ActiveRecord models
│   │   └── services/     # Business logic (AI service)
│   ├── config/           # Rails configuration
│   ├── db/               # Database migrations
│   ├── spec/             # RSpec tests
│   └── Dockerfile
├── frontend/             # Next.js application
│   ├── app/              # Next.js app directory
│   ├── __tests__/        # Jest tests
│   └── Dockerfile
├── docker-compose.yml    # Docker orchestration
└── README.md

🔧 Configuration

Environment Variables

Backend:

  • AI_PROVIDER: AI provider to use (openai or gemini)
  • OPENAI_API_KEY: OpenAI API key (required if using OpenAI)
  • GEMINI_API_KEY: Gemini API key (required if using Gemini)
  • DATABASE_USER: PostgreSQL username (default: postgres)
  • DATABASE_PASSWORD: PostgreSQL password (default: postgres)
  • DATABASE_HOST: PostgreSQL host (default: db for Docker)

Frontend:

  • NEXT_PUBLIC_API_URL: Backend API URL (default: http://localhost:3000)

🚢 CI/CD

The project includes a GitHub Actions workflow (.github/workflows/ci.yml) that:

  • Runs Rubocop linting on the backend
  • Runs RSpec tests on the backend
  • Runs ESLint on the frontend
  • Runs Jest tests on the frontend

📝 Reflection

What I Would Improve with More Time

  1. Error Handling & User Experience

    • Add more granular error messages for different failure scenarios
    • Implement retry logic for AI API calls
    • Add loading states and progress indicators for long-running operations
    • Implement optimistic UI updates
  2. Testing

    • Add integration tests for the full stack
    • Increase test coverage, especially edge cases
    • Add E2E tests with Playwright or Cypress
    • Mock AI responses more comprehensively in tests
  3. Performance & Scalability

    • Implement caching for frequently accessed snippets
    • Add pagination for the snippets list endpoint
    • Implement background jobs (Sidekiq) for AI summary generation to avoid blocking requests
    • Add database indexes for better query performance
  4. Features

    • Add snippet editing and deletion
    • Implement search and filtering
    • Add user authentication and multi-user support
    • Allow users to regenerate summaries with different parameters
    • Add export functionality (CSV, JSON)
  5. Security

    • Add rate limiting to prevent API abuse
    • Implement input sanitization and validation
    • Add CORS configuration for production
    • Implement API authentication/authorization
  6. DevOps

    • Add health check endpoints
    • Implement proper logging and monitoring
    • Add staging environment configuration
    • Set up automated deployments

Trade-offs Made

  1. Synchronous AI Calls: I chose to generate summaries synchronously during snippet creation. This simplifies the implementation but could lead to slow responses if the AI API is slow. In production, I would use background jobs.

  2. Simple UI: The frontend is intentionally simple and focused on core functionality. I prioritized working features over advanced UI components, which could be enhanced with a component library like Material-UI or Tailwind CSS.

  3. Single Database: Using a single PostgreSQL database for simplicity. For a production system handling high volume, I might consider read replicas or separate databases for different concerns.

  4. No Authentication: Skipped user authentication to focus on core functionality. This is a necessary feature for a production system but adds complexity that wasn't required for the challenge.

  5. Basic Error Handling: Implemented basic error handling that covers the main scenarios. More sophisticated error handling with retries, circuit breakers, and detailed logging would be needed for production.

  6. Docker Development Focus: The Docker setup is optimized for development. Production deployments would need multi-stage builds, smaller images, and better security practices.

📄 License

This project was created as part of the Pluga technical challenge.