Skip to content

AsierDev/pocket-promptsmith

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

72 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Pocket Promptsmith

Next.js React TypeScript Supabase Tailwind CSS OpenRouter

A modern Progressive Web App for managing, organizing, and AI-improving reusable prompts with dynamic variables using OpenRouter API.

Pocket Promptsmith is a feature-rich PWA built with Next.js 16 (App Router + React 19) that allows users to save, organize, and enhance reusable prompts with dynamic variables and AI assistance powered by OpenRouter.

πŸš€ Explore the live application: pocket-promptsmith.vercel.app

πŸš€ Features

  • πŸ” Email + Password Authentication - Secure login with Supabase Auth
  • πŸ“ Prompt Management - Create, edit, and organize prompts with categories, tags, and a short "Objective" summary
  • πŸ€– AI-Powered Improvements - Enhance prompts using OpenRouter API with a premium (5/day) + free fallback model chain and a dedicated "text to improve" field (4k chars) that avoids sending the entire prompt when it's too long
  • πŸ”’ Dynamic Variables - Extract and replace variables like {{variable}} in prompts
  • πŸ“± Progressive Web App - Installable app with offline capabilities
  • β™Ώ Freemium Model - 10 prompts limit, 5 AI improvements per day
  • ⚑ Server-Side Rendering - Optimized with Next.js 16 and Webpack/Turbopack
  • 🎨 Modern UI - Clean interface with Tailwind CSS and accessibility features

πŸ“‹ Table of Contents

πŸ› οΈ Tech Stack

Category Technology Version
Frontend Next.js 16.0.1
React 19.2
TypeScript 5.8
Tailwind CSS 3.4
Backend Supabase Latest
PostgreSQL Latest
State Management Zustand 5.x
Forms React Hook Form Latest
Zod Latest
AI Integration OpenRouter API Latest
Testing Playwright Latest
Vitest Latest
PWA Service Worker Native

πŸ“ Project Structure

Pocket-Promptsmith/
β”œβ”€β”€ app/                          # Next.js 16 App Router
β”‚   β”œβ”€β”€ layout.tsx               # Global metadata + providers
β”‚   β”œβ”€β”€ page.tsx                 # Public landing page
β”‚   β”œβ”€β”€ login/                   # Email + password authentication
β”‚   β”œβ”€β”€ auth/callback/           # Supabase session exchange
β”‚   β”œβ”€β”€ prompts/                 # Protected dashboard
β”‚   β”‚   β”œβ”€β”€ layout.tsx           # Protected layout with daily reset
β”‚   β”‚   β”œβ”€β”€ page.tsx             # Prompts listing
β”‚   β”‚   β”œβ”€β”€ new/                 # Create new prompt
β”‚   β”‚   β”œβ”€β”€ [id]/                # Prompt details
β”‚   β”‚   β”‚   β”œβ”€β”€ page.tsx         # Edit prompt
β”‚   β”‚   β”‚   └── use/             # Use prompt modal
β”‚   └── api/                     # API routes
β”‚       └── ai-improve/          # OpenRouter AI integration
β”œβ”€β”€ public/                      # Static assets
β”‚   β”œβ”€β”€ manifest.json           # PWA manifest
β”‚   β”œβ”€β”€ sw.js                   # Service worker
β”‚   └── icons/                  # App icons
β”œβ”€β”€ src/
β”‚   β”œβ”€β”€ components/             # Reusable UI components
β”‚   β”‚   └── common/             # Generic UI components
β”‚   β”œβ”€β”€ features/               # Feature-based architecture
β”‚   β”‚   β”œβ”€β”€ auth/               # Authentication logic
β”‚   β”‚   β”œβ”€β”€ prompts/            # Prompt CRUD operations
β”‚   β”‚   β”œβ”€β”€ ai-improvements/    # AI integration
β”‚   β”‚   β”œβ”€β”€ variables/          # Variable extraction/replacement
β”‚   β”‚   β”œβ”€β”€ limits/             # Freemium limits
β”‚   β”‚   └── pwa/                # PWA functionality
β”‚   β”œβ”€β”€ lib/                    # Core utilities
β”‚   β”‚   β”œβ”€β”€ supabaseServer.ts   # Server-side Supabase client
β”‚   β”‚   β”œβ”€β”€ limits.ts           # Business logic limits
β”‚   β”‚   └── env.ts              # Environment validation
β”‚   β”œβ”€β”€ store/                  # Zustand state management
β”‚   β”œβ”€β”€ types/                  # TypeScript definitions
β”‚   └── styles/                 # Global styles
β”œβ”€β”€ supabase/                   # Database schema & migrations
β”‚   └── schema.sql              # Complete database schema
β”œβ”€β”€ tests/                      # Test suites
β”‚   β”œβ”€β”€ unit/                   # Vitest unit tests
β”‚   └── integration/            # Playwright E2E tests
β”œβ”€β”€ proxy.ts                    # Next.js middleware replacement
β”œβ”€β”€ next.config.ts              # Next.js configuration
β”œβ”€β”€ tailwind.config.ts          # Tailwind CSS configuration
β”œβ”€β”€ vitest.config.ts            # Vitest configuration
└── playwright.config.ts        # Playwright configuration

πŸ“‹ Prerequisites

Before you begin, ensure you have the following installed:

  • Node.js (v18 or higher)
  • npm or yarn
  • Git
  • Supabase CLI (optional but recommended)

Supabase Account Setup

  1. Create a Supabase account
  2. Create a new project
  3. Note your project reference ID

πŸš€ Quick Start

1. Clone the Repository

git clone https://github.com/your-username/pocket-promptsmith.git
cd pocket-promptsmith

2. Install Dependencies

npm install

3. Environment Setup

cp .env.example .env.local

Edit .env.local with your configuration (see Environment Configuration).

4. Supabase Setup

# Install Supabase CLI (if not installed)
npm install -g supabase

# Login to Supabase
supabase login

# Link your project
supabase link --project-ref YOUR_PROJECT_REF

# Apply database schema
supabase db push

5. Start Development Server

npm run dev

Visit http://localhost:3000 to see the application.

πŸ”§ Environment Configuration

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

# Supabase Configuration (Required)
NEXT_PUBLIC_SUPABASE_URL=https://your-project.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=your-anon-key
NEXT_PUBLIC_SITE_URL=http://localhost:3000
SUPABASE_SERVICE_ROLE_KEY=your-service-role-key

# OpenRouter AI Configuration (Required for AI features; env validator requires value)
OPENROUTER_API_KEY=your-openrouter-api-key
OPENROUTER_BASE_URL=https://openrouter.ai/api/v1

# Application Configuration
NODE_ENV=development

Security Notes

  • src/lib/env.ts validates with Zod and is server-side only; if keys are missing, the app fails on startup.
  • Don't import env in use client components; web clients should only depend on NEXT_PUBLIC_*.
  • For CI/tests you can use dummy values (NEXT_PUBLIC_SUPABASE_URL=http://localhost:54321, NEXT_PUBLIC_SUPABASE_ANON_KEY=anon, OPENROUTER_API_KEY=dummy).
  • The service role key is used only from CLI for migrations; never share it or deploy it to the frontend.

πŸ—„οΈ Database Setup

Automatic Setup (Recommended)

supabase db push

This command will create all necessary tables, RLS policies, and PostgreSQL functions:

  • profiles - User profiles and limits tracking
  • prompts - Prompt storage with metadata; includes ai_improvement_source (nullable) to save only the fragment used in AI improvements
  • prompt_improvements - AI improvement history
  • PostgreSQL Functions:
    • get_user_tags() - Fetch user tags efficiently
    • increment_prompt_use_count() - Atomic counter updates
    • reset_daily_improvements() - Daily quota reset (marked as volatile)

Manual Setup

If you prefer manual setup, execute the SQL commands from supabase/schema.sql in your Supabase SQL Editor.

Important: Ensure all SQL functions are applied correctly. If you encounter errors like "UPDATE is not allowed in a non-volatile function", verify that functions modifying data are marked as volatile (not stable) in PostgreSQL.

πŸƒβ€β™‚οΈ Development

Available Scripts

Command Description
npm run dev Start development server with Turbopack
npm run build Create production build
npm run start Start production server
npm run lint Run ESLint with Next.js configuration
npm run test Run Vitest unit tests
npm run test:watch Run Vitest in watch mode
npm run test:integration Run Playwright E2E tests
npm run type-check Run TypeScript type checking
npm run build -- --webpack Production build using Webpack (useful in environments where Turbopack is restricted)

Development Workflow

  1. Code Quality: npm run lint ensures clean code with flat config
  2. Testing: npm run test runs unit tests, ignores Playwright specs
  3. Type Safety: TypeScript strict mode ensures type safety
  4. Hot Reloading: Turbopack provides fast development experience

πŸ“š API Documentation

OpenRouter AI Integration

Endpoint: POST /api/ai-improve

Authentication: Requires valid Supabase session

Request:

{
  content: string;
  goal?: string;
  category: "Writing" | "Code" | "Marketing" | "Analysis" | "Creativity" | "Education" | "Other";
  temperature?: number; // 0..1
  length?: "short" | "medium" | "long";
}

Response:

{
  improved_prompt: string;
  changes: string[];
  diff: string;
  modelUsed?: string;
  premiumImprovementsUsedToday: number;
}

The backend automatically selects the appropriate model using the getModelsForImprovement helper. The first five daily improvement attempts use premium models (google/gemini-2.5-flash-lite, google/gemini-2.0-flash-lite-001); once those are exhausted the flow falls back to free models (google/gemini-2.0-flash-exp:free, meta-llama/llama-4-maverick:free).

Error Responses:

  • 401 Unauthorized - Invalid or missing session
  • 429 Too Many Requests - Daily premium improvement limit exceeded
  • 400 Bad Request - Invalid input data

Supabase Database Schema

Tables

profiles

  • id (uuid, primary key)
  • email (text)
  • plan ('free' | 'pro')
  • prompt_quota_used (integer)
  • improvements_used_today (integer)
  • improvements_reset_at (timestamptz)
  • created_at (timestamptz)
  • updated_at (timestamptz)

prompts

  • id (uuid, primary key)
  • user_id (uuid, foreign key)
  • title (text)
  • summary (text)
  • content (text)
  • category (enum)
  • tags (text[])
  • is_favorite (boolean)
  • use_count (integer)
  • created_at (timestamptz)
  • updated_at (timestamptz)

prompt_improvements

  • id (uuid, primary key)
  • prompt_id (uuid, foreign key)
  • user_id (uuid, foreign key)
  • original_content (text)
  • improved_content (text)
  • diff_json (jsonb)
  • created_at (timestamptz)

πŸ§ͺ Testing

Unit Tests (Vitest)

# Run all unit tests
npm run test

# Run specific test file
npm run test extractVariables

# Watch mode for development
npm run test:watch

# Generate coverage reports (~66% statements)
npm run test:coverage

Coverage and environment:

  • vitest.config.ts injects dummy values for NEXT_PUBLIC_SUPABASE_URL, NEXT_PUBLIC_SUPABASE_ANON_KEY, OPENROUTER_API_KEY and OPENROUTER_BASE_URL, so you don't need real secrets to run tests.
  • npm run test:coverage uses @vitest/coverage-v8 and limits target to src/**/* (excluding heavy UI/PWA) to have an actionable report. The result is saved in coverage/index.html and currently covers 66% of statements.
  • The new suites cover prompt logic (tests/unit/promptServices.test.ts), stores (premiumUsageStore, uiStore), AI helpers and environment validators, in addition to existing form, limits, etc. tests.

Integration Tests (Playwright)

# Install Playwright browsers once (local only)
npx playwright install --with-deps

# Run E2E tests (Playwright starts Next.js automatically)
npm run test:integration

Test Suites:

  • auth.spec.ts - Renders email + password form and validates errors
  • prompts.spec.ts - Ensures dashboard redirects to /login without session
  • ai.spec.ts - Hits POST /api/ai-improve without session and visits /prompts/new to check saving
  • variables.spec.ts - Smoke test of landing and variable content

playwright.config.ts defines webServer with npm run dev -- --hostname 127.0.0.1 --port 3000, so the suite starts and stops Next.js automatically during the pipeline (no need for a parallel npm run dev). It also sets the same dummy environment values that Vitest uses.

πŸ” Continuous Integration

  • The ci.yml action runs on every push to main/master and on all Pull Requests.
  • Key steps: npm ci, npm run lint, npm run test, npm run test:coverage, Playwright browser installation (npx playwright install --with-deps) and npm run test:integration.
  • All tasks run on Node 20 on Ubuntu and reuse dummy values for Supabase/OpenRouter, so workflows don't depend on sensitive secrets.
  • If you need to inspect coverage reports generated in CI, you can add actions/upload-artifact pointing to coverage/ (the flow is prepared for it).

πŸš€ Deployment

Vercel (Recommended)

This application is currently deployed on Vercel: pocket-promptsmith.vercel.app

  1. Connect Repository:

    npx vercel --prod
  2. Environment Variables: Add all environment variables in Vercel dashboard

  3. Database: Ensure supabase db push is run on production

Other Platforms

Netlify:

  • Build command: npm run build
  • Publish directory: .next
  • Environment variables required

Railway:

  • Connect GitHub repository
  • Auto-deploys on push
  • Environment variables in dashboard

Production Checklist

  • Environment variables configured
  • Database schema applied with supabase db push
  • SSL certificate configured
  • Error monitoring (Sentry) setup
  • Performance monitoring configured
  • Database backups enabled

πŸ”’ Security & Performance

Security Measures

  • Row Level Security (RLS): All Supabase tables protected
  • Session Validation: API routes validate Supabase sessions
  • CSP Headers: Content Security Policy implementation
  • Input Validation: Zod schema validation on all inputs
  • Rate Limiting: API endpoints protected from abuse

Performance Optimizations

  • Server Components: Leveraging Next.js 16 Server Components
  • Caching: use cache directive for optimal data fetching
  • Bundle Optimization: Turbopack for fast builds
  • Image Optimization: Next.js Image component
  • Service Worker: PWA caching strategies

Data Privacy

  • Local Storage: Minimal data stored locally
  • Session Management: Secure cookie-based sessions
  • API Key Protection: OpenRouter keys never exposed to client
  • GDPR Compliance: User data deletion capabilities

πŸ”§ Troubleshooting

Common Issues

1. "UPDATE is not allowed in a non-volatile function"

Problem: PostgreSQL function volatility issue Solution:

-- Ensure functions modifying data are marked as volatile
CREATE OR REPLACE FUNCTION reset_daily_improvements(target_user_id uuid)
RETURNS public.profiles
LANGUAGE sql
VOLATILE  -- Not STABLE
AS $$
  -- function body
$$;

2. Build Fails with Turbopack

Problem: Development environment restrictions Solution: Run build outside restricted sandbox environment

3. Authentication Not Working

Problem: Incorrect Supabase URL configuration Solution:

  • Verify NEXT_PUBLIC_SUPABASE_URL format: https://project-id.supabase.co
  • Check redirect URLs in Supabase dashboard
  • Ensure NEXT_PUBLIC_SITE_URL matches your domain

4. AI Improvements Not Working

Problem: OpenRouter API issues Solution:

  • Verify OPENROUTER_API_KEY is valid
  • Check API quotas and limits
  • Ensure network connectivity to OpenRouter

5. PWA Not Installing

Problem: Service Worker registration issues Solution:

  • Check browser console for SW errors
  • Verify manifest.json is accessible
  • Ensure HTTPS in production

Debug Mode

Enable debug logging:

NODE_ENV=development npm run dev

Logs

  • Server logs: Terminal output during development
  • Browser logs: Developer console for client-side debugging
  • Supabase logs: Dashboard > Logs section

🀝 Contributing

We welcome contributions! Please follow these guidelines:

Development Process

  1. Fork repository
  2. Create a feature branch: git checkout -b feature/amazing-feature
  3. Make your changes
  4. Run tests: npm run test && npm run lint
  5. Commit changes: git commit -m 'Add amazing feature'
  6. Push to branch: git push origin feature/amazing-feature
  7. Open a Pull Request

Code Style

  • TypeScript: Strict mode enabled
  • ESLint: Flat config with Next.js recommended rules
  • Prettier: Code formatting (run npm run format)
  • Conventional Commits: Use semantic commit messages

Pull Request Guidelines

  • Title: Clear and descriptive
  • Description: Explain what, why, and how
  • Tests: Include tests for new functionality
  • Documentation: Update README if needed
  • Breaking Changes: Clearly document and justify

Issue Reporting

When reporting issues, include:

  • Environment: OS, Node version, browser
  • Reproduction steps: Clear steps to reproduce
  • Expected vs actual behavior
  • Screenshots: If relevant
  • Error logs: Console output and stack traces

πŸ“„ License

This project is licensed under the MIT License - see the LICENSE file for details.

MIT License Summary

  • βœ… Commercial use - You can use this project commercially
  • βœ… Modification - You can modify the project
  • βœ… Distribution - You can distribute the project
  • βœ… Private use - You can use the project privately
  • ❌ Liability - Liability is not granted
  • ❌ Warranty - Warranty is not granted

πŸ™ Acknowledgments

  • Next.js Team - For the amazing React framework
  • Supabase Team - For the fantastic Backend-as-a-Service
  • OpenRouter - For providing accessible AI models
  • Tailwind CSS - For the utility-first CSS framework
  • Open Source Community - For all the amazing tools and libraries

πŸ“ž Support


Built with ❀️ using Next.js, Supabase, and OpenRouter

Star on GitHub

About

Pocket Promptsmith is a PWA built with Next.js 16 that allows you to save, organize, and improve reusable prompts with dynamic variables and AI assistance.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors