{"id":48056164,"url":"https://github.com/sethdavis512/prompt-bucket","last_synced_at":"2026-04-04T14:27:57.014Z","repository":{"id":310886966,"uuid":"1041634473","full_name":"sethdavis512/prompt-bucket","owner":"sethdavis512","description":"Professional AI prompt management platform with 10-section methodology, team collaboration, AI scoring, and subscription management. Built with React Router 7, TypeScript, and Prisma.","archived":false,"fork":false,"pushed_at":"2025-09-13T20:43:38.000Z","size":1014,"stargazers_count":0,"open_issues_count":1,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-09-13T22:21:19.889Z","etag":null,"topics":["ai-prompts","ai-tools","better-auth","openai","postgresql","prisma","prompt-engineering","prompt-management","react-router","saas","subscription-management","tailwindcss","team-collaboration","typescript"],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/sethdavis512.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-08-20T19:27:39.000Z","updated_at":"2025-09-13T20:43:42.000Z","dependencies_parsed_at":"2025-08-20T21:33:31.094Z","dependency_job_id":"7df75fc0-a2aa-4a98-8d5e-fa8467db7143","html_url":"https://github.com/sethdavis512/prompt-bucket","commit_stats":null,"previous_names":["sethdavis512/prompt-lab","sethdavis512/prompt-bucket"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/sethdavis512/prompt-bucket","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sethdavis512%2Fprompt-bucket","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sethdavis512%2Fprompt-bucket/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sethdavis512%2Fprompt-bucket/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sethdavis512%2Fprompt-bucket/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sethdavis512","download_url":"https://codeload.github.com/sethdavis512/prompt-bucket/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sethdavis512%2Fprompt-bucket/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31402474,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-04T10:20:44.708Z","status":"ssl_error","status_checked_at":"2026-04-04T10:20:06.846Z","response_time":60,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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":["ai-prompts","ai-tools","better-auth","openai","postgresql","prisma","prompt-engineering","prompt-management","react-router","saas","subscription-management","tailwindcss","team-collaboration","typescript"],"created_at":"2026-04-04T14:27:56.727Z","updated_at":"2026-04-04T14:27:56.886Z","avatar_url":"https://github.com/sethdavis512.png","language":"TypeScript","funding_links":["https://docs.polar.sh"],"categories":[],"sub_categories":[],"readme":"# Iridium\n\nA modern full-stack SaaS boilerplate built with React Router 7, featuring authentication, AI integration, and everything you need to ship quickly.\n\n## 🚀 Features\n\n- **React Router 7** - Config-based routing with SSR\n- **React 19** - Latest React with native meta tag support\n- **Authentication** - BetterAuth with Prisma adapter and session management\n- **RBAC** - Role-based access control (USER/EDITOR/ADMIN) with hierarchical permissions\n- **AI Integration** - OpenAI with Vercel AI SDK for streaming responses\n- **Database** - PostgreSQL with Prisma ORM (custom output path)\n- **Model Layer Pattern** - All database operations abstracted through `app/models/` functions\n- **Styling** - DaisyUI 5 + TailwindCSS v4 with CVA for type-safe variants\n- **TypeScript** - Strict mode with full type safety\n- **Form Handling** - React Hook Form + Zod with server/client validation\n- **Caching** - Three-tier caching strategy: client-side route caching, model layer caching, manual caching\n- **Analytics** - PostHog integration for product analytics and feature flags\n- **Billing** - Polar.sh integration via BetterAuth plugin (optional)\n- **Email** - Resend integration with React Email templates, BetterAuth email flows, and centralized API endpoint\n- **Documentation** - Comprehensive patterns documented in `.github/instructions/`\n\n## 🏗️ Architecture\n\n### Tech Stack\n\n- **Frontend**: React 19, React Router 7, DaisyUI 5, TailwindCSS v4\n- **Backend**: Prisma, PostgreSQL, BetterAuth\n- **AI**: OpenAI with Vercel AI SDK\n- **Analytics**: PostHog (product analytics, feature flags, error tracking)\n- **Styling**: CVA (Class Variance Authority) for type-safe component variants\n- **Forms**: React Hook Form + Zod validation\n- **Caching**: FlatCache with TTL support (three-tier strategy)\n- **Billing**: Polar.sh integration via BetterAuth plugin (optional)\n- **Email**: Resend with React Email templates\n\n### Key Patterns\n\n- **Config-based routing** - All routes defined in `app/routes.ts` (not file-based)\n- **Model layer pattern** - All database operations abstracted through `app/models/` functions (never call Prisma directly in routes)\n- **API-first CRUD** - RESTful endpoints with loaders (GET) and actions (POST/PUT/DELETE)\n- **Middleware architecture** - Auth, logging, and context via layout routes\n- **Singleton services** - Database, auth, AI, cache clients use singleton pattern\n- **Three-tier caching** - Client-side route caching, model layer caching, manual caching with TTL support\n- **RBAC system** - Hierarchical role-based access (USER → EDITOR → ADMIN) with server-side enforcement\n- **CVA components** - Type-safe variants with DaisyUI classes\n- **Custom Prisma output** - Client generated to `app/generated/prisma`\n- **Hybrid validation** - Server + client validation with shared Zod schemas\n- **React 19 meta tags** - Native `\u003ctitle\u003e` and `\u003cmeta\u003e` elements (no `meta()` export)\n- **Comprehensive docs** - All patterns documented in `.github/instructions/*.instructions.md`\n\n## 🛠️ Setup\n\n### Prerequisites\n\n- Node.js 20+\n- PostgreSQL database\n- OpenAI API key (optional, for AI features)\n\n### Installation\n\n1. **Clone and install dependencies**\n\n    ```bash\n    git clone \u003cyour-repo\u003e\n    cd iridium\n    npm install\n    ```\n\n2. **Set up environment variables**\n\n    ```bash\n    cp .env.example .env\n    ```\n\n    Edit `.env` with your values:\n    - `DATABASE_URL` - PostgreSQL connection string\n    - `BETTER_AUTH_SECRET` - Random secret (min 32 characters) for session encryption\n    - `BETTER_AUTH_URL` - Your app URL (`http://localhost:5173` for dev)\n    - `OPENAI_API_KEY` - Your OpenAI API key (optional)\n    - `POSTHOG_API_KEY` - PostHog API key for client-side analytics (optional)\n    - `POSTHOG_PROJECT_ID` - PostHog project ID (optional)\n    - `POSTHOG_PERSONAL_API_KEY` - PostHog personal API key for server-side operations (optional)\n    - `POLAR_ACCESS_TOKEN` - Polar.sh access token (optional, for billing)\n    - `POLAR_SERVER` - \"sandbox\" or \"production\" (optional)\n    - `POLAR_SUCCESS_URL` - Checkout success redirect URL (optional)\n    - `POLAR_WEBHOOK_SECRET` - Polar webhook secret (optional)\n    - `RESEND_API_KEY` - Resend API key for sending emails (required)\n    - `RESEND_FROM_EMAIL` - Default sender email address (optional, defaults to `onboarding@resend.dev`)\n\n3. **Set up the database**\n\n    ```bash\n    npx prisma generate\n    npx prisma migrate deploy\n    npm run seed\n    ```\n\n4. **Start development server**\n\n    ```bash\n    npm run dev\n    ```\n\n    The app will be available at `http://localhost:5173`\n\n## 📁 Project Structure\n\n```text\napp/\n├── components/           # UI components (CVA-based with DaisyUI)\n│   ├── Button.tsx       # Canonical CVA component example\n│   ├── TextInput.tsx    # Form input pattern\n│   ├── Card.tsx, Modal.tsx, etc.\n├── constants/\n│   └── index.ts         # Path constants enum\n├── emails/              # React Email templates\n│   ├── verification-email.tsx\n│   ├── password-reset-email.tsx\n│   ├── welcome-email.tsx\n│   └── transactional-email.tsx\n├── generated/\n│   └── prisma/          # Prisma client (custom output path)\n├── hooks/\n│   ├── useAuthenticatedContext.ts\n│   └── useUserRole.ts   # RBAC hooks (client-side only)\n├── lib/\n│   ├── auth.server.ts        # BetterAuth configuration (with Polar plugin)\n│   ├── auth-client.ts        # Client-side auth\n│   ├── session.server.ts     # Session helpers (requireUser, requireRole, etc.)\n│   ├── ai.ts                 # OpenAI client singleton\n│   ├── cache.ts              # FlatCache with three-tier caching utilities\n│   ├── polar.server.ts       # Polar SDK client singleton\n│   ├── resend.server.ts      # Resend SDK client singleton\n│   ├── form-hooks.ts         # useValidatedForm hook\n│   ├── form-validation.server.ts  # Server-side form validation\n│   └── validations.ts        # Zod schemas\n├── middleware/\n│   ├── auth.ts               # Authentication middleware\n│   ├── context.ts            # React Router contexts\n│   └── logging.ts            # Request logging\n├── models/                   # Model layer (data access layer)\n│   ├── user.server.ts        # User CRUD operations\n│   ├── email.server.ts       # Email operations (Resend)\n│   └── feature-flags.server.ts  # PostHog feature flags with caching\n├── routes/\n│   ├── api/\n│   │   ├── auth/\n│   │   │   ├── authenticate.ts   # Central auth endpoint\n│   │   │   └── better-auth.ts    # BetterAuth handler\n│   │   ├── posthog/\n│   │   │   └── feature-flags.server.ts  # Feature flags API\n│   │   ├── email.server.ts       # Email API (send from anywhere)\n│   │   └── profile.server.ts     # Profile API (canonical CRUD example)\n│   ├── admin/\n│   │   └── design.tsx            # Component showcase\n│   ├── authenticated.tsx         # Protected layout with middleware\n│   ├── dashboard.tsx             # User dashboard\n│   ├── profile.tsx               # User profile page\n│   ├── home.tsx                  # Landing page\n│   ├── about.tsx                 # About page\n│   ├── sign-in.tsx               # Sign in page\n│   └── sign-out.tsx              # Sign out handler\n├── types/\n│   └── posthog.ts        # PostHog type definitions\n├── cva.config.ts         # CVA utilities (cx, cva, compose)\n├── db.server.ts          # Prisma client singleton\n├── env.d.ts              # TypeScript environment types\n└── routes.ts             # Config-based routing (single source of truth)\n\nprisma/\n├── schema.prisma         # Database schema\n├── seed.ts              # Database seeding\n└── migrations/          # Migration history\n```\n\n## 🔧 Configuration\n\n### Routing\n\nRoutes are configured in `app/routes.ts` using React Router 7's config-based approach:\n\n```typescript\nexport default [\n    index('routes/home.tsx'),\n    route(Paths.ABOUT, 'routes/about.tsx'),\n    route(Paths.SIGN_IN, 'routes/sign-in.tsx'),\n    layout('routes/authenticated.tsx', [\n        route(Paths.DASHBOARD, 'routes/dashboard.tsx'),\n        route(Paths.PROFILE, 'routes/profile.tsx'),\n        ...prefix('admin', [route('/design', 'routes/admin/design.tsx')]),\n    ]),\n    ...prefix('api', [\n        route('authenticate', 'routes/api/auth/authenticate.ts'),\n        route('auth/*', 'routes/api/auth/better-auth.ts'),\n        route('profile', 'routes/api/profile.ts'),\n    ]),\n] satisfies RouteConfig;\n```\n\n**Important**: After adding/modifying routes, run `npm run typecheck` to generate route types.\n\n### Authentication\n\nBetterAuth is configured with:\n\n- Email/password authentication\n- Prisma adapter with PostgreSQL\n- 7-day session expiry\n- Session helpers: `requireUser()`, `getUserFromSession()`, `requireAnonymous()`\n- Middleware-based route protection via layout files\n- Central authentication endpoint at `/api/authenticate`\n\n### Database Schema\n\nThe Prisma schema includes:\n\n- **User model** - Email, name, profile fields (bio, website, location, phoneNumber)\n- **BetterAuth models** - Account, Session, Verification\n- **Custom output path** - Client generated to `app/generated/prisma` (not default location)\n\n## 🎯 Usage Examples\n\n### Adding a New Protected Route\n\n1. Add route to authenticated layout in `app/routes.ts`:\n\n    ```typescript\n    layout('routes/authenticated.tsx', [\n        route('new-feature', 'routes/new-feature.tsx'),\n    ]);\n    ```\n\n2. Create route file `app/routes/new-feature.tsx`:\n\n    ```tsx\n    import type { Route } from './+types/new-feature';\n    import { useAuthenticatedContext } from '~/hooks/useAuthenticatedContext';\n\n    export default function NewFeature() {\n        const { user } = useAuthenticatedContext();\n        return (\n            \u003c\u003e\n                \u003ctitle\u003eNew Feature - Iridium\u003c/title\u003e\n                \u003ch1\u003eWelcome {user.email}\u003c/h1\u003e\n            \u003c/\u003e\n        );\n    }\n    ```\n\n3. Run `npm run typecheck` to generate route types\n\n### Adding API Endpoints\n\n1. Add route to `api` prefix in `app/routes.ts`:\n\n    ```typescript\n    ...prefix(\"api\", [\n      route(\"new-endpoint\", \"routes/api/new-endpoint.ts\")\n    ])\n    ```\n\n2. Create handler in `app/routes/api/new-endpoint.ts`:\n\n    ```typescript\n    import type { Route } from './+types/new-endpoint';\n    import { data } from 'react-router';\n    import { requireUser } from '~/lib/session.server';\n\n    export async function action({ request }: Route.ActionArgs) {\n        const user = await requireUser(request);\n        // Handle request\n        return data({ success: true });\n    }\n    ```\n\n### Creating UI Components\n\nFollow the CVA + DaisyUI pattern (see `app/components/Button.tsx`):\n\n```typescript\nimport type { VariantProps } from \"cva\";\nimport { cva, cx } from \"~/cva.config\";\n\nexport const buttonVariants = cva({\n  base: \"btn\",\n  variants: {\n    status: {\n      primary: \"btn-primary\",\n      secondary: \"btn-secondary\"\n    },\n    size: { sm: \"btn-sm\", md: \"btn-md\", lg: \"btn-lg\" }\n  },\n  defaultVariants: { status: \"primary\", size: \"md\" }\n});\n\ninterface ButtonProps\n  extends React.ButtonHTMLAttributes\u003cHTMLButtonElement\u003e,\n    VariantProps\u003ctypeof buttonVariants\u003e {}\n\nexport function Button({ status, size, className, ...props }: ButtonProps) {\n  return \u003cbutton className={cx(buttonVariants({ status, size }), className)} {...props} /\u003e;\n}\n```\n\n### Using Form Validation\n\nUse the hybrid validation pattern with React Hook Form + Zod:\n\n```typescript\nimport { useValidatedForm } from \"~/lib/form-hooks\";\nimport { signInSchema } from \"~/lib/validations\";\n\nexport default function SignIn() {\n  const fetcher = useFetcher();\n  const { register, handleSubmit, formState: { errors } } = useValidatedForm({\n    resolver: zodResolver(signInSchema),\n    fetcher\n  });\n\n  return (\n    \u003cfetcher.Form method=\"post\" onSubmit={handleSubmit}\u003e\n      \u003cTextInput {...register(\"email\")} error={errors.email?.message} /\u003e\n      \u003cButton type=\"submit\"\u003eSign In\u003c/Button\u003e\n    \u003c/fetcher.Form\u003e\n  );\n}\n```\n\n## 📖 Documentation\n\nThis project includes comprehensive pattern documentation in `.github/instructions/`:\n\n### Core Patterns\n\n- **`caching-pattern.instructions.md`** - Three-tier caching strategy (client-side, model layer, manual)\n- **`crud-pattern.instructions.md`** - API-first CRUD implementation patterns\n- **`form-validation.instructions.md`** - Universal form validation with React Hook Form + Zod\n- **`role-based-access.instructions.md`** - RBAC patterns with hierarchical roles\n\n### Framework-Specific\n\n- **`better-auth.instructions.md`** - Authentication flows and session management\n- **`react-router.instructions.md`** - Config-based routing patterns\n- **`prisma.instructions.md`** - Database patterns and custom Prisma configuration\n\n### Component Development\n\n- **`component-patterns.instructions.md`** - CVA-based component patterns with DaisyUI\n- **`cva.instructions.md`** - Class Variance Authority usage\n- **`daisyui.instructions.md`** - DaisyUI component library integration\n\n### Integrations\n\n- **`polar.instructions.md`** - Polar billing integration via BetterAuth plugin\n- **`posthog.instructions.md`** - PostHog analytics, feature flags, and error tracking\n- **`resend.instructions.md`** - Resend email integration with React Email templates and BetterAuth\n\nAll patterns include:\n\n- Complete code examples\n- Best practices and anti-patterns\n- Reference implementations\n- Troubleshooting guides\n\n## 🚀 Deployment\n\n**Ready to deploy?** Choose your path:\n\n### ⚡ Quick Start (5 Minutes)\n\nFollow the [Deployment Quick Start](./docs/deployment-quick-start.md) for Railway:\n\n```bash\nrailway login \u0026\u0026 railway init \u0026\u0026 railway add --plugin postgresql\nrailway variables set BETTER_AUTH_SECRET=$(openssl rand -base64 32)\nrailway variables set RESEND_API_KEY=your_key\nrailway up \u0026\u0026 railway run npx prisma migrate deploy\n```\n\n### 📖 Comprehensive Guide\n\nSee the full [Deployment Guide](./docs/deployment.md) for:\n\n- **Railway** - Recommended for beginners (PostgreSQL included, automatic SSL)\n- **Docker** - Self-hosted or custom infrastructure\n- **Vercel** - Serverless deployment (with limitations)\n\n### Essential Environment Variables\n\n```env\nDATABASE_URL=postgresql://...              # Your PostgreSQL connection\nBETTER_AUTH_SECRET=\u003cmin-32-chars\u003e         # Generate: openssl rand -base64 32\nBETTER_AUTH_URL=https://yourdomain.com    # Your production URL\nRESEND_API_KEY=re_...                     # From resend.com (required)\nRESEND_FROM_EMAIL=noreply@yourdomain.com  # Verified sender (required)\n```\n\n**Optional variables** for AI, analytics, and billing - see [Environment Variables Reference](./docs/deployment.md#environment-variables-reference).\n\n### Post-Deployment\n\nAfter deploying, verify:\n\n- ✅ App loads without errors\n- ✅ Sign up/sign in works\n- ✅ Email verification sends\n- ✅ Protected routes require auth\n- ✅ Database migrations applied\n\nFull checklist: [Post-Deployment Checklist](./docs/deployment.md#post-deployment-checklist)\n\n### Database Migrations\n\n```bash\nnpx prisma migrate deploy\n```\n\n### Important Notes\n\n- Run `npx prisma generate` after deploying if schema changed\n- Ensure custom Prisma output path (`app/generated/prisma`) is included in build\n- Set `NODE_ENV=production` for optimal performance\n\n## 📚 Learn More\n\n- [React Router 7 Docs](https://reactrouter.com) - Config-based routing documentation\n- [BetterAuth Docs](https://better-auth.com) - Authentication setup and configuration\n- [Prisma Docs](https://prisma.io/docs) - Database and ORM documentation\n- [PostHog Docs](https://posthog.com/docs) - Analytics, feature flags, and error tracking\n- [DaisyUI Docs](https://daisyui.com) - Component library and theming\n- [CVA Docs](https://cva.style) - Class variance authority patterns\n- [Vercel AI SDK](https://sdk.vercel.ai) - AI integration and streaming\n- [React Hook Form](https://react-hook-form.com) - Form validation patterns\n- [Zod Docs](https://zod.dev) - Schema validation\n- [Polar.sh Docs](https://docs.polar.sh) - Billing integration (optional)\n- [Resend Docs](https://resend.com/docs) - Email service integration\n- [React Email Docs](https://react.email/docs) - Email template development\n\n## 🤝 Contributing\n\n1. Fork the repository\n2. Create a feature branch (`git checkout -b feature/amazing-feature`)\n3. Make your changes following the established patterns\n4. Run `npm run typecheck` to ensure no errors\n5. Run `npm run build` to verify production build\n6. Commit your changes (`git commit -m 'Add amazing feature'`)\n7. Push to the branch (`git push origin feature/amazing-feature`)\n8. Open a Pull Request\n\n### Development Guidelines\n\n- **Never** call Prisma directly in routes - use model layer functions from `app/models/`\n- Follow the API-first CRUD pattern for all data operations\n- Use config-based routing in `app/routes.ts` (never file-based routing)\n- Follow the CVA + DaisyUI component pattern for all UI components\n- Use server-side role checks (`requireRole`, `requireEditor`, `requireAdmin`) for authorization\n- Implement three-tier caching where appropriate (client-side, model layer, or manual)\n- Use middleware for layout-level route protection (not individual auth checks)\n- Run `npm run typecheck` after route changes to generate types\n- Import Prisma types from `~/generated/prisma/client`\n- Reference `.github/instructions/*.instructions.md` for comprehensive patterns and best practices\n\n## 📄 License\n\nMIT License - see LICENSE file for details\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsethdavis512%2Fprompt-bucket","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsethdavis512%2Fprompt-bucket","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsethdavis512%2Fprompt-bucket/lists"}