### Environment Variables Setup (Bash) Source: https://github.com/lutfykumar/ai-invitation-saas/blob/main/README.md Guides users on setting up environment variables by copying the example file and modifying it as needed. ```bash cp .env.example .env ``` -------------------------------- ### Database Setup with Docker (Bash) Source: https://github.com/lutfykumar/ai-invitation-saas/blob/main/README.md Commands to manage PostgreSQL database setup using Docker, including starting the service and pushing schema changes. ```bash npm run db:up npm run db:push ``` -------------------------------- ### Start Development Server (Bash) Source: https://github.com/lutfykumar/ai-invitation-saas/blob/main/README.md Commands to start the development server using npm, yarn, or pnpm, leveraging Turbopack for faster builds. ```bash npm run dev # or yarn dev # or pnpm dev ``` -------------------------------- ### Clone Repository and Install Dependencies (Bash) Source: https://github.com/lutfykumar/ai-invitation-saas/blob/main/README.md Instructions to clone the project repository and install its dependencies using npm, yarn, or pnpm. ```bash git clone cd codeguide-starter-fullstack npm install # or yarn install # or pnpm install ``` -------------------------------- ### Docker Compose Development Workflow Source: https://github.com/lutfykumar/ai-invitation-saas/blob/main/README.md Examples of using Docker Compose and npm scripts to manage the development environment. This includes starting the full application stack or just the database for local application development. Dependencies: Docker, Docker Compose, Node.js, npm. ```bash # Start the entire stack (recommended for new users) npm run docker:up # View logs npm run docker:logs # Stop everything npm run docker:down # Option 1: Database only (develop app locally) npm run db:up # Start PostgreSQL npm run dev # Start Next.js development server # Option 2: Full Docker stack npm run docker:up # Start both app and database ``` -------------------------------- ### Example Project Structure (File Paths) Source: https://github.com/lutfykumar/ai-invitation-saas/blob/main/README.md Illustrates the directory and file structure of the Codeguide Starter Fullstack project, highlighting key directories like app/, components/, and db/. ```file codeguide-starter-fullstack/ ├── app/ # Next.js app router pages │ ├── globals.css # Global styles with dark mode │ ├── layout.tsx # Root layout with providers │ └── page.tsx # Main page ├── components/ # React components │ └── ui/ # shadcn/ui components (40+) ├── db/ # Database configuration │ ├── index.ts # Database connection │ └── schema/ # Database schemas ├── docker/ # Docker configuration │ └── postgres/ # PostgreSQL initialization ├── hooks/ # Custom React hooks ├── lib/ # Utility functions │ ├── auth.ts # Better Auth configuration │ └── utils.ts # General utilities ├── auth-schema.ts # Authentication schema ├── docker-compose.yml # Docker services configuration ├── Dockerfile # Application container definition ├── drizzle.config.ts # Drizzle configuration └── components.json # shadcn/ui configuration ``` -------------------------------- ### Development Commands (Bash) Source: https://github.com/lutfykumar/ai-invitation-saas/blob/main/README.md Common development commands for the application, including starting the development server, building for production, and running ESLint. ```bash npm run dev npm run build npm start npm run lint ``` -------------------------------- ### Start a Task with task-manager Source: https://github.com/lutfykumar/ai-invitation-saas/blob/main/CLAUDE.md This command marks a specific task as 'in progress'. It is a mandatory step that must be executed before any implementation work begins on a task. ```bash task-manager start-task ``` -------------------------------- ### List Available Tasks with task-manager Source: https://github.com/lutfykumar/ai-invitation-saas/blob/main/CLAUDE.md This command is used to discover and view all available tasks within the task management system. It's the mandatory first step before starting any task. ```bash task-manager list-tasks ``` -------------------------------- ### Production Environment Variables Example Source: https://github.com/lutfykumar/ai-invitation-saas/blob/main/README.md An example of essential environment variables required for a production deployment. These variables configure database connections, authentication secrets, and application URLs. Input: A `.env` file or environment variable configuration. Output: A configured application instance. ```env # Required for production DATABASE_URL=postgresql://user:password@host:port/database BETTER_AUTH_SECRET=generate-a-very-secure-32-character-key BETTER_AUTH_URL=https://yourdomain.com # Optional optimizations NODE_ENV=production ``` -------------------------------- ### Local Database Configuration (Environment Variables) Source: https://github.com/lutfykumar/ai-invitation-saas/blob/main/README.md Example environment variable configuration for connecting to a local PostgreSQL database, including credentials and database name. ```env DATABASE_URL=postgresql://username:password@localhost:5432/database_name POSTGRES_DB=your_database_name POSTGRES_USER=your_username POSTGRES_PASSWORD=your_password ``` -------------------------------- ### Environment Variables for Production/Local (Env) Source: https://github.com/lutfykumar/ai-invitation-saas/blob/main/README.md Example `.env` file content for database configuration and Better Auth settings, with default values suitable for Docker. ```env # Database Configuration (defaults work with Docker) DATABASE_URL=postgresql://postgres:postgres@localhost:5433/postgres POSTGRES_DB=postgres POSTGRES_USER=postgres POSTGRES_PASSWORD=postgres # Authentication BETTER_AUTH_SECRET=your_secret_key_here BETTER_AUTH_URL=http://localhost:3000 NEXT_PUBLIC_BETTER_AUTH_URL=http://localhost:3000 ``` -------------------------------- ### GET /api/themes - Get Themes Source: https://context7.com/lutfykumar/ai-invitation-saas/llms.txt Retrieves themed templates with optional category filtering for invitation styling. Results are ordered alphabetically by theme name. ```APIDOC ## GET /api/themes ### Description Retrieves themed templates with optional category filtering for invitation styling. The results are ordered alphabetically by theme name. ### Method GET ### Endpoint /api/themes ### Parameters #### Query Parameters - **categoryId** (string) - Optional - Filters themes by a specific category ID. ### Request Example ``` GET /api/themes GET /api/themes?categoryId=550e8400-e29b-41d4-a716-446655440000 ``` ### Response #### Success Response (200 OK) - Returns an array of active themes, optionally filtered by category. - **id** (string) - Unique identifier for the theme. - **name** (string) - The name of the theme. - **description** (string) - A description of the theme. - **slug** (string) - A URL-friendly identifier for the theme. - **thumbnail** (string) - URL path to the theme's thumbnail image. - **categoryId** (string) - The ID of the category this theme belongs to. - **category** (object) - An object containing details of the associated category. - **id** (string) - Category ID. - **name** (string) - Category name. - **slug** (string) - Category slug. #### Response Example ```json [ { "id": "660e8400-e29b-41d4-a716-446655440001", "name": "Elegant Rose", "description": "Classic rose-themed design with elegant typography", "slug": "elegant-rose", "thumbnail": "/themes/elegant-rose.jpg", "categoryId": "550e8400-e29b-41d4-a716-446655440000", "category": { "id": "550e8400-e29b-41d4-a716-446655440000", "name": "Wedding", "slug": "wedding" } } ] ``` ### Notes - Only returns active themes (`isActive: true`). - Includes category relationship data. - Ordered alphabetically by theme name. ``` -------------------------------- ### Production Deployment with Docker Compose Source: https://github.com/lutfykumar/ai-invitation-saas/blob/main/README.md Steps for deploying the application using Docker Compose on a VPS or server. This involves cloning the repository, configuring environment variables in a `.env` file, and starting the application stack. Dependencies: Docker, Docker Compose, Git, npm. ```bash git clone cd codeguide-starter-fullstack cp .env.example .env # Edit .env with production values # DATABASE_URL=postgresql://postgres:your_secure_password@postgres:5432/postgres # POSTGRES_DB=postgres # POSTGRES_USER=postgres # POSTGRES_PASSWORD=your_secure_password # BETTER_AUTH_SECRET=your-very-secure-secret-key # BETTER_AUTH_URL=https://yourdomain.com # NEXT_PUBLIC_BETTER_AUTH_URL=https://yourdomain.com npm run docker:up ``` -------------------------------- ### Docker Compose Profile for Development Database Source: https://github.com/lutfykumar/ai-invitation-saas/blob/main/README.md Demonstrates how to start a specific Docker profile for the development database using docker-compose CLI or an npm script. This allows for isolated development database instances. Dependencies: Docker, Docker Compose, npm. ```bash # Start development database on port 5433 docker-compose --profile dev up postgres-dev -d # Or use the npm script npm run db:dev ``` -------------------------------- ### Complete a Task with task-manager Source: https://github.com/lutfykumar/ai-invitation-saas/blob/main/CLAUDE.md This command marks a task as successfully completed. A brief description of the work done must be provided. This is a mandatory step after implementation. ```bash task-manager complete-task "Brief description of what was implemented" ``` -------------------------------- ### GET /api/invitations Source: https://context7.com/lutfykumar/ai-invitation-saas/llms.txt Retrieves all invitations owned by the authenticated user with joined category and theme data. ```APIDOC ## GET /api/invitations ### Description Retrieves all invitations owned by the authenticated user with joined category and theme data. ### Method GET ### Endpoint /api/invitations ### Parameters #### Headers - **Cookie** (string) - Required - Session cookie for authentication (e.g., `session=...`). ### Response #### Success Response (200 OK) Returns an array of invitation objects. Each object includes details about the invitation, its category, and its theme. - **id** (string) - The unique identifier for the invitation. - **title** (string) - The title of the invitation. - **content** (string) - The main content of the invitation. - **eventDate** (string) - The date and time of the event (ISO 8601 format). - **eventLocation** (string) - The location of the event. - **slug** (string) - A unique slug for the invitation's public page. - **isPublished** (boolean) - Indicates if the invitation is published. - **viewCount** (integer) - The number of views the invitation has received. - **createdAt** (string) - The timestamp when the invitation was created (ISO 8601 format). - **updatedAt** (string) - The timestamp when the invitation was last updated (ISO 8601 format). - **category** (object) - Details about the invitation's category. - **id** (string) - The category ID. - **name** (string) - The category name. - **slug** (string) - The category slug. - **theme** (object) - Details about the invitation's theme. - **id** (string) - The theme ID. - **name** (string) - The theme name. - **slug** (string) - The theme slug. - **thumbnail** (string) - The URL to the theme's thumbnail image. #### Response Example ```json [ { "id": "770e8400-e29b-41d4-a716-446655440002", "title": "Sarah & John's Wedding", "content": "You are cordially invited...", "eventDate": "2025-12-15T14:00:00.000Z", "eventLocation": "Grand Ballroom, Downtown Hotel", "slug": "a8B3xY9z-1735128000000", "isPublished": true, "viewCount": 45, "createdAt": "2025-10-29T10:30:00.000Z", "updatedAt": "2025-10-29T11:00:00.000Z", "category": { "id": "550e8400-e29b-41d4-a716-446655440000", "name": "Wedding", "slug": "wedding" }, "theme": { "id": "660e8400-e29b-41d4-a716-446655440001", "name": "Elegant Rose", "slug": "elegant-rose", "thumbnail": "/themes/elegant-rose.jpg" } } ] ``` ### Notes - Invitations are ordered by `createdAt` in descending order. - Returns an empty array `[]` if the user has no invitations. ``` -------------------------------- ### Database Management Commands Source: https://github.com/lutfykumar/ai-invitation-saas/blob/main/README.md A set of npm scripts for managing the PostgreSQL database. These commands facilitate starting, stopping, and resetting the database, as well as handling schema changes and migrations. Dependencies include Node.js and npm with a configured PostgreSQL environment (potentially Docker). ```bash npm run db:up npm run db:down npm run db:dev npm run db:dev-down npm run db:push npm run db:generate npm run db:studio npm run db:reset ``` -------------------------------- ### Dockerfile Health Check Configuration Source: https://github.com/lutfykumar/ai-invitation-saas/blob/main/README.md Example of adding a HEALTHCHECK instruction to a Dockerfile to monitor the application's status. This command periodically checks if the application is running and responsive on its defined port. Dependencies: Dockerfile, curl. ```dockerfile # In Dockerfile, add health check HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \ CMD curl -f http://localhost:3000/api/health || exit 1 ``` -------------------------------- ### Password Hashing with Argon2/bcrypt Source: https://github.com/lutfykumar/ai-invitation-saas/blob/main/documentation/security_guideline_document.md Illustrates secure password storage by hashing passwords using strong algorithms like Argon2 or bcrypt. It emphasizes the use of a unique salt per user to enhance security against rainbow table attacks. Note: This is a conceptual example; actual implementation requires a crypto library. ```plaintext // Conceptual Example: // const salt = generateSalt(); // const hashedPassword = argon2.hash(password, salt); // store(user_id, { hashedPassword, salt }); // Or using bcrypt: // const salt = bcrypt.genSaltSync(10); // const hashedPassword = bcrypt.hashSync(password, salt); ``` -------------------------------- ### Get Themed Invitation Templates Source: https://context7.com/lutfykumar/ai-invitation-saas/llms.txt Retrieves themed templates for invitation styling, with an optional filter by category ID. The response includes theme details and their associated category. Only active themes are returned and ordered alphabetically. ```typescript // GET /api/themes // Optional query: ?categoryId=550e8400-e29b-41d4-a716-446655440000 // Response (200 OK): [ { "id": "660e8400-e29b-41d4-a716-446655440001", "name": "Elegant Rose", "description": "Classic rose-themed design with elegant typography", "slug": "elegant-rose", "thumbnail": "/themes/elegant-rose.jpg", "categoryId": "550e8400-e29b-41d4-a716-446655440000", "category": { "id": "550e8400-e29b-41d4-a716-446655440000", "name": "Wedding", "slug": "wedding" } }, { "id": "661e8400-e29b-41d4-a716-446655440005", "name": "Modern Minimalist", "description": "Clean and contemporary design with subtle colors", "slug": "modern-minimalist", "thumbnail": "/themes/modern-minimalist.jpg", "categoryId": "550e8400-e29b-41d4-a716-446655440000", "category": { "id": "550e8400-e29b-41d4-a716-446655440000", "name": "Wedding", "slug": "wedding" } } ] // Filtered by categoryId if provided // Only returns active themes (isActive: true) // Includes category relationship data // Ordered alphabetically by theme name ``` -------------------------------- ### GET /api/invitations/[id] Source: https://context7.com/lutfykumar/ai-invitation-saas/llms.txt Retrieves complete invitation details for the authenticated owner, including associated theme templates and CSS. This endpoint is restricted to the invitation's owner. ```APIDOC ## GET /api/invitations/[id] ### Description Retrieves complete invitation details with theme template and CSS for authenticated owner. ### Method GET ### Endpoint `/api/invitations/[id]` ### Parameters #### Path Parameters - **id** (string) - Required - The unique identifier of the invitation to retrieve. ### Response #### Success Response (200) - **id** (string) - The invitation's unique identifier. - **title** (string) - The invitation's title. - **content** (string) - The main content of the invitation. - **eventDate** (string) - The date and time of the event. - **eventLocation** (string) - The location of the event. - **recipientEmail** (string) - The email of the recipient. - **recipientName** (string) - The name of the recipient. - **senderName** (string) - The name of the sender. - **customMessage** (string) - A custom message for the invitation. - **slug** (string) - A unique slug for the invitation. - **isPublished** (boolean) - Indicates if the invitation is published. - **viewCount** (integer) - The number of times the invitation has been viewed. - **createdAt** (string) - The timestamp when the invitation was created. - **updatedAt** (string) - The timestamp of the last update. - **userId** (string) - The ID of the user who owns the invitation. - **category** (object) - Details about the invitation's category. - **id** (string) - Category ID. - **name** (string) - Category name. - **slug** (string) - Category slug. - **theme** (object) - Details about the invitation's theme. - **id** (string) - Theme ID. - **name** (string) - Theme name. - **slug** (string) - Theme slug. - **cssVariables** (string) - CSS variables for theme customization. - **templateHtml** (string) - HTML template for the invitation. #### Response Example ```json { "id": "770e8400-e29b-41d4-a716-446655440002", "title": "Sarah & John's Wedding", "content": "You are cordially invited to celebrate our special day", "eventDate": "2025-12-15T14:00:00.000Z", "eventLocation": "Grand Ballroom, Downtown Hotel", "recipientEmail": "smith@example.com", "recipientName": "Mr. & Mrs. Smith", "senderName": "Sarah & John", "customMessage": "We look forward to celebrating with you!", "slug": "a8B3xY9z-1735128000000", "isPublished": true, "viewCount": 45, "createdAt": "2025-10-29T10:30:00.000Z", "updatedAt": "2025-10-29T11:00:00.000Z", "userId": "user_123", "category": { "id": "550e8400-e29b-41d4-a716-446655440000", "name": "Wedding", "slug": "wedding" }, "theme": { "id": "660e8400-e29b-41d4-a716-446655440001", "name": "Elegant Rose", "slug": "elegant-rose", "cssVariables": "{\"--primary\":\"#ff6b9d\",\"--background\":\"#fff8fa\"}", "templateHtml": "
...
" } } ``` #### Error Responses - **404 Not Found** - Invitation doesn't exist or user is not the owner. ``` -------------------------------- ### Content Security Policy (CSP) Configuration Source: https://github.com/lutfykumar/ai-invitation-saas/blob/main/documentation/security_guideline_document.md Defines a strict Content Security Policy (CSP) to mitigate cross-site scripting (XSS) attacks by controlling the resources the browser is allowed to load. This example sets default sources to self, allows scripts from a specific CDN, permits inline styles, and restricts frames and objects. ```http Content-Security-Policy: default-src 'self'; script-src 'self' https://cdn.vercel.ai; style-src 'self' 'unsafe-inline'; img-src 'self' data:; frame-ancestors 'none'; object-src 'none'; ``` -------------------------------- ### Database Schema: Invitation Management (TypeScript) Source: https://context7.com/lutfykumar/ai-invitation-saas/llms.txt Defines a type-safe Drizzle ORM schema for managing invitations. It includes examples for creating and querying invitations. The schema details fields like title, content, event details, and foreign key relationships to user, category, and theme. It also specifies type inference for insert and full records. ```typescript import { invitation, type Invitation, type NewInvitation } from "@/db"; import { db } from "@/db"; import { eq } from "drizzle-orm"; // Create invitation: const newInvitation: NewInvitation = { title: "Wedding Invitation", content: "Join us for our special day...", eventDate: new Date("2025-12-15"), eventLocation: "Grand Ballroom", slug: "unique-slug-123", userId: "user_123", categoryId: "cat_uuid", themeId: "theme_uuid", isPublished: false, }; const [created] = await db .insert(invitation) .values(newInvitation) .returning(); // Query invitation: const invitations = await db .select() .from(invitation) .where(eq(invitation.userId, "user_123")); // Type inference: // Invitation = full record with defaults // NewInvitation = insert type (optional defaults) // Schema fields: // - id: uuid (primary key, auto-generated) // - title, content: text (required) // - eventDate: timestamp (optional) // - eventLocation, recipientEmail, recipientName: text (optional) // - senderName, customMessage: text (optional) // - slug: text unique (required) // - isPublished: boolean (default false) // - viewCount: integer (default 0) // - userId: text (foreign key to user.id, cascade delete) // - categoryId: uuid (foreign key, restrict delete) // - themeId: uuid (foreign key, restrict delete) // - createdAt, updatedAt: timestamp (auto-managed) ``` -------------------------------- ### GET /api/categories - Get Categories Source: https://context7.com/lutfykumar/ai-invitation-saas/llms.txt Retrieves all active event categories for invitation classification. Categories are ordered alphabetically by name. ```APIDOC ## GET /api/categories ### Description Retrieves all active event categories for invitation classification. The categories are ordered alphabetically by name. ### Method GET ### Endpoint /api/categories ### Parameters None ### Request Example ``` GET /api/categories ``` ### Response #### Success Response (200 OK) - Returns an array of active event categories. - **id** (string) - Unique identifier for the category. - **name** (string) - The name of the category. - **description** (string) - A brief description of the category. - **slug** (string) - A URL-friendly identifier for the category. - **isActive** (boolean) - Indicates if the category is active. - **createdAt** (string) - Timestamp of when the category was created. - **updatedAt** (string) - Timestamp of when the category was last updated. #### Response Example ```json [ { "id": "550e8400-e29b-41d4-a716-446655440000", "name": "Wedding", "description": "Wedding ceremonies and receptions", "slug": "wedding", "isActive": true, "createdAt": "2025-01-01T00:00:00.000Z", "updatedAt": "2025-01-01T00:00:00.000Z" }, { "id": "551e8400-e29b-41d4-a716-446655440004", "name": "Celebration", "description": "Birthdays and special celebrations", "slug": "celebration", "isActive": true, "createdAt": "2025-01-01T00:00:00.000Z", "updatedAt": "2025-01-01T00:00:00.000Z" } ] ``` ### Notes - Only returns categories where `isActive` is true. - Ordered alphabetically by name. - No authentication required. ``` -------------------------------- ### Vercel Deployment and Configuration Source: https://github.com/lutfykumar/ai-invitation-saas/blob/main/README.md Instructions for deploying the application to Vercel and setting up necessary environment variables. This option is suitable for frontend-heavy applications or those leveraging Vercel's serverless functions. Dependencies: Vercel CLI, Node.js, npm. ```bash npm i -g vercel vercel # Add environment variables in Vercel dashboard: # - DATABASE_URL: Your managed PostgreSQL connection string # - BETTER_AUTH_SECRET: Generate a secure secret # - BETTER_AUTH_URL: Your Vercel deployment URL # Setup database: npm run db:push ``` -------------------------------- ### Building and Pushing Docker Image Source: https://github.com/lutfykumar/ai-invitation-saas/blob/main/README.md Commands to build a Docker image for the application and push it to a container registry. This is a prerequisite for deploying to cloud platforms like AWS, GCP, or Azure. Dependencies: Docker, npm. ```bash # Build the image docker build -t your-registry/codeguide-starter-fullstack:latest . # Push to registry docker push your-registry/codeguide-starter-fullstack:latest ``` -------------------------------- ### Cancel a Task with task-manager Source: https://github.com/lutfykumar/ai-invitation-saas/blob/main/CLAUDE.md This command is used to cancel a task if it cannot be completed or is no longer needed. A reason for cancellation must be provided. This is an alternative mandatory step to completion. ```bash task-manager cancel-task "Reason for cancellation" ``` -------------------------------- ### Docker Operations Commands Source: https://github.com/lutfykumar/ai-invitation-saas/blob/main/README.md npm scripts for building, running, and managing the application's Docker containers. These commands are essential for local development and deployment, enabling the creation of Docker images and the orchestration of the application stack. Dependencies include Docker and npm. ```bash npm run docker:build npm run docker:up npm run docker:down npm run docker:logs npm run docker:clean ``` -------------------------------- ### Get Event Categories Source: https://context7.com/lutfykumar/ai-invitation-saas/llms.txt Retrieves all active event categories used for invitation classification. The response is an array of category objects, ordered alphabetically by name. No authentication is required. ```typescript // GET /api/categories // Response (200 OK): [ { "id": "550e8400-e29b-41d4-a716-446655440000", "name": "Wedding", "description": "Wedding ceremonies and receptions", "slug": "wedding", "isActive": true, "createdAt": "2025-01-01T00:00:00.000Z", "updatedAt": "2025-01-01T00:00:00.000Z" }, { "id": "551e8400-e29b-41d4-a716-446655440004", "name": "Celebration", "description": "Birthdays and special celebrations", "slug": "celebration", "isActive": true, "createdAt": "2025-01-01T00:00:00.000Z", "updatedAt": "2025-01-01T00:00:00.000Z" }, { "id": "552e8400-e29b-41d4-a716-446655440008", "name": "Meeting", "description": "Professional meetings and reunions", "slug": "meeting", "isActive": true, "createdAt": "2025-01-01T00:00:00.000Z", "updatedAt": "2025-01-01T00:00:00.000Z" } ] // Only returns categories where isActive: true // Ordered alphabetically by name // No authentication required ``` -------------------------------- ### User Authentication - Sign Up Source: https://context7.com/lutfykumar/ai-invitation-saas/llms.txt Registers a new user account using email and password via Better Auth. The server automatically creates a session and hashes the password. ```APIDOC ## User Authentication - Sign Up ### Description Registers a new user account with email and password using Better Auth. The server automatically creates a session for the newly registered user and hashes the password using bcrypt before storage. ### Method POST (implicitly, via client-side library) ### Endpoint (Handled by the `signUp.email` function in `@/lib/auth-client`) ### Parameters #### Request Body (passed to `signUp.email` function) - **email** (string) - Required - The user's email address. - **password** (string) - Required - The user's desired password. - **name** (string) - Required - The user's full name. ### Request Example (Client-side) ```typescript import { signUp } from "@/lib/auth-client"; const result = await signUp.email({ email: "user@example.com", password: "SecureP@ssw0rd", name: "John Doe", }); if (result.error) { console.error("Signup failed:", result.error.message); // Handle errors: "Email already exists", "Invalid email format", etc. } else { console.log("User created:", result.data.user); // Redirect to dashboard or login } ``` ### Response #### Success Response - **data.user** (object) - Information about the created user. #### Error Response - **error.message** (string) - Description of the error (e.g., "Email already exists", "Invalid email format"). ### Notes - Password hashing is handled server-side using bcrypt. - User records are stored in the 'user' table according to the Better Auth schema. - A session is automatically created for the new user. ``` -------------------------------- ### GET /api/invites/[slug] Source: https://context7.com/lutfykumar/ai-invitation-saas/llms.txt Retrieves a published invitation using its unique slug. This endpoint is publicly accessible and does not require authentication. It returns theme rendering data for the invitation and increments the view count upon access. ```APIDOC ## GET /api/invites/[slug] ### Description Retrieves published invitation for public viewing with theme rendering data (no authentication required). ### Method GET ### Endpoint `/api/invites/[slug]` ### Parameters #### Path Parameters - **slug** (string) - Required - The unique slug of the invitation to retrieve. ### Response #### Success Response (200) - **id** (string) - The invitation's unique identifier. - **title** (string) - The invitation's title. - **content** (string) - The main content of the invitation. - **eventDate** (string) - The date and time of the event. - **eventLocation** (string) - The location of the event. - **recipientName** (string) - The name of the recipient. - **senderName** (string) - The name of the sender. - **customMessage** (string) - A custom message for the invitation. - **createdAt** (string) - The timestamp when the invitation was created. - **category** (object) - Details about the invitation's category. - **id** (string) - Category ID. - **name** (string) - Category name. - **slug** (string) - Category slug. - **theme** (object) - Details about the invitation's theme. - **id** (string) - Theme ID. - **name** (string) - Theme name. - **slug** (string) - Theme slug. - **cssVariables** (string) - CSS variables for theme customization. - **templateHtml** (string) - HTML template for the invitation. #### Response Example ```json { "id": "770e8400-e29b-41d4-a716-446655440002", "title": "Sarah & John's Wedding", "content": "You are cordially invited to celebrate our special day", "eventDate": "2025-12-15T14:00:00.000Z", "eventLocation": "Grand Ballroom, Downtown Hotel", "recipientName": "Mr. & Mrs. Smith", "senderName": "Sarah & John", "customMessage": "We look forward to celebrating with you!", "createdAt": "2025-10-29T10:30:00.000Z", "category": { "id": "550e8400-e29b-41d4-a716-446655440000", "name": "Wedding", "slug": "wedding" }, "theme": { "id": "660e8400-e29b-41d4-a716-446655440001", "name": "Elegant Rose", "slug": "elegant-rose", "cssVariables": "{\"--primary\":\"#ff6b9d\",\"--background\":\"#fff8fa\"}", "templateHtml": "
...
" } } ``` #### Error Responses - **404 Not Found** - Invitation not found or not published. **Note:** View count is incremented on each successful access. ``` -------------------------------- ### User Authentication: Sign Up Source: https://context7.com/lutfykumar/ai-invitation-saas/llms.txt Registers a new user account using email and password via Better Auth. Handles client-side calls and server-side operations like password hashing and session creation. Returns user data or error messages. ```typescript import { signUp} from "@/lib/auth-client"; // Client-side usage: const result = await signUp.email({ email: "user@example.com", password: "SecureP@ssw0rd", name: "John Doe", }); if (result.error) { console.error("Signup failed:", result.error.message); // Handle errors: "Email already exists", "Invalid email format", etc. } else { console.log("User created:", result.data.user); // Redirect to dashboard or login } // Server creates session automatically // Password hashed with bcrypt before storage // User record stored in 'user' table with Better Auth schema ``` -------------------------------- ### POST /api/invitations Source: https://context7.com/lutfykumar/ai-invitation-saas/llms.txt Creates a new invitation with validated input, auto-generated unique slug, and user ownership tracking. ```APIDOC ## POST /api/invitations ### Description Creates a new invitation with validated input, auto-generated unique slug, and user ownership tracking. ### Method POST ### Endpoint /api/invitations ### Parameters #### Request Body - **title** (string) - Required - The title of the invitation. - **content** (string) - Required - The main content of the invitation. - **eventDate** (string) - Required - The date and time of the event (ISO 8601 format). - **eventLocation** (string) - Required - The location of the event. - **recipientName** (string) - Optional - The name of the recipient. - **recipientEmail** (string) - Optional - The email of the recipient. - **senderName** (string) - Optional - The name of the sender. - **customMessage** (string) - Optional - A custom message for the invitation. - **categoryId** (string) - Required - The ID of the category for the invitation. - **themeId** (string) - Required - The ID of the theme for the invitation. ### Request Example ```json { "title": "Sarah & John's Wedding", "content": "You are cordially invited to celebrate our special day", "eventDate": "2025-12-15T14:00:00Z", "eventLocation": "Grand Ballroom, Downtown Hotel", "recipientName": "Mr. & Mrs. Smith", "recipientEmail": "smith@example.com", "senderName": "Sarah & John", "customMessage": "We look forward to celebrating with you!", "categoryId": "550e8400-e29b-41d4-a716-446655440000", "themeId": "660e8400-e29b-41d4-a716-446655440001" } ``` ### Response #### Success Response (201 Created) - **id** (string) - The unique identifier for the invitation. - **title** (string) - The title of the invitation. - **slug** (string) - A unique slug for the invitation's public page. - **content** (string) - The main content of the invitation. - **eventDate** (string) - The date and time of the event (ISO 8601 format). - **eventLocation** (string) - The location of the event. - **isPublished** (boolean) - Indicates if the invitation is published. - **viewCount** (integer) - The number of views the invitation has received. - **userId** (string) - The ID of the user who owns the invitation. - **categoryId** (string) - The ID of the category the invitation belongs to. - **themeId** (string) - The ID of the theme the invitation uses. - **createdAt** (string) - The timestamp when the invitation was created (ISO 8601 format). - **updatedAt** (string) - The timestamp when the invitation was last updated (ISO 8601 format). #### Response Example ```json { "id": "770e8400-e29b-41d4-a716-446655440002", "title": "Sarah & John's Wedding", "slug": "a8B3xY9z-1735128000000", "content": "You are cordially invited to celebrate our special day", "eventDate": "2025-12-15T14:00:00.000Z", "eventLocation": "Grand Ballroom, Downtown Hotel", "isPublished": false, "viewCount": 0, "userId": "user_123", "categoryId": "550e8400-e29b-41d4-a716-446655440000", "themeId": "660e8400-e29b-41d4-a716-446655440001", "createdAt": "2025-10-29T10:30:00.000Z", "updatedAt": "2025-10-29T10:30:00.000Z" } ``` ### Error Handling - **401 Unauthorized**: User not authenticated. - **400 Bad Request**: Invalid input (Zod validation failure). - **500 Internal Server Error**: Database or server error. ``` -------------------------------- ### POST /api/chat - AI Content Generation Source: https://context7.com/lutfykumar/ai-invitation-saas/llms.txt Streams AI-generated invitation text using OpenAI GPT-3.5 with category-specific prompts. The response is streamed token-by-token. ```APIDOC ## POST /api/chat ### Description Streams AI-generated invitation text using OpenAI GPT-3.5 with category-specific prompts. ### Method POST ### Endpoint /api/chat ### Parameters #### Headers - **Content-Type** (string) - Required - application/json #### Request Body - **category** (string) - Required - The category for which to generate content (e.g., "wedding", "meeting", "celebration"). - **messages** (array) - Required - An array of message objects, typically starting with a user message containing the specific details for the invitation. - **role** (string) - Required - The role of the message sender (e.g., "user", "system"). - **content** (string) - Required - The content of the message. ### Request Example ```json { "category": "wedding", "messages": [ { "role": "user", "content": "Generate wedding invitation text for Sarah and John, ceremony at Grand Ballroom on December 15, 2025 at 2 PM" } ] } ``` ### Response #### Success Response (200 OK - Streaming) - **Content-Type**: text/event-stream - The response is streamed token-by-token. Each data chunk is a JSON object with `type` and `value` fields. #### Response Example (Streaming) ``` data: {"type":"text","value":"Dengan"} data: {"type":"text","value":" penuh"} data: {"type":"text","value":" sukacita"} ... ``` ### Notes - Uses OpenAI GPT-3.5 model. - Configuration includes `temperature: 0.7`, `maxTokens: 1000`, `maxDuration: 30 seconds`. - Category-specific system prompts are used for tone and language. ``` -------------------------------- ### User Authentication: Sign In Source: https://context7.com/lutfykumar/ai-invitation-saas/llms.txt Authenticates an existing user and establishes a session using Better Auth. This endpoint handles login requests, sets session cookies automatically, and returns user data upon successful authentication. ```typescript import { signIn} from "@/lib/auth-client"; // Client-side usage: const result = await signIn.email({ email: "user@example.com", password: "SecureP@ssw0rd", }); if (result.error) { console.error("Login failed:", result.error.message); // Handle errors: "Invalid credentials", "User not found", etc. } else { console.log("Logged in:", result.data.user); // Session cookie set automatically // Redirect to dashboard } // Session stored in 'session' table // Cookie-based authentication // Configurable session expiration ``` -------------------------------- ### Database Utilities: Increment Invitation View Count (TypeScript) Source: https://context7.com/lutfykumar/ai-invitation-saas/llms.txt Provides a utility function to atomically increment the view count for an invitation using SQL expressions, ensuring race-condition safety. It's designed to be used in public invitation routes. The example shows how to call `incrementInvitationViewCount` before rendering the invitation. ```typescript import { incrementInvitationViewCount } from "@/lib/db/utils"; // Usage in public invitation route: export async function GET( request: NextRequest, { params }: { params: { slug: string } } ) { const invitation = await getInvitationBySlug(params.slug); if (invitation) { // Atomic increment (race-condition safe) await incrementInvitationViewCount(invitation.id); // Renders invitation page return NextResponse.json(invitation); } return NextResponse.json({ error: "Not found" }, { status: 404 }); } // SQL executed: // UPDATE invitation // SET view_count = view_count + 1 // WHERE id = $1 // Avoids read-modify-write race conditions // No return value (fire-and-forget update) ```