{"id":50857944,"url":"https://github.com/leonidasdev/portfolio-forge","last_synced_at":"2026-06-14T19:32:11.191Z","repository":{"id":330900569,"uuid":"1124360164","full_name":"leonidasdev/portfolio-forge","owner":"leonidasdev","description":"AI-powered portfolio builder with customizable templates, certification management, and public sharing","archived":false,"fork":false,"pushed_at":"2026-01-31T21:50:00.000Z","size":618,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-02-01T07:11:18.400Z","etag":null,"topics":["nextjs","webapp"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/leonidasdev.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-12-28T22:04:18.000Z","updated_at":"2026-01-31T21:50:04.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/leonidasdev/portfolio-forge","commit_stats":null,"previous_names":["leonidasdev/portfolio-forge"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/leonidasdev/portfolio-forge","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leonidasdev%2Fportfolio-forge","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leonidasdev%2Fportfolio-forge/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leonidasdev%2Fportfolio-forge/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leonidasdev%2Fportfolio-forge/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/leonidasdev","download_url":"https://codeload.github.com/leonidasdev/portfolio-forge/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leonidasdev%2Fportfolio-forge/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34335688,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-14T02:00:07.365Z","response_time":62,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["nextjs","webapp"],"created_at":"2026-06-14T19:32:10.326Z","updated_at":"2026-06-14T19:32:11.185Z","avatar_url":"https://github.com/leonidasdev.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Portfolio Forge\n\n\u003cdiv align=\"center\"\u003e\n\n![Next.js](https://img.shields.io/badge/Next.js-15.1-black?style=for-the-badge\u0026logo=next.js)\n![TypeScript](https://img.shields.io/badge/TypeScript-5.7+-blue?style=for-the-badge\u0026logo=typescript)\n![Supabase](https://img.shields.io/badge/Supabase-PostgreSQL-green?style=for-the-badge\u0026logo=supabase)\n![Groq](https://img.shields.io/badge/AI-Groq-orange?style=for-the-badge)\n![Tests](https://img.shields.io/badge/Tests-388%20passing-brightgreen?style=for-the-badge)\n![License](https://img.shields.io/badge/License-Apache%202.0-blue?style=for-the-badge)\n\n**AI-powered portfolio builder for creating stunning professional portfolios**\n\nBuild, customize, and optimize your professional portfolio with intelligent AI assistance.\nCreate job-tailored resumes, generate compelling content, and stand out from the crowd.\n\n[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/clone?repository-url=https://github.com/leonidasdev/portfolio-forge\u0026env=NEXT_PUBLIC_SUPABASE_URL,NEXT_PUBLIC_SUPABASE_ANON_KEY,SUPABASE_SERVICE_ROLE_KEY,GROQ_API_KEY)\n\n[Features](#-features) • [Quick Start](#-quick-start) • [Documentation](#-documentation) • [API Reference](#-api-reference)\n\n\u003c/div\u003e\n\n---\n\n## Features\n\n### Portfolio Builder\n- **Drag-and-drop interface** for creating professional portfolios\n- **Multiple templates** - Single column, two-column, grid, timeline layouts\n- **Customizable themes** - Professional, modern, creative, minimal, elegant\n- **Real-time preview** of changes\n\n### AI-Powered Features (10+ capabilities)\n| Feature | Description |\n|---------|-------------|\n| **Text Improvement** | Rewrite text in 5 tones: concise, formal, casual, senior, technical |\n| **Summary Generation** | Create professional summaries from portfolio content |\n| **Tag Suggestions** | AI-powered tags with confidence scores |\n| **Experience Bullets** | Generate STAR-method bullet points |\n| **Portfolio Analysis** | Comprehensive scoring with actionable feedback |\n| **Job Optimization** | Tailor portfolio for specific job descriptions |\n| **Resume Import** | Convert resume text to structured portfolio |\n| **Template Recommendations** | Get AI suggestions based on your content |\n| **Batch Rewrite** | Rewrite entire portfolio sections at once |\n| **Theme Recommendations** | Optimal theme based on content style |\n\n### Enterprise-Ready Security\n- **Supabase Auth** with Row-Level Security (RLS)\n- **API Rate Limiting** (configurable per-route)\n- **Request Validation** via Zod schemas\n- **Centralized Error Handling**\n\n### Export \u0026 Deployment\n- **GitHub Pages Export** - Deploy your portfolio to `username.github.io`\n- **ZIP Download** - Download your portfolio as a static site\n- **Custom Domains** - Support for custom domain configuration\n- **Auto-generated** sitemap.xml, robots.txt, 404 page\n\n### Modern Architecture\n- **Next.js 15+ App Router** with server components\n- **TypeScript** throughout with strict typing\n- **API Versioning** (v1 namespace)\n- **Modular AI Layer** (provider → router → abilities → agents)\n\n---\n\n## Quick Start\n\n### Prerequisites\n\n- **Node.js 18+** and npm/yarn/pnpm\n- **Supabase account** ([supabase.com](https://supabase.com))\n- **Groq API key** ([console.groq.com](https://console.groq.com))\n- **(Optional) Upstash Redis** for production rate limiting ([upstash.com](https://upstash.com))\n\n### 1. Clone and Install\n\n```bash\n# Clone the repository\ngit clone https://github.com/yourusername/portfolio-forge.git\ncd portfolio-forge\n\n# Install dependencies\nnpm install\n```\n\n### 2. Configure Supabase\n\n#### A. Create Supabase Project\n1. Go to [supabase.com](https://supabase.com) and create a new project\n2. Wait for the project to finish setting up (2-3 minutes)\n\n#### B. Set Up Database Schema\n1. In your Supabase dashboard, go to **SQL Editor**\n2. Copy the contents of `supabase/schema.sql`\n3. Paste and run the SQL to create tables, policies, and seed data\n4. Verify tables exist in **Table Editor**\n\n#### C. Configure Storage\n1. Go to **Storage** in Supabase dashboard\n2. Copy contents of `supabase/storage-buckets.sql`\n3. Run in SQL Editor to create storage buckets with policies.\n\nNote: `storage-buckets.sql` creates the `certifications` bucket and attempts to enable RLS\nand create storage policies. Policy creation requires ownership privileges on the\n`storage.objects` table; when run as a non-owner you will see NOTICE messages and\nthe file will still create/update the bucket metadata but may skip creating policies.\nIf you want the policies guaranteed to be created, run the file as the DB owner\n(Supabase project owner/service role) or ask the owner to run the policy-only section.\n\n#### D. Enable Authentication Providers\n1. Go to **Authentication \u003e Providers**\n2. Enable **Google**, **GitHub**, and **LinkedIn**\n3. Configure OAuth credentials:\n   - **Callback URL**: `https://your-project.supabase.co/auth/v1/callback`\n   - Add your redirect URLs in each provider's settings\n\n#### E. Get API Credentials\n1. Go to **Settings \u003e API**\n2. Copy:\n   - **Project URL**: `https://your-project.supabase.co`\n   - **anon/public key**: `eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...`\n\n### 3. Get Groq API Key\n\n1. Go to [console.groq.com](https://console.groq.com)\n2. Sign up or log in\n3. Navigate to **API Keys**\n4. Click **Create API Key**\n5. Copy the key (starts with `gsk_...`)\n\n### 4. (Optional) Set Up Redis Rate Limiting\n\nFor production-grade rate limiting:\n\n1. Go to [upstash.com](https://upstash.com) and create account\n2. Create a new Redis database\n3. Select **Serverless** plan (free tier available)\n4. Copy **UPSTASH_REDIS_REST_URL** and **UPSTASH_REDIS_REST_TOKEN**\n\n**Note:** App works without Redis (uses in-memory fallback), but won't scale across multiple instances.\n\n### 5. Configure Environment Variables\n\n```bash\n# Copy the example file\ncp .env.example .env.local\n```\n\nEdit `.env.local` with your credentials:\n\n```env\n# =============================================================================\n# REQUIRED - Get from Supabase Settings \u003e API\n# =============================================================================\nNEXT_PUBLIC_SUPABASE_URL=https://your-project.supabase.co\nNEXT_PUBLIC_SUPABASE_ANON_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...\n\n# =============================================================================\n# REQUIRED - Get from Groq Console\n# =============================================================================\nGROQ_API_KEY=gsk_your_groq_api_key_here\nGROQ_MODEL=llama-3.3-70b-versatile\n\n# =============================================================================\n# OPTIONAL - Production Rate Limiting (uses in-memory if not set)\n# =============================================================================\nUPSTASH_REDIS_REST_URL=https://your-redis.upstash.io\nUPSTASH_REDIS_REST_TOKEN=your_token_here\n\n# =============================================================================\n# OPTIONAL - Rate Limit Configuration\n# =============================================================================\nRATE_LIMIT_ENABLED=true\nRATE_LIMIT_API_MAX=100\nRATE_LIMIT_API_WINDOW=60\nRATE_LIMIT_AI_MAX=20\nRATE_LIMIT_AI_WINDOW=60\n```\n\nSee [.env.example](.env.example) for all available options.\n\n### 6. Run the Development Server\n\n```bash\nnpm run dev\n```\n\nOpen [http://localhost:3000](http://localhost:3000) in your browser.\n\n### 7. Create Your First User\n\n1. Navigate to [http://localhost:3000/login](http://localhost:3000/login)\n2. Click \"Sign in with Google\" (or GitHub/LinkedIn)\n3. Complete OAuth flow\n4. You'll be redirected to `/dashboard`\n\n### Verify Installation\n\nRun tests to ensure everything is configured correctly:\n\n```bash\nnpm test\n```\n\nYou should see **388+ tests passing**.\n\n---\n\n## Troubleshooting\n\n### \"Supabase client not initialized\"\n- Verify `NEXT_PUBLIC_SUPABASE_URL` and `NEXT_PUBLIC_SUPABASE_ANON_KEY` are set in `.env.local`\n- Restart development server after changing env vars\n\n### \"Failed to fetch portfolios\"\n- Check database schema is created (run `supabase/schema.sql`)\n- Verify RLS policies are enabled in Supabase dashboard\n- Check browser console for specific error messages\n\n### \"AI features not working\"\n- Verify `GROQ_API_KEY` is valid\n- Check Groq API quota at [console.groq.com](https://console.groq.com)\n- Ensure key has permissions for `llama-3.3-70b-versatile` model\n\n### OAuth redirect not working\n- Add `http://localhost:3000` to allowed redirect URLs in OAuth providers\n- Check callback URL is `https://your-project.supabase.co/auth/v1/callback`\n- Enable the provider in Supabase Authentication settings\n\n### Rate limiting errors in production\n- Set up Upstash Redis for distributed rate limiting\n- Or disable rate limiting: `RATE_LIMIT_ENABLED=false`\n\n---\n\n## Project Structure\n\n```\nportfolio-forge/\n├── app/                          # Next.js App Router\n│   ├── (auth)/                   # Authentication pages (login, signup)\n│   ├── api/v1/                   # Versioned API routes\n│   │   ├── ai/                   # AI endpoints (10 routes)\n│   │   ├── portfolios/           # Portfolio CRUD + features\n│   │   ├── certifications/       # Certification management\n│   │   └── tags/                 # Tag system\n│   ├── dashboard/                # Protected dashboard pages\n│   └── p/[token]/                # Public portfolio viewing\n│\n├── components/                   # React components\n│   ├── portfolio-builder/        # Builder UI components\n│   ├── portfolio-sections/       # Section type renderers\n│   ├── portfolio-templates/      # Template components\n│   ├── portfolio-themes/         # Theme providers\n│   ├── certifications/           # Certification UI\n│   └── tags/                     # Tag selector\n│\n├── lib/                          # Core libraries\n│   ├── ai/                       # AI integration layer\n│   │   ├── abilities/            # Single-purpose AI functions\n│   │   ├── agent.ts              # Multi-step AI workflows\n│   │   ├── provider.ts           # Groq API client\n│   │   └── router.ts             # Provider abstraction\n│   ├── api/                      # API utilities\n│   │   ├── client.ts             # Frontend API client\n│   │   ├── route-handler.ts      # Error handling wrapper\n│   │   ├── auth-middleware.ts    # Auth utilities\n│   │   └── rate-limit.ts         # Rate limiting middleware\n│   ├── config/                   # Centralized configuration\n│   ├── validation/               # Zod schemas \u0026 helpers\n│   └── supabase/                 # Supabase client setup\n│\n├── hooks/                        # Custom React hooks\n├── types/                        # TypeScript definitions\n├── docs/                         # Documentation\n│   ├── architecture/             # Design documents\n│   ├── api/                      # API documentation\n│   ├── features/                 # Feature guides\n│   └── examples/                 # Code examples\n│\n├── supabase/                     # Database schema\n│   ├── schema.sql                # Main schema\n│   └── storage-buckets.sql       # Storage configuration\n│\n└── __mocks__/                    # Jest mocks\n```\n\n---\n\n## Documentation\n\n| Document | Description |\n|----------|-------------|\n| [docs/README.md](docs/README.md) | Documentation index |\n| [docs/DEVELOPMENT.md](docs/DEVELOPMENT.md) | Local development guide |\n| [docs/DEPLOYMENT.md](docs/DEPLOYMENT.md) | Production deployment guide |\n| [docs/RATE_LIMITING.md](docs/RATE_LIMITING.md) | Rate limiting configuration |\n| [docs/TODO.md](docs/TODO.md) | Project tasks and progress |\n| [docs/architecture/ARCHITECTURE.md](docs/architecture/ARCHITECTURE.md) | Architecture overview and patterns |\n| [docs/architecture/DIAGRAMS.md](docs/architecture/DIAGRAMS.md) | Visual architecture diagrams |\n| [docs/api/api-versioning.md](docs/api/api-versioning.md) | API versioning strategy |\n| [docs/features/authentication.md](docs/features/authentication.md) | Auth system documentation |\n\n---\n\n## API Reference\n\nAll API routes are under `/api/v1` namespace with rate limiting enabled.\n\n### Portfolios\n\n```\nGET    /api/v1/portfolios              # List user's portfolios\nPOST   /api/v1/portfolios              # Create portfolio\nGET    /api/v1/portfolios/:id          # Get portfolio details\nPATCH  /api/v1/portfolios/:id          # Update portfolio\nDELETE /api/v1/portfolios/:id          # Delete portfolio\nPOST   /api/v1/portfolios/:id/public-link  # Generate public share link\n```\n\n### AI Endpoints (Rate limited: 20/min)\n\n```\nPOST   /api/v1/ai/improve-text               # Improve text with tone\nPOST   /api/v1/ai/generate-summary           # Generate portfolio summary\nPOST   /api/v1/ai/suggest-tags               # Get tag suggestions\nPOST   /api/v1/ai/generate-experience-bullets # Generate bullet points\nPOST   /api/v1/ai/analyze-portfolio          # Analyze portfolio quality\nPOST   /api/v1/ai/recommend-template-theme   # Get recommendations\nPOST   /api/v1/ai/rewrite-portfolio          # Batch rewrite sections\nPOST   /api/v1/ai/optimize-portfolio-for-job # Job-specific optimization\nPOST   /api/v1/ai/generate-portfolio-from-resume # Import from resume\n```\n\n### Certifications\n\n```\nGET    /api/v1/certifications          # List certifications\nPOST   /api/v1/certifications          # Create certification\nGET    /api/v1/certifications/:id      # Get certification\nPATCH  /api/v1/certifications/:id      # Update certification\nDELETE /api/v1/certifications/:id      # Delete certification\n```\n\n---\n\n## Testing\n\n```bash\n# Run all tests\nnpm test\n\n# Run with coverage\nnpm test -- --coverage\n\n# Run specific test file\nnpm test -- --testPathPattern=\"rate-limit\"\n\n# Watch mode\nnpm test -- --watch\n```\n\n**Current Status:** 356+ tests passing (1 skipped)\n\n---\n\n## Development\n\n### Scripts\n\n```bash\nnpm run dev          # Start development server\nnpm run build        # Build for production\nnpm run start        # Start production server\nnpm run lint         # Run ESLint\nnpm test             # Run tests\n```\n\n### Database Setup\n\n1. Create a new Supabase project\n2. Run the schema from `supabase/schema.sql`\n3. Set up storage buckets from `supabase/storage-buckets.sql`\n4. Enable Row-Level Security on all tables\n5. Configure authentication providers\n\n### Generate Types\n\n```bash\nnpx supabase gen types typescript --project-id YOUR_PROJECT_ID \u003e lib/supabase/types.ts\n```\n\n---\n\n## Architecture Highlights\n\n### AI Layer Design\n\n```\n┌─────────────────┐\n│   API Routes    │  HTTP endpoints (/api/v1/ai/*)\n└────────┬────────┘\n         │\n┌────────▼────────┐\n│     Agents      │  Complex multi-step workflows\n└────────┬────────┘\n         │\n┌────────▼────────┐\n│   Abilities     │  Single-purpose AI functions\n└────────┬────────┘\n         │\n┌────────▼────────┐\n│     Router      │  Provider abstraction layer\n└────────┬────────┘\n         │\n┌────────▼────────┐\n│    Provider     │  Groq API integration\n└─────────────────┘\n```\n\n### Request Flow\n\n```\nRequest → Rate Limit → Auth → Validation → Handler → Response\n            ↓            ↓         ↓\n         429 Error   401 Error  400 Error\n```\n\n---\n\n## Security\n\n- **Row-Level Security (RLS)** - All database tables protected\n- **API Authentication** - JWT-based via Supabase Auth\n- **Rate Limiting** - Configurable per endpoint type\n- **Input Validation** - Zod schemas on all routes\n- **Error Handling** - Centralized with no stack trace leakage\n\n---\n\n## Roadmap\n\n### Completed\n- [x] Core portfolio builder\n- [x] 10 AI features\n- [x] API versioning (v1)\n- [x] Rate limiting middleware\n- [x] Zod validation\n- [x] Centralized config\n- [x] Test infrastructure (82 tests)\n\n### In Progress\n- [ ] Component refactoring (split large files)\n- [ ] API client migration in components\n- [ ] Redis-backed rate limiting\n\n### Planned\n- [ ] OpenAPI documentation\n- [ ] Error monitoring (Sentry)\n- [ ] Background job processing\n- [ ] Multi-provider AI support\n- [ ] E2E tests (Playwright)\n\n---\n\n## Contributing\n\n1. Fork the repository\n2. Create a feature branch (`git checkout -b feature/amazing-feature`)\n3. Commit changes (`git commit -m 'Add amazing feature'`)\n4. Push to branch (`git push origin feature/amazing-feature`)\n5. Open a Pull Request\n\nPlease read [CONTRIBUTING.md](CONTRIBUTING.md) for details on our code of conduct and development process.\n\n---\n\n## License\n\nThis project is licensed under the Apache License 2.0 - see the [LICENSE](LICENSE) file for details.\n\n---\n\n## Acknowledgments\n\n- [Next.js](https://nextjs.org/) - React framework\n- [Supabase](https://supabase.com/) - Backend as a service\n- [Groq](https://groq.com/) - AI inference\n- [dnd-kit](https://dndkit.com/) - Drag and drop\n- [Zod](https://zod.dev/) - Schema validation\n- [Tailwind CSS](https://tailwindcss.com/) - Styling\n\n---\n\n\u003cdiv align=\"center\"\u003e\n\n**[Back to top](#portfolio-forge)**\n\nBuilt with Next.js, Supabase, and Groq AI\n\n\u003c/div\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fleonidasdev%2Fportfolio-forge","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fleonidasdev%2Fportfolio-forge","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fleonidasdev%2Fportfolio-forge/lists"}